无法理解git交互式rebase期间reword标志的行为

时间:2017-10-23 16:47:16

标签: git git-rebase

我几乎没有与git interactive rebase相关的问题。 首先,我在本地计算机上创建了一个git存储库,并执行了5次提交。

  1. 当我点击git rebase -i HEAD~5时,我收到以下错误

    fatal: Needed a single revision
    invalid upstream HEAD~5
    

    我不明白上述错误的原因

  2. 当我到达rebase交互式shell时,我使用r标志尝试了reword选项并提供了更新的消息。当我尝试保存并退出时,启动了另一个终端来传递提交消息。我错过了什么。有人可以教育我这个行为。

1 个答案:

答案 0 :(得分:2)

从根本上说,rebase通过复制提交。例如,假设您有四个我在下面标记为AD的提交,并且您希望将branch重新绑定到mainline

...--o--o--T   <-- mainline
      \
       A--B--C--D   <-- branch (HEAD)

git rebase mainline将会复制 A到“A'的新提交A,但同样好或更好“:

             A'   <-- temporary (HEAD)
            /
...--o--o--T   <-- mainline
      \
       A--B--C--D   <-- branch

AA'之间的区别在于A'Tmainline的提示,作为其父提交。 (如果您使用交互式rebase,它还有您需要做的任何其他更改。)

A复制到A'后,git rebase会继续复制B,然后CD。最终,结果是:

             A'-B'-C'-D'   <-- temporary (HEAD)
            /
...--o--o--T   <-- mainline
      \
       A--B--C--D   <-- branch

现在所有提交都已复制,git rebase“剥离”旧分支标签branch并移动它以替换临时分支名称:

             A'-B'-C'-D'   <-- branch (HEAD)
            /
...--o--o--T   <-- mainline
      \
       A--B--C--D   [abandoned]

您传递给git rebase的参数是您希望副本执行的提交的名称。在这种情况下,名称mainline名称提交T,因此副本会追溯到T

既然您已经知道这一点,并且注意到HEAD~5意味着“从HEAD算上五步”,我们可以解释您的问题:

  

git rebase -i HEAD~5 [失败]

假设您要复制的链中只有 五个提交:

A--B--C--D--E   <-- master

其中A没有提交,即 root 提交。 HEAD名称提交EHEAD~1个名称DHEAD~2个名称C,依此类推。什么提交是HEAD~5

A 之前没有提交。 git rebase通常用于在某些现有提交之后复制提交,但如果您想复制A本身,您将如何命名提交A之前的提交复制应该继续,让rebase从提交A开始复制?

这是--root的来源:git rebase --root允许您复制A本身。 Git使用了许多特殊技巧来做到这一点,最终结果是一个独立的副本链:

A--B--C--D--E   [abandoned]

A'-B'-C'-D'-E'  <-- master
  

当我到达rebase交互式shell时,我使用r标志尝试了reword选项并提供了更新的消息。当我尝试保存并退出时,它启动了另一个终端来传递提交消息。

所有rewordr都会修改复制过程:Git仍会将提交一次一个地复制到新的提交中,但是当它转到“reword”的副本时“提交,它会触发git commit --edit而不是git commit --no-edit。这会在原始提交消息上显示您的编辑器,您现在可以重新编写该消息。

您最初编辑的说明书不允许您更改整个提交消息,因为提交消息(或应该)不仅仅是一行。因此,除了从pick更改命令之外,它最终完全忽略您所做的任何其他更改。

新的编辑器会话仅适用于一个特定的提交。

(更确切地说,命令pick <hash>字面意思是对给定的哈希值运行git cherry-pick。哈希ID必须是有效的。如果你在说明书中重新排列这些行,你会重新安排交互式rebase运行的git cherry-pick命令的顺序。如果你删除或注释掉一行,Git绝不会挑选那个特定的提交。使用reword代替pick只是cherry-pick提交交互式,而不是完全自动化。)