
first-contributions 进阶指南从修改提交到解决冲突的完整 Git 实战手册【免费下载链接】first-contributions✨ Help beginners to contribute to open source projects项目地址: https://gitcode.com/gh_mirrors/fi/first-contributions导读完成 first-contributions 主教程的首次 Pull Request 之后你已经掌握了 fork、clone、branch、commit、push 与 PR 的基础闭环。但真实的开源协作远不止于此提交信息写错了怎么办Fork 落后于上游仓库怎么办两个分支同时改了同一行代码怎么办本篇文章以仓库 孟加拉语补充材料索引 为骨架系统展开其引用的全部 13 个进阶 Git 主题覆盖提交修正、历史重写、分支治理、冲突处理与凭据管理五大场景让你在参与开源项目时不再畏惧任何一次意外。前置说明这份补充材料是什么仓库中每一份补充文档都默认读者已经完成了 primary tutorialfork 上游 → clone 到本地 → 新建add-your-name分支 → 提交 → 发起 Pull Request。因此下文涉及的所有操作都发生在真实开源协作的上下文里你的仓库同时存在origin自己的 GitHub Fork与upstream原项目公共仓库两个远程以及本地、Fork、上游三方协作的三角工作流。原索引以 additional-material.be.md 收录了 10 篇 git_workflow_scenarios 下的操作文档外加 .gitignore、凭据存储与实用链接共 13 个主题。下文逐一展开每节都给出可直接复制的命令与关键注意点。一、修改提交git commit --amend对应文档amending-a-commit.md场景一提交推送到远程后发现提交信息有拼写错误或发现自己漏改了一行。你不需要新建一个补救提交只需修改最近一次提交。修改最近一次提交的信息git commit --amend -m 新的提交信息 git push origin branch-name不加-m直接运行git commit --amendGit 会打开默认文本编辑器等你修改提交信息后保存退出加上-m标志则跳过编辑器直接以新信息替换原信息。把漏改的内容并入上一次提交假设你的提交历史如下g56123f create file botfile a2235d updated contributor.md a5da0d modified botfile你发现a5da0d里漏写了一个单词。两种做法一是新建一条独立提交二是把新改动并入a5da0d让改动保持一个提交一个主题。后一种对小型修正更干净操作如下# 1. 修改文件把遗漏的单词补上 # 2. 加入暂存区 git add filename # 3. 修改上一次提交会打开编辑器可保留或改写原信息 git commit --amend # 4. 推送 git push origin branch-name修改已推送到远程的提交一旦提交已经推送到远程git commit --amend本质上是用一个新提交替换旧提交本地历史将与远程历史分叉。要让远程也更新必须强制推送覆盖远程分支历史git add your changed files git commit --amend -m followed by your new commit message git push --force⚠️ 警告git push --force会直接覆盖远程分支、丢弃远程上已有的改动——包括其他协作者在此期间推送的内容。 更安全的替代方案是git push --force-with-lease推送前 Git 会先核对远程分支是否仍是你上次拉取时的状态若是则拒绝推送并提醒你避免误伤他人的提交。在你无意覆盖别人改动时应优先使用它。二、配置 Git 身份与更多选项对应文档configuring-git.md第一次运行git commit时你可能会看到这样的提示$ git commit *** Please tell me who you are. Run git config --global user.email youexample.com git config --global user.name Your Name to set your accounts default identity. Omit --global to set the identity only in this repository.Git 要求每次提交都绑定名字与邮箱这是协作的基础只有这样才能知道谁在什么时候改了什么。向 Git 提供身份有三种作用域优先级从高到低为命令行级 仓库级 全局级。全局配置Global存入全局配置后本机所有仓库都会生效适用于大多数场景git config --global user.email youexample.com git config --global user.name Your Name通用语法git config --global 变量名 值。仓库配置Repository省略--global配置只作用于当前仓库。典型场景工作项目用公司邮箱、个人项目用私人邮箱git config user.email youalternate.com git config user.name Your Name通用语法git config 变量名 值。命令行配置Command-line仅对单条命令生效。所有 Git 命令都支持在动作动词之前用-c传入临时配置git -c user.nameYour Name -c user.emailyouexample.com commit -m Your commit message通用语法git -c 变量-1值 -c 变量-2值 command。优先级说明三种方式的生效优先级是命令行级 仓库级 全局级。例如某个变量同时在命令行和全局配置中出现本次操作使用命令行中的值。身份之外的其他配置项core.editor—— 指定编写提交信息等场景使用的编辑器名称commit.template—— 指定系统上一个文件作为初始提交信息模板color.ui—— 布尔值控制 Git 输出是否使用颜色。三、保持 Fork 与上游仓库同步对应文档keeping-your-fork-synced-with-this-repository.md开源协作的典型结构是三角工作流上游公共仓库upstream→ 你的 GitHub Forkorigin→ 本地仓库一共三个仓库。Pull Request 只能从你的 Fork 发起所以同步的次序是先让本地与上游同步再让本地推送到 Fork。GitHub 提示你落后 N 个提交时就该执行下面的流程。完整同步流程# 1. 确认当前在 main 分支git status 的第一行会显示当前分支 git status # 如果不在 main git checkout main # 2. 添加上游远程只需做一次命名为 upstream git remote add upstream https://github.com/firstcontributions/first-contributions.git # 3. 拉取上游最新内容 git fetch upstream # 4. 把上游 main 变基/合并进本地 main git rebase upstream/main # 5. 推送到你的 GitHub Forkorigin git push origin main一步到位的快捷方式如果只想一次性拉取并合并上游main到当前本地分支git pull upstream main此后本地、Fork、上游三方保持一致。建议每次看到 GitHub 提示落后时都执行一遍同步再做新功能开发可大幅减少后续的合并冲突。四、把提交移动到正确的分支对应文档moving-a-commit-to-a-different-branch.md不小心在错误的分支上提交了代码两条路线可以补救。移动到已存在的分支git reset HEAD~ --soft # 撤销最后一次提交但保留文件改动 git stash # 记录当前工作目录状态 git checkout name-of-the-correct-branch # 切换到正确的分支 git stash pop # 恢复之前暂存的状态 git add . # 或逐个添加文件 git commit -m your message here # 在正确分支上重新提交移动到新建的分支git branch newbranch # 创建新分支保留全部提交 git reset --hard HEAD~# # 当前分支回退 # 个提交这些提交将从当前分支消失 git checkout newbranch # 切换到新分支它拥有全部提交⚠️ 注意git reset --hard会丢弃未提交的改动。执行前确认没有未保存的工作。五、从 Git 仓库移除文件对应文档removing-a-file.md有时你想让 Git 停止跟踪某个文件但文件本身还要留在电脑上例如误提交的配置文件。核心命令git rm file --cached原理说明加上--cached后Git 不再跟踪该文件的变更从版本控制角度看如同已删除但文件仍然存在于磁盘上。如果不加--cachedGit 会同时把文件从仓库和你的文件系统中删除。之后照常提交并推送远程仓库就会移除该文件git commit -m Remove file1.js git push origin main批量与通配符用法# 一次移除多个文件 git rm file1.js file2.js file3.js --cached # 用通配符移除同类文件例如所有 .txt git rm *.txt --cached六、删除本地与远程分支对应文档removing-branch-from-your-repository.md按主教程做完贡献后add-your-name分支已完成了它的使命可以清理掉。先把它合并进main再删除本地分支git checkout main git merge add-your-name main git branch -d add-your-name删除远程分支GitHub Fork 上的add-your-name则需要谨慎在维护者尚未合并你的 Pull Request 之前千万不要删除它。只有确认 PR 已合并后才执行git push origin --delete add-your-name这样本地与远程的分支都保持整洁。时间一长上游仓库会积累大量新提交记得回到第三节的同步流程保持三方一致。七、解决合并冲突对应文档resolving-merge-conflicts.md什么是合并冲突当不同分支的改动相互冲突、Git 无法自动合并时就会产生冲突。常见场景两个贡献者修改了同一文件的同一行一个贡献者删除了另一个贡献者正在修改的文件两个分支把同一文件重命名成了不同名字。此时 Git 会暂停合并把冲突文件标记出来等待人工处理。本教程聚焦命令行解法。五步解决流程1. 找出冲突文件。合并失败后运行git status在 Unmerged paths 下查找冲突文件列表。2. 打开冲突文件查看标记。Git 用冲突标记标出边界 HEAD 你的改动 传入的改动 branch-name HEAD以下是当前分支的改动分隔双方改动 branch-name以下是另一分支传入的改动。3. 手动解决冲突。三种选择保留你的改动、接受传入的改动、或把两者有意义地合并。编辑完成后务必删除、、这些冲突标记。4. 标记为已解决git add filename对每个冲突文件重复此步骤。5. 提交合并git commit -m Resolved merge conflicts至此合并流程收尾。辅助工具# 启动可视化合并工具需先安装 Meld、KDiff3、Beyond Compare 等 git mergetool # 想放弃本次合并时 git merge --abort减少冲突的最佳实践经常从主分支拉取更新git pull origin main每个功能/修复使用独立分支git checkout -b feature-branch。八、还原提交git revert对应文档reverting-a-commit.mdgit revert相当于 Git 世界的 CtrlZ它新建一条提交来撤销另一条提交的所有改动历史保持线性增长非常适合已经推送到远程的提交。每个提交都有唯一的 SHASecure Hash Algorithm标识只要能拿到 SHA 就能还原它但要注意按顺序还原以免搞乱仓库。步骤# 1. 查看提交历史--oneline 以一行简洁形式显示每行开头是 7 位短 SHA git log --oneline示例输出389004d added spacing in title c1b9fc1 Merge branch master into tutorials 77eaafd added tutorial for reverting a commit# 2. 复制目标提交的 SHA如 389004d git revert 389004dGit 会打开文本编辑器让你编辑提交信息可以保留默认以Revert开头的消息也可以自定义。# 3. 保存并关闭编辑器 # 4. 推送 git push origin branch-name完成。本例中仓库将回到c1b9fc1时的状态。九、压缩提交git rebase -i对应文档squashing-commits.md什么是 SquashSquash 即重写提交历史把多个提交合并成一个带有完整描述的提交。开源项目经常要求这样做分支上大量的过程性提交只对作者本人有意义合并成一个提交后改动描述更清晰、日后也更容易整体还原。操作步骤先查看要合并的提交git log会看到类似commit blablabla Author: omguhh Date: 10/10/20 Commit message 1 commit blablabla2 Author: omguhh Date: 10/10/20 Commit message 2进入交互式 rebase并指定回溯范围git rebase -i HEAD~2编辑器会打开一个待办列表pick blablabla Changing test01.txt file pick blablabla2 Adding dummy01.txt file # # Commands: # p, pick use commit # r, reword use commit, but edit the commit message # e, edit use commit, but stop for amending # s, squash use commit, but meld into previous commit # f, fixup like squash, but discard this commits log message # x, exec run command (the rest of the line) using shell # # These lines can be re-ordered; they are executed from top to bottom. # # If you remove a line here THAT COMMIT WILL BE LOST. # # However, if you remove everything, the rebase will be aborted. # # Note that empty commits are commented out把第二条的pick改为squash使其并入上一条pick blablabla Changing test01.txt file squash blablabla2 Adding dummy01.txt file保存退出后Git 会打开提交信息编辑器展示两条提交信息的组合# This is a combination of 2 commits. # The first commits message is: commit message 1 # This is the 2nd commit message: commit message 2自由修改后保存退出。再次运行git log两个提交已合并为一个。十、撤销本地提交git reset对应文档undoing-a-commit.mdgit reset系列用于撤销尚未推送的本地提交。三种模式各有用途。软撤销仅重置暂存区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硬重置彻底回到上次提交git reset --hard不仅重置暂存区还把工作目录的所有文件改动一并还原到上次提交。--hard模式告诉 Git 连工作目录的改动一起丢弃只有在确定要放弃全部本地开发时才使用。# 开始了一次疯狂的实验 # 新建 crazy.php 并写入代码 $ git add crazy.php $ git commit -m Started a crazy dev # 再次修改 crazy.php 以及大量其他文件 $ git add . $ git commit -m Continued dev # 测试后局面失控决定整体回退 $ git reset --hard HEAD~2git reset --hard HEAD~2把当前分支回退 2 个提交点同时丢弃这两次提交产生的所有改动快照。⚠️ 记住如果提交已经推送到共享仓库永远不要执行git reset --hard否则会给仓库中所有协作者带来麻烦。此时应改用第八节的git revert。十一、创建 .gitignore 文件对应文档creating-a-gitignore-file.md为什么需要 .gitignore.gitignore是 Git 工作流的关键组件告诉 Git 忽略哪些文件与目录防止不必要或敏感的数据被纳入版本控制。以下几类文件不应入库临时或系统生成的文件缓存、构建产物、日志可重新安装的大型依赖如node_modules个人或敏感配置API 密钥、环境变量IDE/编辑器专属文件如.vscode/、.idea/。忽略它们能让仓库保持干净、减少冲突、避免安全风险。创建方法在项目根目录新建名为.gitignore的文本文件每行列出一个要忽略的文件或目录保存。基本语法*—— 通配符匹配多个文件/—— 指定相对.gitignore的路径#—— 注释。示例文件# 忽略 Mac 系统文件 .DS_Store # 忽略依赖目录 node_modules/ venv/ # 忽略日志与缓存文件 *.log .cache/ # 忽略环境变量文件 .env # 忽略所有文本文件 *.txt全局 .gitignore对所有仓库生效的全局忽略文件git config --global core.excludesfile ~/.gitignore_global然后像编辑本地.gitignore一样编辑~/.gitignore_global。取消已跟踪文件的跟踪文件在加入.gitignore之前若已被提交需要先从跟踪中移除# 取消跟踪单个文件保留在本地 git rm --cached filename # 取消跟踪所有被忽略的文件-- 之后是路径. 表示当前目录 git rm -r --cached . git add . git commit -m Updated .gitignore撤销git rm --cached只需git add filename。十二、存储凭据git credential cache对应文档storing-credentials.md每次访问远程仓库都要输入用户名密码确实影响效率Git 提供了凭据缓存机制来解决。⚠️ 安全提示请务必遵守你工作/学习场所的安全策略。注意credential.helper cache方式以明文把凭据保存在本机磁盘上同一台电脑上的其他用户例如恶意 NPM 模块都可能读取到它。全局凭据缓存所有仓库git config --global credential.helper cache仓库级凭据缓存git config credential.helper cache设置缓存超时不指定时长时凭据可能被长期保留用--timeout控制保存在内存中的时间git config credential.helper cache --timeouttimeout使用该 helper 时凭据不会落盘超时后自动清除。默认值是 900 秒15 分钟。十三、进一步学习资源索引对应文档Useful-links-for-further-learning.md该文档是一份面向初学者与进阶者的学习资源索引收录了 GitHub 官方文档、交互式 Git 练习工具、视频课程、命令速查表、合并冲突专题、rebase 图解、提交信息书写规范、开源贡献入门指南、版本控制课程以及编辑器内置 Git 功能说明等多类资料。当你完成本文全部练习后可以继续翻阅这份清单把交互式教程当作日常练习场把速查表贴在案头把提交信息规范应用到每一次git commit中就能逐步形成更专业的协作习惯。总结把这些技巧串进真实的贡献流程把本文的 13 个技巧放回 first-contributions 的真实贡献场景你会看到一条完整的能力链路开发前先按第三节同步 fork避免落后 N 个提交提交后若发现信息有误或漏改用第一节git commit --amend修正若提交到了错误分支用第四节移动到正确分支若误提交了不该入库的文件用第五节或第十一节从跟踪中移除PR 合并后用第六节清理本地与远程的临时分支若 PR 评审要求合并提交历史用第九节 squash若遭遇冲突按第七节逐文件解决若推错了提交用第八节 revert已推送或第十节 reset未推送最后用第十二节配置凭据缓存避免频繁输入密码。这些文档全部收录在 git_workflow_scenarios 目录下除英文原版外多数主题还提供了中文如 amending-a-commit.zh-cn.md、孟加拉语additional-material.be.md等多语言版本可对照阅读。掌握这 13 个主题你在任何开源项目中的协作都会更加从容。【免费下载链接】first-contributions✨ Help beginners to contribute to open source projects项目地址: https://gitcode.com/gh_mirrors/fi/first-contributions创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考