多人协作时,fork + rebase 是一套很稳妥的工作流。它的核心目标有两个:
- 让自己的开发分支始终基于上游最新代码
- 尽量保持提交历史线性,减少无意义的 merge commit
下面这套流程适合大多数基于 GitHub 的开源协作场景。
1. Fork 后先配置远程仓库
先克隆自己的仓库,再把原仓库登记为 upstream:
git clone <your-fork-url>
cd <repo>
git remote rename origin origin
git remote add upstream <upstream-repo-url>
git remote -v
如果你是直接从上游仓库克隆下来的,也可以把当前远程重命名为 upstream,再补一个自己的 origin。关键不是命令顺序,而是保证语义清楚:
origin指向你自己的 forkupstream指向原始主仓库
2. 开始开发前先同步上游
每次准备新改动前,先拉取上游最新历史:
git fetch upstream
git checkout main
git rebase upstream/main
git push origin main
这样你自己的 main 会和上游保持一致,后面切功能分支时不容易把旧代码带进去。
3. 从干净的主分支切功能分支
git checkout -b feat/my-change
不要长期直接在 main 上写代码。功能分支更容易审查,也方便你在需要时重做或拆分提交。
4. 提交前先检查改动范围
git status
git diff
git add <files>
git commit -m "feat: add something useful"
这里最容易犯的错,是把无关文件一起提交进去。提交前至少看一遍 git status,必要时用 git restore --staged <file> 把误加的文件撤回来。
5. 提交 PR 前做一次 Rebase
如果上游仓库在你开发期间又前进了,提交 PR 之前建议再同步一次:
git fetch upstream
git rebase upstream/main
出现冲突时,按顺序处理:
- 编辑冲突文件
git add <resolved-file>git rebase --continue
如果发现这次 rebase 方向不对,再用 git rebase --abort 回退,而不是硬着头皮继续改。
6. 推送分支到自己的 fork
git push -u origin feat/my-change
如果这个分支已经推送过,而你又做过 rebase,那么需要强制更新远程历史:
git push --force-with-lease
优先使用 --force-with-lease,不要养成直接 --force 的习惯。前者至少会帮你避免误覆盖别人刚推上去的提交。
7. 什么时候该用 Rebase,什么时候不该用
适合 rebase 的场景:
- 你在维护自己的功能分支
- 你想把提交历史整理得更线性
- 你准备在发 PR 之前同步上游最新代码
不适合 rebase 的场景:
- 这个分支已经被多人共享
- 其他人已经基于你的提交继续开发
原因很简单:rebase 会重写提交历史。对私有分支很方便,对共享分支很危险。
8. 一套够用的最小命令清单
git fetch upstream
git checkout main
git rebase upstream/main
git checkout -b feat/my-change
git add <files>
git commit -m "feat: add something useful"
git fetch upstream
git rebase upstream/main
git push -u origin feat/my-change
结语
fork + rebase 的重点不在命令本身,而在边界清晰:主分支负责同步上游,功能分支负责承载改动,提交前主动整理历史。只要坚持这三件事,协作成本会低很多。