我有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^1
和HEAD^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
也会按照正确的顺序显示父提交。)
建议:这里有两个可能的调整,你可以做你的工作流程,以防止这种情况在未来发生(这两个都可以防止它,但我个人更喜欢两个):
- 与其将
main
合并到你的特性分支中,你可以将你的分支重新定位到main
来更新它。这样你就不会添加"反向合并"了。这可能会被快速转发到main
,从而翻转所需的父订单。 - 当合并到
main
时,选择--no-ff
选项强制创建一个新的合并提交。那么第一个父级将永远是你所期望的。