如何修复级联分支变基混乱

dee*_* zg 2 git github git-rebase

我们有一个工作流程,其中只有一名团队成员在多个功能分支上工作。工作是这样的,下一个分支都依赖于他之前所做的分支。默认分支是develop.

我们来说说这个场景:

  1. 他创建featureA分支,完成工作,推送分支,并在 GitHub 上创建 PR
  2. 他创建featureB分支(基于featureA一个分支),进行工作并进行公关
  3. 他创建featureC分支,(基于featureB)做工作并公关它
  4. 他创建featureD分支,(基于featureC)做工作并公关它

尚未合并任何 PR。

现在,项目经理介入并开始合并。合并走这样的路:

  1. 项目经理并入featureA开发
  2. 他这边的开发人员这样做:

    git checkout develop
    git fetch origin
    git rebase origin/develop
    git checkout featureB
    git rebase origin/develop
    git push origin featureB
    
    Run Code Online (Sandbox Code Playgroud)

此时我们得到错误:

machine /c/Work/ (featureB)
$ git push origin featureB
To https://github.com/x.git
 ! [rejected]        featureB -> featureB (non-fast-forward)
error: failed to push some refs to 'https://github.com/x.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
Run Code Online (Sandbox Code Playgroud)

为什么会出现这种情况?

我们认为变featureBorigin/develop(现在合并后包含featureA)将为featureB推送做好准备。但显然我们看到了一些问题。

Sco*_*don 6

解释发生的情况的最简单方法是查看存储库的历史记录。这是合并前您的历史记录(的删节版本):

*--*--*--* [develop, origin/develop]
          \
           *--*--* [featureA, origin/featureA]
                  \
                   A--B--C [featureB, origin/featureB]
Run Code Online (Sandbox Code Playgroud)

以及合并后:

*--*--*--*---------* [develop, origin/develop]
          \       /
           *--*--*
                  \
                   A--B--C [featureB, origin/featureB]
Run Code Online (Sandbox Code Playgroud)

然后你重新featureB基于develop

*--*--*--*---------* [develop, origin/develop]
          \       / \
           *--*--*   A'--B'--C' [featureB]
                  \
                   A--B--C [origin/featureB]
Run Code Online (Sandbox Code Playgroud)

这里,A'B'、 、分别包含与、、 和C'相同的更改,但它们不是相同的提交,因为具有不同的父提交。ABCA'

因此,在每次变基之后,您必须强制推送变基分支:

git push --force-with-lease origin featureB
Run Code Online (Sandbox Code Playgroud)

(这--force-with-lease确保自上次获取以来没有推送任何新提交。虽然这里可能并不严格需要它,但最好养成使用它的习惯--force。)

正如我的上一张图所示,只要分支(例如featureB)及其远程跟踪分支(例如origin/featureB)出现分歧,您就必须强制推送。因此,每当您重新定位已推送到远程的分支时,您都需要执行此操作。