first-contributions 附加材料指南:开源新手必学的 Git 进阶工作流全解析
2026/9/19 2:56:16 网站建设 项目流程

first-contributions 附加材料指南:开源新手必学的 Git 进阶工作流全解析

【免费下载链接】first-contributions🚀✨ Help beginners to contribute to open source projects项目地址: https://gitcode.com/gh_mirrors/fi/first-contributions

本篇指南以 first-contributions 仓库的"附加材料"(Additional Material)为骨架,系统梳理初学者完成基础贡献流程后应当掌握的 10 项 Git 进阶技能:从修正已推送的提交、配置 Git 身份,到保持 fork 与上游同步、解决合并冲突、压缩与还原提交。读完本文,你将获得一套可复制、可上手的 Git 日常操作命令集,足以独立应对开源协作中最常见的版本控制场景。

这份附加材料是什么

additional-material.sl.md 是 first-contributions 为完成基础教程(即通过 fork、clone、提交、发起 Pull Request 完成首次贡献)的读者准备的进阶内容索引。它的前提很明确:"假设你已经完成了基础教程",随后的所有主题都围绕高级 Git 用法展开——这些内容在首次贡献流程中不会用到,但一旦你开始认真参与开源项目,几乎每天都会遇到。

该索引指向 10 篇独立教程,外加一份延伸学习资源清单,覆盖了"提交写错了怎么办""fork 落后了怎么办""分支冲突怎么办"等真实协作痛点。仓库同时在 docs/additional-material/git_workflow_scenarios/ 目录维护了这些教程的英文原版,多语言版本则统一收录在 docs/translations/Translations.md 中,便于对照阅读。

下面按主题逐一展开,每个主题均继承原文的全部命令与步骤,并补充必要的参数说明与适用场景。

一、修正已推送的提交:git commit --amend

1.1 修改最近一次提交的说明文字

提交已经推送到 GitHub 之后才发现注释写错了?无需重开提交,直接使用--amend

git commit --amend -m "你的新提交说明" git push origin <branch-name>
  • 第一条命令用新说明覆盖最近一次提交;
  • 第二条命令把修改后的提交推送到远程仓库。

注意:如果只输入git commit --amend(不带-m),Git 会打开默认文本编辑器,提示你修改提交说明;-m标志的作用正是跳过编辑器、直接指定新说明。

1.2 把漏改的内容补进最近一次提交

假设你向远程推送了提交,随后发现某个文件(例如botfile)漏改了一个单词。原文给出了一个真实风格的提交历史示例:

g56123f create file botfile a2235d updated contributor.md a5da0d modified botfile

有两种处理思路:

  1. 新建一个独立提交补齐改动(简单但会在历史中多一条记录);
  2. 改写原提交a5da0d,把漏掉的改动合并进去,整体只推送一个提交——原文明确推荐这种方式处理小改动。

第二种方式的完整操作:

# 1. 修改文件(给 botfile 补上漏掉的单词) # 2. 将文件加入暂存区 git add botfile # 3. 改写最近一次提交(这里会打开编辑器,可选择保留或修改提交说明) git commit --amend # 4. 推出编辑器 # 5. 推送 git push origin <branch-name>

最终两条改动合并为一个提交,远程历史保持整洁。这一点对开源协作很重要:维护者更希望看到语义清晰的提交,而不是一连串"fix typo"式的补丁。

二、配置 Git 身份与环境:让提交有据可查

第一次执行git commit时,你很可能见过这条报错:

$ git commit *** Please tell me who you are. Run git config --global user.email "you@example.com" git config --global user.name "Your Name" to set your account's default identity. Omit --global to set the identity only in this repository.

Git 必须知道"你是谁"才能创建提交。多人协作时,每个提交都要能追溯到作者及其提交时间,因此提交与姓名、邮箱绑定是 Git 的底层设计。

2.1 三种配置层级

原文给出三种配置方式,优先级由低到高为global(全局)< repository(仓库级)< command-line(命令行级)

