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

hel*_*on3 5 git

我想了解更多关于我们团队最近的git问题.我们有几层分支:

-> Master
   |-> Feature Branch
        |-> Individual developer branches
Run Code Online (Sandbox Code Playgroud)

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

当一个与主合并特性分支业主将重订其功能分支.它们经常与从各个开发人员合并到功能分支的任何工作发生合并冲突.

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

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

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

当此开发人员尝试与功能分支进行比较时,旧提交将被视为新工作并且"拉扯"拉取请求.

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

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

Sch*_*ern 5

TL;DR 版本:让大家使用git pull --rebase.


如果我理解正确的话,你就会遇到这种情况。

A - B - C [m]
     \
      D - E - F [f]
           \
            G - H - I [d]
Run Code Online (Sandbox Code Playgroud)

m 代表 master,f 代表功能分支,d 代表开发分支。您希望能够将 f 变基到 m 并将 d 变基到新的 f。

                     G1 - H1 - I1 [d]
                     /
          D1 - E1 - F1 [f]
         /
A - B - C [m]
     \
      D - E - F
           \
            G - H - I
Run Code Online (Sandbox Code Playgroud)

答案是拥有Everyone git pull --rebase,相当于agit fetch加a git rebase。下面是它的工作原理。这就是将工作推送到 master(提交 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]
Run Code Online (Sandbox Code Playgroud)

功能分支维护者决定更新的时间,因此他们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]
Run Code Online (Sandbox Code Playgroud)

然后他们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]
Run Code Online (Sandbox Code Playgroud)

现在开发分支维护者想要更新,幸福地没有意识到功能分支发生了任何事情。它们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]
Run Code Online (Sandbox Code Playgroud)

然后是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]
Run Code Online (Sandbox Code Playgroud)

他们可以推动这一点,可能是通过--force.

您会注意到 dev 分支位于 F1,而不是原来的 E1。如果您想保持这一点,则必须专门重新建立基础到 E1。


如果 Git 无法确定 D 和 E 并不是 dev 分支的真正一部分,那么您可能会遇到这样的情况。

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]
Run Code Online (Sandbox Code Playgroud)

Git 应该能够使用类似于提交 ID 的“补丁 ID”来解决这个问题,但它们只检查内容,而不检查其他内容。如果不能,请尝试更新 Git 并查看是否有帮助。如果仍然无法做到这一点,那么您就处于 git-rebase 文档所说的“困难情况”中。你必须向 Git 说明你想要使用 .rebase 进行 rebase 的提交--onto。幸运的是,引用日志包含功能分支之前的位置 f@{1},您可以将其用作参考。

git rebase --onto f f@{1}
Run Code Online (Sandbox Code Playgroud)

这表示将当前分支 (d) 变基到 f,但仅从 d 变基到 f@{1}(这是 f 曾经所在的位置)。


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

有关更多信息,请参阅文档中的从上游变基恢复git-rebase