根据文档,在用于cherry-pick
的三个音序器子命令中,我们有这两个对我来说非常相似:
--quit
忘记当前正在进行的操作。可用于在挑选或还原失败后清除音序器状态。
--abort
取消操作并返回到预序列状态。
到目前为止,我一直使用--abort
,效果很好。--quit
不同/更可取的用例是什么?
如果你还记得git rebase
是一系列git cherry-pick
操作,1加上开头和结尾的几个有用的噱头,那就更有意义了。
假设您有以下一系列提交:
...--o--*--...--o <-- mainline
A--B--C <-- feature
您希望feature
与mainline
保持同步,以便:
git checkout feature
git rebase mainline
Git 首先枚举可从feature
访问的提交(C
、B
、A
、*
、...)和可从mainline
访问的提交(未命名、...、*
、...)。 它从feature
集合2中减去mainline
集,并使用反向拓扑顺序,因此它现在在 Git 调用序列器的东西中列出了哈希 IDA
、B
和C
。 (音序器还记录操作,在这种情况下是变基/樱桃采摘。 序列器还用于多次还原。 音序器可以在中途停止,然后通过--continue
恢复。 这就是为什么它需要知道操作的原因:我们是继续挑选樱桃、恢复还是变基?
然后,Git 在mainline
尖端的提交处分离HEAD
,并通过音序器运行操作,无论它是什么。 由于操作是"变基"的,因此音序器的每一步都是一个简单的单提交挑剔:
(with)
...--o--*--...--o <-- mainline, HEAD
A--B--C <-- feature
(execute git cherry-pick A to produce)
A' <-- HEAD
/
...--o--*--...--o <-- mainline
A--B--C <-- feature
这可能会因合并冲突而失败。 如果是这样,排序器将停止,在索引和工作树中留下一堆合并冲突。 您可以修复它们并恢复音序器(如果您自己没有进行A'
,它将在需要时提交您进行A'
),或者选择两种停止之一,"中止"或"退出"。 如果您恢复 - 或者如果事情进展顺利 - 我们将继续(尝试)挑选B
:
A'-B' <-- HEAD
/
...--o--*--...--o <-- mainline
A--B--C <-- feature
假设这也成功了,我们继续尝试挑选C
但这次尝试失败了。 音序器停止,在索引和工作树中留下一团糟,与上面看到的图表相同:A'
和B'
存在,但C'
不存在。
假设我们决定停止:完成C
的樱桃选择暂时太难了,我们需要退后一步,做点别的事情。 您现在有两个选项:中止或退出。
如果你选择--abort
,Git 会重新将你的HEAD
附加到feature
,给出:
...--o--*--...--o <-- mainline
A--B--C <-- feature (HEAD)
A'
和B'
在哪里? 好吧,如果您知道自己在做什么,则可以将它们从 reflog 中捞出来,或者在选择--abort
之前,您已经巧妙地将分支或标签名称附加到B'
。 但是如果你选择--quit
,Git 会在不移动HEAD
的情况下终止变基,这样你最终会得到:
A'-B' <-- HEAD
/
...--o--*--...--o <-- mainline
A--B--C <-- feature
但现在可以用git reset --hard
为自己获得干净的索引和工作树。 (或者,你可以把混乱留在原地。 因此,您不必足够聪明地在--quit
之前附加分支名称。
这基本上就是它的全部内容。 但是,在经历了漫长而令人沮丧的变基和很多冲突之后,你想保存你到目前为止所取得的成就并回到非变基工作,然后再回到变基,"退出"变体以某种方式感觉更令人满意。
(我认为这里真正缺少的是保存音序器状态的其余部分并在以后恢复它的选项。 但是,排序器状态是按工作树的,因此,如果您有一个正在进行的变基任务,并且必须使用更高优先级的任务中断它,则可以为更高优先级的任务添加一个工作树。 通过 Git 2.15 添加的工作树中的各种错误并不是那么鼓舞人心,但它们现在似乎表现得很好。 添加的工作树还覆盖了另一个更大的缺失部分,即保存正在进行的冲突合并并在以后恢复它的能力。
1但请注意,旧式非交互式git-rebase--am
仍然使用git format-patch
和git am
。 在某些情况下,此过程不适用于重命名的文件,并且无法复制"不进行任何更改"提交,但运行速度更快。 在大多数情况下,尽管底层机制发生了变化,但这和樱桃选择样式应该给出相同的结果,特别是因为樱桃选择变体默认不复制"不进行任何更改"提交。
2变基还会减去mainline
集中存在的任何提交,并且与feature
集中的任何提交具有相同git patch-id
,当然,默认情况下,它会减去所有合并。
--abort
将带您回到开始樱桃拣选操作之前的位置,而--quit
将退出操作并使您保持当前所在的修订版。我想不出除了你想在你遇到一个无法自动挑选的修订后走上不同的方向之外的用例,这就是为什么樱桃采摘首先停止的原因,对吧?