① 全局配置(推荐,覆盖本机所有仓库)

git config --global user.email "you@example.com" git config --global user.name "Your Name"

② 仓库级配置(仅对当前仓库生效)

适用于在特定项目中使用不同身份(例如公司项目用工作邮箱):

git config user.email "you@alternate.com" git config user.name "Your Name"

只需去掉--global标志即可。

③ 命令行级配置(仅对当前这一条命令生效)

所有 Git 命令都接受-c前缀,形成临时配置:

git -c user.name='Your Name' -c user.email='you@example.com' commit -m "Your commit message"

2.2 优先级规则

原文明确给出叠加顺序:command-line > repository > global。即同一变量同时存在于命令行级与全局配置时,命令行级取值胜出。这在需要临时切换身份(如代表组织提交)时非常实用。

2.3 其他常用配置项

除用户身份外,原文还列出三个高频配置:

  1. core.editor—— 指定用于撰写提交说明等场景的文本编辑器;
  2. commit.template—— 指定系统中一个文件作为提交说明的初始模板;
  3. color.ui—— 布尔值,控制 Git 输出是否使用颜色。

配置项远不止这些,完整的配置参考可查阅 Git 官方文档(原文链接指向 git-scm.com 的 Customizing Git 章节)。

三、保持 fork 与上游同步:Triangle Workflow

开源贡献的典型协作模型是"三角工作流":存在三个仓库——上游公共仓库、你在 GitHub 上的 fork、你本地的克隆。同步的本质是:先 fetch + merge 上游到本地,再把本地推送回你的 fork,最后才能从 fork 发起 Pull Request,因此 fork 总是最后一个被更新的仓库。

完整同步步骤如下:

# 1. 确认当前在 master 分支(查看 git status 输出的第一行) git status # 若不在 master,切换过去 git checkout master # 2. 添加上游远程仓库,命名为 upstream git remote add upstream https://github.com/Roshanjossey/first-contributions # 3. 拉取上游最新内容 git fetch upstream # 4. 把上游内容并入本地 master git rebase upstream/master # 5. 推送本地 master 到你的 fork(origin) git push origin master

要点说明:

  • remote add upstream告诉 Git 存在另一个项目版本;fetch只下载不合并;
  • rebase upstream/master将本地 master 变基到上游最新状态;
  • push origin master推送的目标是名为origin的远程(即你的 fork)。

实操建议:每当 GitHub 提示你的 fork 落后于上游时,就按此流程同步一次。这正是 first-contributions 仓库 README.md 基础教程流程的后续配套动作——首次贡献只是起点,长期参与开源项目时保持 fork 同步是日常必修课。

四、把提交挪到正确的分支

4.1 把最近一次提交移到已存在的分支

误把提交打在错误分支上时,用"软重置 + stash"组合拳:

git reset HEAD~ --soft # 撤销最近一次提交,改动保留 git stash # 暂存当前工作区状态 git checkout name-of-the-correct-branch # 切换到正确的分支 git stash pop # 恢复暂存的改动 git add . # 或按需 add 单个文件 git commit -m "your message here"

--soft的关键作用是只移动 HEAD 指针、保留所有改动内容,配合stash完成"跨分支搬家"。

4.2 把最近几个提交移到新分支

git branch newbranch # 新建分支,包含当前全部提交 git reset --hard HEAD~# # 主分支回退 # 个提交(这些提交将从主分支移除) git checkout newbranch # 切到新分支,提交都在这里

重要警告(原文原文强调):所有未提交的改动都会丢失!执行reset --hard前务必确认工作区干净。

五、从 Git 中移除文件但不删本地文件

有时你只想让 Git 停止跟踪某个文件,却不希望它从磁盘消失(典型场景:误提交了本应忽略的本地配置文件):

git rm <file> --cached

5.1 原理

--cached只把文件从暂存区/索引移除。对 Git 而言该文件"不再存在"(停止跟踪),但你打开磁盘目录,文件依然在那里。若省略--cached,Git 会连磁盘上的文件一并删除。

