列出压扁的提交

tak*_*hin 5 git git-rebase git-reflog

在我做了交互式rebase之后:git rebase -i HEAD~20我得到了一个新的提交,例如ea1234ea

我知道历史记录在reflog中,但是如何获得此提交中压缩的提交列表,包括它们的标识符(sha)

git show ea1234ea 将显示一个提交消息,其中列出了被压扁的消息,但没有标识符.

tor*_*rek 3

从...开始git reflog。输出将如下所示(但有更多rebase -i条目):

\n\n
aa4e140 HEAD@{0}: rebase -i (finish): returning to refs/heads/branch\naa4e140 HEAD@{1}: rebase -i (squash): c1-c3, squashed\n3a422a7 HEAD@{2}: rebase -i (squash): # This is a combination of 2 commits.\nf7cac12 HEAD@{3}: rebase -i (start): checkout HEAD~3\n283263c HEAD@{4}: commit: blah yadda etc, but not a rebase\n
Run Code Online (Sandbox Code Playgroud)\n\n

最后一个非rebase行具有提交的 SHA1,该提交您执行rebase -i. 此时,您可能想在其上粘贴临时分支或标签,尽管这在技术上不是必需的。在这里我将temp在其上放置一个轻量级标签,命名为:

\n\n
git tag temp 283263c\n
Run Code Online (Sandbox Code Playgroud)\n\n

现在你可以简单地运行git log temp, 或(将其限制为您重新设置的基础):

\n\n
git log temp --not HEAD\n
Run Code Online (Sandbox Code Playgroud)\n\n

或者:

\n\n
git log temp ^HEAD\n
Run Code Online (Sandbox Code Playgroud)\n\n

(这是拼写同一事物的两种方式)1,或:

\n\n
git log -n 20 temp\n
Run Code Online (Sandbox Code Playgroud)\n\n

(这使用了 rebased 中有 20 次提交的事实HEAD~20..HEAD,只有当原始历史是线性的时才是正确的,当然取决于该~20部分)。

\n\n

完成临时标签后,将其删除:

\n\n
git tag -d temp\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n\n

其工作原理是,rebase -i实际上并不删除 任何提交,它只是添加 新的提交。(事实上​​,几乎每个 git 命令都是如此。垃圾收集过程除外,它会删除未引用的对象。)

\n\n

完整的变基“提交和分支”参数(即忽略像-i-p标志这样的重要内容)是:start-pointdestinationbranch-name。该文档巧妙地将前两个伪装为“upstream”和“onto”(说真的,“onto”不是一个坏名字,我将在下面坚持使用它,但“upstream”在某些情况下会产生误导)。start-point之后的所有提交,直到branch的顶端,都被复制(或省略或压缩或其他什么),本质上是通过一次一个地挑选它们,作为添加到生长在的分支上的提交目的地。如果原始提交树看起来(部分)像这样:

\n\n
old -- start-point -- c2 -- c3 -- c4   <-- branch\n    \\\n      onto -- c6 -- c7                 <-- another-branch\n
Run Code Online (Sandbox Code Playgroud)\n\n

然后变基开始通过复制(或“重播更改”) (起点后的c2第一次提交)到相同的更改(但具有不同的提交信息) ,将其放置为其父级:c2\'onto

\n\n
old -- start-point -- c2 -- c3 -- c4   <-- branch\n    \\\n      onto -- c6 -- c7                 <-- another-branch\n        \\\n          c2\'\n
Run Code Online (Sandbox Code Playgroud)\n\n

然后它复制c3到一个新的 ( c3\') 版本,c3\'\ 的父版本是c2\',依此类推。当这一切完成后,它会将标签 ( branch) 从 上剥离c4,并将其粘贴到指向最后一个新提交 ( c4\') 上:

\n\n
old -- start-point -- c2 -- c3 -- c4   <-- [no label]\n    \\\n      onto -- c6 -- c7                 <-- another-branch\n        \\\n          c2\' -- c3\' -- c4\'            <-- branch\n
Run Code Online (Sandbox Code Playgroud)\n\n

请注意,旧的提交(start-pointc2c3c4)仍然存在,只是不再具有分支标签。另请注意,在这种特殊情况下(使用--onto如图所示的参数和特定的提交树),名为自身的提交变得“不可见”(与throughstart-point含义相同),因为它不再有任何分支或标签指向它\xe2\x80\x94,当然,除非您在执行变基之前或之后设置了一个。(通常没有这样的“跳过”提交。当然,在交互式变基中,您可以让它跳过一些提交,但是很明显您打算这样做。)c2c4

\n\n

未标记的(“不可见”或“隐藏”)提交只要保留在引用日志中(90 天,除非您更改默认设置),就会一直存在。为了使它们停留更长时间,请设置一个标签\xe2\x80\x94(例如分支或标记名称\xe2\x80\x94)来指向它们。这就是我对temp上面标签所做的事情。现在它们再次可见,并且可以在任何提交树查看器中轻松查看,例如gitkgit log中轻松查看。

\n\n

(如果您要求交互式变基“压缩”多个提交,它只是将更改折叠到一个提交中。由于每个新提交都是一个副本\xe2\x80\x94a“重播”,就像\xe2\x80\ x94很容易将更多更改堆叠在一起,将它们全部作为一个压缩提交提交。如果您省略某个提交,它只会跳过它,仅复制其余的。如果您重新排序提交,它只会复制它们按照新的顺序排列。)

\n\n
\n\n

1它的拼写方式还有很多。事实上,git log HEAD..temp尽管看起来是错误的,但不知何故,它确实奏效了。:-) 这些版本都假设这HEAD仍然是您进行变基操作的分支的名称。例如,如果您在分支机构,squiggle则可以使用git log temp ^squiggle, 一旦移动到其他地方。HEAD

\n