Github 合并成功后仍然显示分支之间的差异
Github still shows differences between branches after sucessfull merge
最近我将一个巨大的 pull request(140 次提交)从功能分支合并到 master:
我可以在 master 分支的 github overiew 中看到合并:
然而,当我切换到功能分支时,我可以看到该功能提前 141 次提交(今天我对功能进行了另一次提交)和 1 次落后于主提交:
现在的主要问题是,我无法将我今天在功能上所做的更改合并到 master 中:
因为 github 似乎想再次提交已经合并的 140 个旧提交(在一些痛苦的冲突解决之后)
我怎样才能再次同步 master 和 feature,所以它们就是它们实际的样子:它们之间的区别是 ONLY 从今天开始对 feature 的提交。
正如@matt 所说,您可能没有合并,而是被压扁或变基之类的。那么你能做的最好的事情就是在基础分支之上重新设置单个修订的基础:
git checkout feature-branch
git rebase --onto origin/the-base-branch feature-branch~ feature-branch
这会将分支置于基本分支之上...如果您使用的是之前用于创建 PR 的同一分支,则可能必须 force-push,因为该历史不是 真的 合并到基础分支所以正常的推送会失败。
看起来您正在使用两个 long-running 分支并使用压缩合并。这有点问题,原因如下。
当 Git 执行合并时,它只考虑三个点:您要合并的两个头和第三个点,称为 合并基础 ,它通常是他们的共同祖先。合并的结果是合并基和每个头的变化之和。
如果您使用正常的合并提交合并两个分支,那么您将创建一个新的共同祖先,因此未来的合并将从该基础开始。您不必担心已经合并的内容发生冲突,因为 Git 甚至不考虑它们。
当您使用压缩合并合并两个分支时,您在一个分支上创建了一个提交,其中包括来自另一个分支的所有更改,但您没有创建一个新的共同祖先。因此,当您尝试再次合并时,Git 会查看双方的所有更改,并且您最终可能会遇到很多冲突。如果你继续挤压合并两个分支,这只会变得更糟。
因此,您确实必须使用正常的合并提交来集成两个long-running 分支,除非您真的想一直解决很多冲突。壁球合并在这里不起作用。
如果 feature
不需要是 long-running,那么只需从 master
重新创建它。 Git 非常擅长创建功能分支,一旦它们合并,您就可以丢弃这些分支。这是解决这个问题最简单的方法。由于您有一个需要包含的提交,因此只需按照类似于 eftshift0 概述的步骤进行操作:
$ git checkout feature
$ git rebase --onto master HEAD^
# optionally:
$ git push origin +feature
否则,这是解决此问题的最简单方法。在你的 squash 合并之前立即在 master
上提交,并将其命名为 A
。将您合并的 feature
上的提交命名为 B
.
$ git checkout -b temp A
$ git merge B
$ git checkout master
$ git merge temp
这将创建一个名为 temp
的分支,它看起来与压缩合并完全一样,但具有真正的合并提交,然后将其合并到 master
中。此合并是 no-op 因为双方完全相同,所以您不必解决任何冲突。然而,双方现在共享一个新的共同祖先,未来的合并可以基于这个祖先,这解决了这个问题。然后,您可以在集成两个分支时使用正常的合并提交。
最近我将一个巨大的 pull request(140 次提交)从功能分支合并到 master:
我可以在 master 分支的 github overiew 中看到合并:
然而,当我切换到功能分支时,我可以看到该功能提前 141 次提交(今天我对功能进行了另一次提交)和 1 次落后于主提交:
现在的主要问题是,我无法将我今天在功能上所做的更改合并到 master 中:
因为 github 似乎想再次提交已经合并的 140 个旧提交(在一些痛苦的冲突解决之后)
我怎样才能再次同步 master 和 feature,所以它们就是它们实际的样子:它们之间的区别是 ONLY 从今天开始对 feature 的提交。
正如@matt 所说,您可能没有合并,而是被压扁或变基之类的。那么你能做的最好的事情就是在基础分支之上重新设置单个修订的基础:
git checkout feature-branch
git rebase --onto origin/the-base-branch feature-branch~ feature-branch
这会将分支置于基本分支之上...如果您使用的是之前用于创建 PR 的同一分支,则可能必须 force-push,因为该历史不是 真的 合并到基础分支所以正常的推送会失败。
看起来您正在使用两个 long-running 分支并使用压缩合并。这有点问题,原因如下。
当 Git 执行合并时,它只考虑三个点:您要合并的两个头和第三个点,称为 合并基础 ,它通常是他们的共同祖先。合并的结果是合并基和每个头的变化之和。
如果您使用正常的合并提交合并两个分支,那么您将创建一个新的共同祖先,因此未来的合并将从该基础开始。您不必担心已经合并的内容发生冲突,因为 Git 甚至不考虑它们。
当您使用压缩合并合并两个分支时,您在一个分支上创建了一个提交,其中包括来自另一个分支的所有更改,但您没有创建一个新的共同祖先。因此,当您尝试再次合并时,Git 会查看双方的所有更改,并且您最终可能会遇到很多冲突。如果你继续挤压合并两个分支,这只会变得更糟。
因此,您确实必须使用正常的合并提交来集成两个long-running 分支,除非您真的想一直解决很多冲突。壁球合并在这里不起作用。
如果 feature
不需要是 long-running,那么只需从 master
重新创建它。 Git 非常擅长创建功能分支,一旦它们合并,您就可以丢弃这些分支。这是解决这个问题最简单的方法。由于您有一个需要包含的提交,因此只需按照类似于 eftshift0 概述的步骤进行操作:
$ git checkout feature
$ git rebase --onto master HEAD^
# optionally:
$ git push origin +feature
否则,这是解决此问题的最简单方法。在你的 squash 合并之前立即在 master
上提交,并将其命名为 A
。将您合并的 feature
上的提交命名为 B
.
$ git checkout -b temp A
$ git merge B
$ git checkout master
$ git merge temp
这将创建一个名为 temp
的分支,它看起来与压缩合并完全一样,但具有真正的合并提交,然后将其合并到 master
中。此合并是 no-op 因为双方完全相同,所以您不必解决任何冲突。然而,双方现在共享一个新的共同祖先,未来的合并可以基于这个祖先,这解决了这个问题。然后,您可以在集成两个分支时使用正常的合并提交。