移除后照常提交并推送,远程仓库中的文件也会被删除:

git commit -m "Remove file1.js" git push origin master

5.2 批量与通配符

一次移除多个文件:

git rm file1.js file2.js file3.js --cached

用通配符批量移除同类文件(例如清除所有.txt跟踪记录):

git rm *.txt --cached

六、清理仓库中的无用分支

完成 Pull Request 并被合并后,你创建的特性分支<add-your-name>就完成了使命,可以清理:

git checkout master git merge <add-your-name> master git branch -d <add-your-name> # 删除本地分支

若远程 fork 上的分支也已被上游合并,再删除远程分支:

git push origin --delete <add-your-name>

关键提醒:只有当你的 Pull Request 已被上游项目合并后,才能删除 GitHub fork 上的分支;在此之前删除将导致无法继续提交 PR。

此外,原文在此处提示:随着上游持续演进,你的本地与 fork 的 master 都会逐渐落后,需要按第三部分的同步流程定期更新——这是本仓库文档体系中前后呼应的设计。

七、解决合并冲突:读懂标记并手动合流

7.1 冲突是怎么产生的

当你把另一条分支合并进当前分支时,如果两个人改了同一文件的同一行,或一人删除了文件而另一人修改了它,Git 无法自动判断谁对,就会把该文件标记为冲突,等待人工裁决。

7.2 冲突标记的含义

Git 会在冲突位置插入特殊标记:

<<<<<<< HEAD:mergetest This is my third line ======= This is a fourth line I am adding >>>>>>> 4e2b407f501b68f8588aa645acafffa0224b9b78:mergetest
标记含义
<<<<<<<冲突开始,上方内容来自你当前分支(HEAD)
=======分界线,分隔你的改动(上)与他人的改动(下)
>>>>>>>冲突结束,后面跟着另一方分支的标识/SHA

7.3 解决步骤

  1. 编辑冲突文件,手动合并两部分内容——可以保留自己的、保留对方的,或取两者的混合;必要时与写下冲突代码的同事沟通确认;
  2. 必须删除<<<<<<<=======>>>>>>>三组标记;
  3. git add标记文件已解决;
  4. 运行测试,确认冲突解决正确。

IDE 插件(取决于你使用的编辑器)可以显著简化冲突可视化与解决过程。

7.4 放弃合并

若决定不合并了,执行:

git merge --abort

将整个合并操作安全撤销。

八、还原已推送的提交:git revert

8.1 原理

revert创建一个新提交,反向撤销目标提交的所有改动——相当于 Git 世界里的CTRL+Z。由于每个提交都有唯一的 SHA(Secure Hash Algorithm)标识,只要拿到 SHA 就能还原任意提交。当然,还原操作需谨慎,操作不当可能损坏仓库。

8.2 查看提交历史与 SHA

git log --oneline

--oneline让每个提交只占一行,输出每行前 7 个字符就是该提交的缩写哈希。示例:

389004d added spacing in title c1b9fc1 Merge branch 'master' into tutorials 77eaafd added tutorial for reverting a commit

(完整的git log也会给出 SHA,只是输出更长。)

8.3 执行还原

以撤销 "added spacing in title"(SHA389004d)为例:

  1. 复制目标 SHA:389004d
  2. 执行git revert 389004d
  3. Git 打开编辑器让你填写提交说明——可保留默认的以Revert开头的消息,也可自行修改;
  4. 保存并关闭编辑器,回到命令行;
  5. 推送:git push origin <branch-name>

完成后仓库即恢复到目标提交之前的状态(本例中相当于回到c1b9fc1时的内容),且历史中明确留有一条 revert 记录,适合协作场景。

九、压缩提交:interactive rebase 与 squash

9.1 为什么要压缩

squashing 是指把多个提交"压"成一个提交、合并成一条说明。开源项目普遍要求这么做,因为:特性分支的大量中间提交只对作者有意义;压缩后变更易于追踪,也便于在需要时整体还原。

