合并后哪个提交是 HEAD^,为什么它不是正确的提交

  • 本文关键字:提交 HEAD 合并 git
  • 更新时间 :
  • 英文 :


我有main:

* 38f4e95 - (HEAD -> main, origin/main) …
* 2abcc91 - nginx configs blue and green …

从main,我合并一个分支,现在我有:

*   461eb66 - (HEAD -> main, 
|  
| * 38f4e95 - (origin/main) .
| * 2abcc91 - nginx configs b
| *   320c676 - Merge branch 
| |  
| * | 46d0cbd - fix filter (3
* | | 7ea521f - EF Migration 

我期望HEAD^38f4e95. 但这不是,这是几天前提交的一份文件,其中丢失了一大堆工作。为什么?

  • 相反,HEAD^2是我期望的HEAD^1(又名HEAD^)。

  • 在合并到main之前,我的习惯是首先从main合并到branch(这样问题就会在branch中被发现和修复)。这有什么区别吗?

  • 当然,这个问题源于想要撤销合并。看起来git reset HEAD^ --hard应该只是撤消上次提交的东西,但相反,我必须非常小心或首先记下"前一次"提交是什么,或者希望从远程重置将巧妙地解决它。

HEAD^1HEAD^2都是合并提交的父级。man gitrevisions:

有一个很好的说明
Here is an illustration, by Jon Loeliger. Both commit nodes B and C are
parents of commit node A. Parent commits are ordered left-to-right.
G   H   I   J
 /      /
D   E   F
  |  / 
 | /   |
|/    |
B     C
   /
 /
A
A =      = A^0
B = A^   = A^1     = A~1
C =      = A^2
D = A^^  = A^1^1   = A~2
E = B^2  = A^^2
F = B^3  = A^^3
G = A^^^ = A^1^1^1 = A~3
H = D^2  = B^^2    = A^^^2  = A~2^2
I = F^   = B^3^    = A^^3^
J = F^2  = B^3^2   = A^^3^2

这是因为您在快进中描述的工作流程合并:

在合并到main之前,我的习惯是首先从main合并到分支(这样问题就会在分支中被发现和修复)。这有什么区别吗?

这就是它发生的原因!如果你检查出my-branch并从main合并,那么main(commit 38f4e95)是该合并提交的第二个父级。当你切换到main并合并my-branch时,这是一个快进合并,所以分支在那一刻是等效的。

注意,第一父母和第二父母不能根据观点切换-他们被"烤成";提交。

所以,是的,如果您需要恢复,您将需要仔细检查第一和第二父节点,以确保您恢复了正确的方向。您可以使用git log --first-parent来查看-m1会产生什么。(即使是git log也会按照正确的顺序显示父提交。)

建议:这里有两个可能的调整,你可以做你的工作流程,以防止这种情况在未来发生(这两个都可以防止它,但我个人更喜欢两个):

  1. 与其将main合并到你的特性分支中,你可以将你的分支重新定位到main来更新它。这样你就不会添加"反向合并"了。这可能会被快速转发到main,从而翻转所需的父订单。
  2. 当合并到main时,选择--no-ff选项强制创建一个新的合并提交。那么第一个父级将永远是你所期望的。

最新更新