列出压缩过的提交记录

5

当我执行交互式变基后:git rebase -i HEAD~20,我得到了一个新的提交,例如ea1234ea。

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

git show ea1234ea会显示一个提交消息,其中列出了被压缩的消息,但不包括标识符。

1个回答

3

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`、`destination` 和 `branch-name`。文档巧妙地掩盖了前两者,将它们伪装成“upstream”和“onto”(说真的,“onto”不是一个糟糕的名称,下面我会坚持使用它,但“upstream”在某些情况下是具有误导性的)。从 `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的提交本身变得“不可见”(与c2c4同义),因为它不再具有任何指向它的分支或标签标签-除非在重新定位之前或之后设置一个标签。 (通常没有这样的“跳过”提交。当然,在交互式重新定义中,您可以让它跳过某些提交,但那时您打算这样做是清楚的。)
未标记(“不可见”或“隐藏”的)提交将保留在引用日志中,只要它们保持在其中(90天,除非更改默认设置)。要使它们长时间保留,请设置标签(例如分支或标记名称)以指向它们。这就是我在上面使用temp标记的方式。现在它们又可见了,并且在任何提交树查看器(例如gitkgit log)中都很容易看到。
(如果您要求交互式重新定义“压缩”多个提交,则将这些更改合并到单个提交中。由于每个新提交都是一个副本-可以说是一个“回放”-所以很容易将更多更改堆叠在一起,将它们全部作为一个压缩提交进行提交。如果省略了某个提交,它只会跳过该提交,只复制剩余的提交。如果重新排序提交,则只会按新顺序复制它们。)
1有很多拼写方式。实际上,git log HEAD..temp就可以解决问题,尽管看起来有点奇怪。 :-) 这些版本都假设HEAD仍然是您对其进行重新定义的分支的名称。例如,如果您处于squiggle分支上,则可以在HEAD移动到其他位置后使用git log temp ^squiggle

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接