首页 > 解决方案 > `--abort` 和 `--quit` 作为 `cherry-pick` 的音序器子命令有什么不同?

问题描述

根据文档,在 的三个序列器子命令中cherry-pick,我们有这两个,对我来说,奇怪地相似:

--quit

忘记当前正在进行的操作。可用于在cherry-pick 或revert 失败后清除sequencer 状态。

--abort

取消操作,返回前序状态。


到目前为止,我一直在使用--abort,并且效果很好。什么--quit是不同/优选的用例?

标签: gitgit-cherry-pick

解决方案


如果你记得那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(unnamed, ..., *, ...) 可达的提交。mainline它从feature集合2中减去集合并使用相反的拓扑顺序,因此它现在具有哈希 ID ABC列在 Git 调用的序列器中。(sequencer 也记录操作,在这种情况下 rebase/cherry-pick。sequencer 也用于多个 reverts。sequencer 可以中途停止,然后用 恢复--continue。这就是它需要知道操作的原因:我们继续挑选、恢复或变基?)

Git 然后HEAD在提交时分离mainline并通过排序器运行操作,无论它是什么。由于操作是“rebase”,因此序列器的每一步都是一个简单的单次提交樱桃选择:

(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'),或者选择两种停止中的一种,“中止”或“退出”。如果你恢复——或者如果事情进展顺利——我们继续(尝试)cherry-pick B

                  A'-B'   <-- HEAD
                 /
...--o--*--...--o   <-- mainline
         \
          A--B--C   <-- feature

假设这也成功了,我们继续尝试挑选C,但这次尝试失败了。定序器停止,在索引和工作树中留下一团糟,与我们在上面看到的相同的图:A'存在B'C'不存在。

假设我们决定停止:目前完成挑选的樱桃C太难了,我们需要退后一步,做点别的事情。您现在有两个选择,abortquit

如果你选择--abort,Git 会重新附加你的HEADto feature,给出:

...--o--*--...--o   <-- mainline
         \
          A--B--C   <-- feature (HEAD)

A'和在哪里B'?好吧,如果您知道自己在做什么,则可以将它们从 reflog 中找出来,或者您在选择B' 之前--abort已经巧妙地附加了一个分支或标签名称。但是如果你选择,Git 会在不移动--quit的情况下终止 rebase ,这样你就会得到:HEAD

                  A'-B'   <-- HEAD
                 /
...--o--*--...--o   <-- mainline
         \
          A--B--C   <-- feature

但是一个干净的索引和工作树。因此,您不必足够聪明就可以--quit.

基本上就是这样。:-) 但是在经历了一个漫长而令人沮丧的 rebase 和很多冲突之后,你想保存你到目前为止所取得的成就并在稍后再次回到 rebase 之前回到非 rebase 工作,“退出”变体不知何故感觉更满足。

(我认为这里真正缺少的是保存序列器状态的剩余部分并在以后恢复它的选项。但是,序列器状态是每个工作树的,所以如果你有一个正在进行的变基任务并且必须用更高的中断它优先级任务,你可以只为更高优先级的任务添加一个工作树。通过 Git 2.15 添加的工作树中的各种错误并不是那么鼓舞人心,但它们现在似乎表现得很好。还添加了工作树将纸张覆盖在另一个更大的缺失部分上,这是保存正在进行的冲突合并并在以后恢复它的能力。)


1但是请注意,旧式非交互式git-rebase--am仍然使用git format-patchand git am。在某些重命名文件的情况下,此过程无法正常工作,并且无法复制“不进行更改”提交,但运行速度更快。在大多数情况下,尽管底层机制发生了变化,但这种风格和cherry-pick 风格都应该给出相同的结果,尤其是因为cherry-pick 变体默认不复制“不做任何更改”提交。

2 rebase 还会减去集合中存在的任何提交,并且与集合中的任何提交mainline相同,当然,默认情况下,它会减去所有合并。git patch-idfeature


推荐阅读