git 恢复合并:确定哪个 parent 是哪个(-m 1 vs -m 2)
git revert a merge: determine which parent is which (-m 1 vs -m 2)
我正在尝试还原合并,但我不知道是使用 git revert -m 1 <merge commit's sha>
还是 git revert -m 2 <merge commit's sha>
。我如何找出哪个 parent 是 -m 1
,哪个 parent 是 -m 2
?
嗯,super-short 的答案是总是 -m 1
。 :-) 但这值得一些解释:
parent是有序的,git log
和git show
等命令显示顺序:
commit c13c783c9d3d7d3eff937b7bf3642d2a7fe32644
Merge: 3f7ebc6ec 39ee4c6c2
所以这里 3f7ebc6ec
是 parent #1 而 39ee4c6c2
是 parent #2.
后缀 ^
操作采用这些相同的值:
$ git rev-parse c13c783c9d3d7d3eff937b7bf3642d2a7fe32644^1
3f7ebc6ece46f1c23480d094688b8b5f24eb345c
(当然 ...^2
会是另一个)。
绘制图表的程序,包括 git log --graph
,将向您展示这些是如何连接的。
但最重要的是,任何合并的 第一个 parent 是您进行合并时的最新提交.
特别是,这意味着如果您在分支 main
和 运行 git merge sidebranch
上,您现在(如果一切顺利)或最终(如果您必须手动解决合并)作为其 first parent,main
分支的前一个提示。它的第二个 parent 因此是 sidebranch
.
的尖端
那么,假设我们从以下内容开始:
...--o--*--A--B------C <-- main
\
D--E--F--G--H <-- sidebranch
当我们运行git merge
。公共基础提交是 *
,Git 通过做一个新的合并提交 M,本质上:
git diff * C
(我们改变了什么?)
git diff * H
(他们改变了什么?)
然后组合这两组更改并将它们应用到 *
,得到这个最终结果:
...--o--*--A--B------C--M <-- main
\ /
D--E--F--G--H <-- sidebranch
现在,如果 A-B-C
中更改的所有内容完全独立于 D-E-F-G-H
中更改的所有内容,那么精确 how Git 进行了还原,只要它在放弃 D-E-F-G-H
更改的同时保留 A-B-C
更改即可。
但是如果 B
与 F
大部分相同,即 B
和 F
都修复了一个错误怎么办?在这种情况下,我们不想撤消B
和F
的共享更改,Git复制了一份。 这是 -m 1
部分的用武之地。
当 git revert
去撤消某些更改时,它 运行 它自己的 git diff
。 git diff
it 运行s 将您要还原的提交与其 parent 进行比较。对于任何普通的 non-merge 提交,这很容易:比较 B
与 A
,或 E
与 D
,或其他,看看发生了什么,然后返回出来。但是,对于合并提交,与 parent 进行比较并不明显(除了它有点像 :-) )。这里的第一个parent是C
,我们看看运行:
会得到什么
git diff C M
C
和 M
之间的变化是我们通过 添加 从 D-E-F-G-H
到我们 在A-B-C
中已经有,如果我们比较M
和*
。换句话说:
如果B
和F
重叠100%,C
-vs-M
的变化是D-E-G-H
:一切除了重叠。所以我们最终只恢复了那些。
如果F
比B
有更多的变化,C
-vs-[的变化=52=] 是 D-E-(some-of-F)-G-H
:我们最终恢复了这些更改,但不是 B
.
中的更改
如果F
比B
有更少的变化,C
-vs-[的变化=52=] 又是 D-E-G-H
,我们最终只还原了那些。
由于第一个 parent 是 C
,我们想要取消 D-E-F-G-H
更改(不包括我们已经通过 A-B-C
进行的任何更改),我们想要 -m 1
在此还原中。
我正在尝试还原合并,但我不知道是使用 git revert -m 1 <merge commit's sha>
还是 git revert -m 2 <merge commit's sha>
。我如何找出哪个 parent 是 -m 1
,哪个 parent 是 -m 2
?
嗯,super-short 的答案是总是 -m 1
。 :-) 但这值得一些解释:
parent是有序的,
git log
和git show
等命令显示顺序:commit c13c783c9d3d7d3eff937b7bf3642d2a7fe32644 Merge: 3f7ebc6ec 39ee4c6c2
所以这里
3f7ebc6ec
是 parent #1 而39ee4c6c2
是 parent #2.后缀
^
操作采用这些相同的值:$ git rev-parse c13c783c9d3d7d3eff937b7bf3642d2a7fe32644^1 3f7ebc6ece46f1c23480d094688b8b5f24eb345c
(当然
...^2
会是另一个)。绘制图表的程序,包括
git log --graph
,将向您展示这些是如何连接的。但最重要的是,任何合并的 第一个 parent 是您进行合并时的最新提交.
特别是,这意味着如果您在分支 main
和 运行 git merge sidebranch
上,您现在(如果一切顺利)或最终(如果您必须手动解决合并)作为其 first parent,main
分支的前一个提示。它的第二个 parent 因此是 sidebranch
.
那么,假设我们从以下内容开始:
...--o--*--A--B------C <-- main
\
D--E--F--G--H <-- sidebranch
当我们运行git merge
。公共基础提交是 *
,Git 通过做一个新的合并提交 M,本质上:
git diff * C
(我们改变了什么?)git diff * H
(他们改变了什么?)
然后组合这两组更改并将它们应用到 *
,得到这个最终结果:
...--o--*--A--B------C--M <-- main
\ /
D--E--F--G--H <-- sidebranch
现在,如果 A-B-C
中更改的所有内容完全独立于 D-E-F-G-H
中更改的所有内容,那么精确 how Git 进行了还原,只要它在放弃 D-E-F-G-H
更改的同时保留 A-B-C
更改即可。
但是如果 B
与 F
大部分相同,即 B
和 F
都修复了一个错误怎么办?在这种情况下,我们不想撤消B
和F
的共享更改,Git复制了一份。 这是 -m 1
部分的用武之地。
当 git revert
去撤消某些更改时,它 运行 它自己的 git diff
。 git diff
it 运行s 将您要还原的提交与其 parent 进行比较。对于任何普通的 non-merge 提交,这很容易:比较 B
与 A
,或 E
与 D
,或其他,看看发生了什么,然后返回出来。但是,对于合并提交,与 parent 进行比较并不明显(除了它有点像 :-) )。这里的第一个parent是C
,我们看看运行:
git diff C M
C
和 M
之间的变化是我们通过 添加 从 D-E-F-G-H
到我们 在A-B-C
中已经有,如果我们比较M
和*
。换句话说:
如果
B
和F
重叠100%,C
-vs-M
的变化是D-E-G-H
:一切除了重叠。所以我们最终只恢复了那些。如果
F
比B
有更多的变化,C
-vs-[的变化=52=] 是D-E-(some-of-F)-G-H
:我们最终恢复了这些更改,但不是B
. 中的更改
如果
F
比B
有更少的变化,C
-vs-[的变化=52=] 又是D-E-G-H
,我们最终只还原了那些。
由于第一个 parent 是 C
,我们想要取消 D-E-F-G-H
更改(不包括我们已经通过 A-B-C
进行的任何更改),我们想要 -m 1
在此还原中。