列出压扁的提交

时间:2013-09-18 07:04:42

标签: git git-rebase git-reflog

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

我知道历史记录在reflog中,但是如何在此提交中获取包含其标识符(sha)的提交列表?

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

1 个答案:

答案 0 :(得分:2)

git reflog开始。输出看起来像这样(但有更多rebase -i条目):

aa4e140 HEAD@{0}: rebase -i (finish): returning to refs/heads/branch
aa4e140 HEAD@{1}: rebase -i (squash): c1-c3, squashed
3a422a7 HEAD@{2}: rebase -i (squash): # This is a combination of 2 commits.
f7cac12 HEAD@{3}: rebase -i (start): checkout HEAD~3
283263c HEAD@{4}: commit: blah yadda etc, but not a rebase

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

git tag temp 283263c

现在您只需运行git log temp或(将其限制为您重新定位的那些):

git log temp --not HEAD

或:

git log temp ^HEAD

(这两种方法拼写相同的东西) 1 ,或者:

git log -n 20 temp

(这使用了重新定位HEAD~20..HEAD中有20个提交的事实,只有在原始历史是线性的情况下才会出现这种情况,当然这取决于~20部分。

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

git tag -d temp

这样做的方式是rebase -i实际上删除 任何提交,只有添加 提交。 (几乎每个git命令都是如此。例外是垃圾收集过程,它删除了未引用的对象。)

完整的rebase“commit-and-branch”参数集(即忽略-i-p标志等重要内容)是: start-point ,< em>目的地和分支名称。文档巧妙地伪装:-)前两个作为“上游”和“上”(严重地说,“上”不是一个坏名字,我将坚持下面,但“上游”在某些情况下会产生误导)。 start-point 之后的所有提交,直到 branch 的提示,都被复制(或者被省略或者被压扁或者其他),实际上是通过挑选它们来实现的,一段时间,作为提交添加到目的地增长的分支上。如果原始提交树看起来(部分)如下:

old -- start-point -- c2 -- c3 -- c4   <-- branch
    \
      onto -- c6 -- c7                 <-- another-branch

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

old -- start-point -- c2 -- c3 -- c4   <-- branch
    \
      onto -- c6 -- c7                 <-- another-branch
        \
          c2'

然后将c3复制到新的c3')版本,其中c3'的父级为c2',依此类推。完成所有操作后,它会将标签(branch)从c4剥离,然后将其粘贴到指向上一次新提交(c4')的位置:

old -- start-point -- c2 -- c3 -- c4   <-- [no label]
    \
      onto -- c6 -- c7                 <-- another-branch
        \
          c2' -- c3' -- c4'            <-- branch

请注意,旧提交(start-pointc2c3c4)仍然存在,它们不再具有分支标签。还要注意,在这种特殊情况下(使用如此显示的--onto参数,使用此特定的提交树),名为start-point的提交本身变为“不可见”(与{{1}的意义相同) }} c2)因为它不再有任何分支或标签标签指向它 - 当然,除非您在进行rebase之前或之后设置了一个。 (通常没有这样的“跳过”提交。当然在交互式rebase中,你可以 make 它跳过一些,但是很明显你打算这样做。)

未标记(“隐藏”或“隐藏”)提交只要保留在reflog中(90天,除非您更改默认设置)。为了使它们更长时间,请设置标签(例如分支或标签名称)以指向它们。这就是我对上面c4标记的处理方式。现在它们再次可见,并且在任何提交树查看器中都很容易看到,例如tempgitk

(如果你要求交互式rebase“压缩”几个提交,它只是将更改折叠成一个单一的提交。由于每个新提交都是一个副本 - 一个“重放”,因为它是 - 很容易保持将更多的更改堆叠在一起,将它们全部提交为一个squashed-commit。如果省略提交,它只是跳过它,只复制其余的。如果你重新提交提交,它只是按新的顺序复制它们。)< / p>


1 还有很多方法可以拼写它。实际上,git log可以解决这个问题,即使它看起来错误,不知何故。 :-)这些版本都假设git log HEAD..temp仍然是您进行rebase的分支的名称。例如,如果您在分支机构HEAD上,则可以使用squigglegit log temp ^squiggle移动到其他位置。