git开发基础流程
背景
简单场景描述:
有一个git仓库,将master作为主分支,主管基于master分支在页面上新建了两个分支dev1和dev2,有两个同事分别基于这两个分支进行开发。如果你是其中一个同事,需要基于dev1分支开发,那么你的具体操作是什么样的呢?
基于分支开发的简单流程
核心原则:区分“同步”和“整理”
git fetch
:这是一个“同步”操作。它的成本很低,只是从远程仓库下载最新的分支和提交信息到你的本地仓库,不会修改你的任何工作文件。你应该频繁地执行这个操作,以便了解远程的最新进展。git rebase -i
:这是一个“整理”操作。它会重写你的本地提交历史,是一个重量级操作。你不需要每次都做,只在特定时机进行。
正确的日常开发循环流程
下图清晰地展示了何时进行简单的同步 (fetch
),以及何时需要进行完整的变基整理 (rebase -i
):
flowchart TDA[开始新一天的工作<br>或开始一个新功能模块] --> B[【高频操作】<br>git fetch origin master]B --> C{我的分支功能完成<br>且准备推送到远程?}C -- 否 --> D[进行本地开发<br>(多次add/commit)]D --> BC -- 是 --> E[【关键操作】<br>git rebase -i origin/master]E --> F[解决可能出现的冲突<br>git add . && git rebase --continue]F --> G[强制推送到远程<br>git push --force-with-lease]G --> H[创建Pull Request]
详细步骤说明
第1步:开始工作前,先同步信息(高频操作)
# 确保你在自己的开发分支上
git switch dev1# 获取远程最新信息(这只是一个下载动作,非常安全)
git fetch origin master
目的:让本地仓库知道origin/master
(远程主分支)现在已经进展到哪里了。这时你本地dev1
分支的代码还完全没变,但你心里有数了。
第2步:进行开发工作
# ...编写你的代码...
git add <文件>
git commit -m "feat: 完成了某个功能点"
# ...可以多次提交...
这是开发的主体部分。你专注于编码和提交,不需要被复杂的Git操作打断。
第3步:决定推送前,进行整理和变基(关键操作)
当你觉得一个功能模块完成、一天工作结束、或者准备发起Pull Request时,就是进行整理的最佳时机。
# 1. 再次同步,确保你基于的是最新的master(这步不能省!)
git fetch origin master# 2. 执行交互式变基,整理提交历史
git rebase -i origin/master
为什么是这时才做?
- 你将所有小的、琐碎的提交压缩成1个或几个有意义的提交。
- 你确保你的功能是基于项目最新的代码进行开发的,这能极大减少未来合并时的冲突。
- 你只需要在最后解决一次可能出现的冲突,而不是在开发过程中反复解决。
第4步:推送到远程
由于rebase改写了历史,需要强制推送:
git push --force-with-lease origin dev1
一个具体的场景示例
假设同事1在8月24日的工作流程:
-
早上9:00
git switch dev1 git fetch origin master # 发现master自从昨天后没有新提交 # 开始 coding... git commit -m "feat: 添加登录接口" git commit -m "fix: 修正登录参数验证的bug"
-
上午11:00
git fetch origin master # 发现同事2刚刚合并了一个重要功能到master # 你评估了一下,这个新功能不影响你当前的工作,决定继续开发,暂不rebase。 git commit -m "feat: 添加记住登录状态功能"
-
下午5:00,功能开发完毕,准备推送代码。
# 最后同步一次! git fetch origin master# 开始整理!将今天的3个提交整合成1个清晰的提交。 git rebase -i origin/master # 在交互界面将后两个提交标记为'squash'# 解决可能出现的冲突(因为11点后master有更新) # 写入新的提交信息:"feat: 实现用户登录功能"# 推送到远程,发起PR git push --force-with-lease origin dev1
总结
git fetch
:频繁使用(一天数次)。这是一个安全的“查看”操作,让你保持信息同步。git rebase -i
:仅在关键时刻使用(一天一次,或一个功能完成时)。这是一个“整理”操作,目的是在提交前创造出清晰、线性的历史。
所以你最初的理解——“每次开发前都做”——是不必要的。正确的模式是:频繁fetch
获取信息,在推送前进行一次rebase
整理。这样既保证了代码的时效性,又不会打扰你的开发节奏。