9.2 查看待压缩的提交

git log

典型的输出结构:

commit blablabla Author: omguhh Date: 10/10/20 Commit message 1 commit blablabla2 Author: omguhh Date: 10/10/20 Commit message 2

9.3 交互式变基

进入交互模式并指定回看深度:

git rebase -i HEAD~2

HEAD是起点,~2表示回溯 2 个提交。编辑器会列出待处理提交及全部可用命令:

pick blablabla Changing test01.txt file pick blablabla2 Adding dummy01.txt file

命令速查(原文完整列出):

命令简写作用
pickp使用该提交
rewordr使用该提交,但编辑提交说明
edite使用该提交,但停下来修改
squashs使用该提交,并合并进上一个提交
fixupf同 squash,但丢弃该提交的说明
execx用 shell 执行命令行的剩余部分

原文特别提示:这些行可以重排、从上到下依次执行;删除某一行意味着该提交将丢失;如果删光所有行,rebase 会被中止;空提交会被注释掉。

要把blablabla2压进blablabla,将第二行的pick改为squash

pick blablabla Changing test01.txt file squash blablabla2 Adding dummy01.txt file

保存后 Git 展示合并提交说明的编辑界面:

# This is a combination of 2 commits. # The first commit's message is: commit message 1 # This is the 2nd commit message: commit message 2

按需改写说明、保存退出。再次git log,即可看到两个提交已合并为一个,且保留了最终说明。这在"维护者要求你把多个提交 squash 成一个并补充信息性说明"的场景下是标准操作。

十、撤销本地提交:git reset

10.1 基础用法:软撤销与取消暂存

git reset

把暂存区重置回最近一次提交的状态,但工作区的改动全部保留,之后可以重新提交。若只想把某个文件移出暂存区:

git reset <file>

原文给出的完整示例:

# 修改 index.php 和 tutorial.php # 加入暂存区 $ git add . # 想起两个文件应分开提交 # 先取消暂存 tutorial.php $ git reset tutorial.php # 先提交 index.php $ git commit -m "Changed index.php" # 现在提交 tutorial.php $ git add tutorial.php $ git commit -m "Changed tutorial.php"

10.2 硬重置:清空一切改动

git reset --hard

--hard会同时清空暂存区并丢弃工作区所有未提交改动,将文件恢复到最近一次提交的状态。只有你确信要放弃自上次提交以来的所有改动时才使用。

带回溯深度的写法(丢弃最近两个提交及其改动):

git reset --hard HEAD~2

10.3 红线警告

千万不要对已经推送到共享仓库的提交执行git reset --hard——这会重写公共历史,给所有协作者带来麻烦。共享历史请改用第八部分的git revert

延伸学习:有用的链接

作为收尾,Useful-links-for-further-learning.md 汇集了面向开源新手的博客、实用站点与技巧页面,可以作为继续深入 Git 与开源协作的索引。结合本仓库的多语言体系,你还可以在 docs/additional-material/translations/Slovenian/ 目录中找到与本文每一节一一对应的斯洛文尼亚语原文,并在 docs/additional-material/git_workflow_scenarios/ 找到英文原版对照。

小结:从首次提交到熟练协作者

把这份附加材料的 10 个主题串起来,就是一条完整的进阶路径:写错提交用amend,身份未配置用config,fork 落后用fetch + rebase + push,提交打错分支用reset + stash,误跟踪文件用rm --cached,收尾清理用branch -d/--delete,冲突缠身用标记手动合流,推错历史用revert,提交过多用交互式rebase -i压缩,本地乱套用reset。结合 first-contributions 的基础流程(fork → clone → 提交 → Pull Request)与本文的进阶技能,你已具备参与绝大多数开源项目的 Git 操作能力。

【免费下载链接】first-contributions🚀✨ Help beginners to contribute to open source projects项目地址: https://gitcode.com/gh_mirrors/fi/first-contributions

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询