Git如何将master分支最新更新同步到派生的feature分支
你本地有从master分支切出的feature开发分支,当前远端master已经合入了多个新提交、领先于你当初切分支时的master版本,目标是把master的最新更新同步到自己的feature分支,避免后续提合并请求时出现冲突。
逐个拆解你列的每个命令的实际作用,以及为什么符合/不符合需求:
git pull:无参数的pull默认拉取当前分支绑定的远端对应分支(也就是origin/feature)的最新提交,之后默认用merge方式合并到本地。这个操作完全不会拉取master的内容,达不到同步master的目的。git pull --rebase:逻辑和上面的无参数pull一致,只是把合并方式从merge换成rebase,拉取的还是远端feature分支的内容,和同步master无关。git pull origin feature:显式指定拉取远端的feature分支合并到本地,本质还是同步feature分支的远端更新,和master没有关系。git pull origin master:这个命令确实会拉取远端master的内容,但它会直接把拉下来的master提交merge到你当前的feature分支,会生成多余的merge提交,而且因为跳过了显式同步远端状态的步骤,很容易因为本地缓存的远端分支版本过旧导致合并混乱,不是规范操作。git rebase origin/master:这是特性分支同步master的主流推荐方案之一,但有个前提:你本地的origin/master必须是最新的远端状态,不然rebase的是旧版本的master,等于白同步。git merge origin/master:这也是可行的同步方案之一,同样需要提前保证本地的origin/master是最新版本,缺点是会生成专门的merge提交,提交历史会出现分叉,适合团队统一约定用merge工作流的场景。
不管团队用rebase还是merge规范,第一步都要先执行安全的远端状态同步:git fetch origin
这个操作只会把远端所有分支的最新提交拉到本地的远端追踪缓存区,不会修改你本地工作区的任何代码,没有破坏性。
执行完fetch之后,根据团队的工作流规范二选一即可:
方案1:Rebase流(个人独立开发的feature分支推荐)
执行命令:git rebase origin/master
这个命令会把你在feature分支上写的所有自定义提交,挨个临时保存,然后把当前feature分支的基线移到最新的origin/master提交上,再把你之前的自定义提交挨个接在新基线后面,最终得到完全线性的提交历史,没有多余的merge节点,后续提代码审查的时候提交记录非常清晰。
如果rebase过程中遇到代码冲突,只需要按提示打开冲突文件解决冲突,解决完执行git add <冲突文件路径>,再执行git rebase --continue即可,重复这个步骤直到rebase完成。
注意:如果你的feature分支之前已经推送到远端,rebase会修改原有提交的hash值,推送的时候需要用
git push --force-with-lease,不要用裸--force强推,避免误覆盖同分支上其他人提交的代码。
方案2:Merge流(公共协作分支/团队禁止rebase时适用)
执行命令:git merge origin/master
这个命令会把最新的master提交直接合并到当前feature分支,自动生成一条merge提交记录,标记本次同步master的操作。优点是不会修改原有提交的hash,同步完直接普通git push即可,不需要强推;缺点是提交历史会有分叉,时间线相对杂乱,长期多次同步master之后提交记录会很难梳理。
如果merge过程中遇到冲突,解决完冲突执行git add <冲突文件路径>,再执行git merge --continue就可以完成合并。
- 同步前如果工作区有没写完、不想提交的代码,可以先用
git stash把修改暂存,等同步完master之后再执行git stash pop把暂存的修改恢复到工作区,避免未提交的修改干扰合并流程。 - 不要图省事直接用
git pull origin master一步同步,隐式的fetch+merge很容易因为本地缓存的远端状态不对出问题,显式分步骤执行fetch和后续的rebase/merge,可控性高很多。
内容的提问来源于stack exchange,提问作者romanzdk

