当现有提交哈希值发生更改时重新绑定

时间:2015-03-02 19:47:30

标签: git

我试图更多地了解我们团队最近的git问题。我们有几层分支:

-> Master
   |-> Feature Branch
        |-> Individual developer branches

小组开发人员在功能分支上工作,我们一次有几个不同的功能分支。

当一个人与Master合并时,功能分支所有者将 rebase 他们的功能分支。它们经常与任何已经从各个开发人员合并到功能分支的工作发生合并冲突。

修复合并冲突通常会在rebase期间更改提交哈希。

当一个开发人员将功能分支的rebase重新放入他们的开发分支时,技术上有两个提交哈希值用于已更正的项目:

  • 旧的提交哈希(pre-rebase / merge-conflicts)仍然留在开发人员分支
  • 新的提交哈希(post-rebase)现在存在于功能分支上。

当此开发人员尝试与功能分支进行比较时,旧提交将被视为新工作和"污垢"拉请求。

我可以轻松地解决问题"通过让他们从最新的功能分支创建一个新分支,并挑选他们的工作。这会丢弃旧的提交哈希值,但这并不高效。

有没有办法改变我们的做法或改变不同的方式,以便我们可以排除"改变"在开发人员分支中提交哈希值?

1 个答案:

答案 0 :(得分:3)

TL; DR版本:让每个人都使用git pull --rebase


如果我理解正确,你就有这种情况。

A - B - C [m]
     \
      D - E - F [f]
           \
            G - H - I [d]

m表示master,f表示功能分支,d表示dev分支。您希望能够将f重新定义为m并将d重新绑定到新f。

                     G1 - H1 - I1 [d]
                     /
          D1 - E1 - F1 [f]
         /
A - B - C [m]
     \
      D - E - F
           \
            G - H - I

答案是让每个人git pull --rebase等同于git fetch加上git rebase。以下是它的工作原理。这就是在将工作推送到掌握(提交C)后,存储库的样子。

origin
A - B - C [m]
     \
      D - E - F [f]
           \
            G - H - I [d]

feature branch maintainer
A - B [m][o/m]
     \
      D - E - F [f][o/f]
           \
            G - H - I [o/d]

dev branch maintainer
A - B [m][o/m]
     \
      D - E - F [o/f]
           \
            G - H - I [d][o/d]

功能分支维护者决定更新时间,因此他们git pull --rebase origin master。这样做git fetch origin加上git rebase origin/master。导致这一点。

feature branch maintainer
             D1 - E1 - F1 [f]
            /
A - B [m]- C [o/m]
     \
      D - E - F [o/f]
           \
            G - H - I [o/d]

然后他们git push origin(我相信他们需要强迫),这就是结果。

origin
             D1 - E1 - F1 [f]
            /
A - B - C [m]
     \
      D - E
           \
            G - H - I [d]

feature branch maintainer
             D1 - E1 - F1 [f][o/f]
            /
A - B [m]- C [o/m]
     \
      D - E
           \
            G - H - I [o/d]

dev branch maintainer
A - B [m][o/m]
     \
      D - E - F [o/f]
           \
            G - H - I [d][o/d]

现在,dev分支维护者想要更新,幸福地没有意识到功能分支发生了任何事情。他们git pull --rebase相当于git fetch origingit rebase origin/feature。获取后,它看起来像这样。

dev branch maintainer
             D1 - E1 - F1 [o/f]
            /
A - B [m]- C[o/m]
     \
      D - E
           \
            G - H - I [d][o/d]

然后是git rebase origin/feature

dev branch maintainer
                         G1 - H1 - I1 [d]
                        /
             D1 - E1 - F1 [o/f]
            /
A - B [m]- C[o/m]
     \
      D - E
           \
            G - H - I [o/d]

他们可以用--force来推动它。

你会注意到dev分支在F1上,而不是原来的E1。如果你想保持你必须专门修改到E1。


如果Git无法弄清楚D和E实际上并不是开发分支的一部分,那么你可能会对此感到厌烦。

dev branch maintainer
                         D2 - E2 - G1 - H1 - I1 [d]
                        /
             D1 - E1 - F1 [o/f]
            /
A - B [m]- C[o/m]
     \
      D - E
           \
            G - H - I [o/d]

Git应该能够使用" patch id"这类似于提交ID,但它们只检查内容而不检查其余内容。如果它不能,请尝试更新Git并查看是否有帮助。如果它仍然无法做到,那么你就是git-rebase docs所称的"硬案例"。你必须拼写出Git,你希望用--onto来修改。幸运的是,reflog包含功能分支的先前位置为f @ {1},您可以将其用作参考。

git rebase --onto f f@{1}

这就是说将当前分支(d)重新定义为f,但只将d从d变为f {1}(这就是以前的f)。


git pull --rebase别名git repull。我几乎完全这样做,它相当安全,而且通常是正确的。您可以使用git config --global pull.rebase true将其配置为默认值。

有关详细信息,请参阅Recovering From An Upstream Rebase in the git-rebase docs