在我进行交互式 rebase 之后:git rebase -i HEAD~20
我得到一个新的提交,例如ea1234ea
我知道历史记录在 reflog 中,但是我怎样才能获得在此提交中压缩的提交列表,包括它们的标识符 (sha)?git show ea1234ea
将显示一个提交消息,其中列出了被压扁的消息,但没有标识符。
最佳答案
从 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
行具有提交的 SHA1,它是您执行 rebase -i
之前的 HEAD .此时您可能希望在其上粘贴一个临时分支或标记标签,尽管这在技术上不是必需的。在这里,我将放置一个名为 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 “提交和分支”参数(即忽略重要的东西,如
-i
和 -p
标志)是:起点、目的地和分支名称。该文档巧妙地将 :-) 前两个伪装为“上游”和“onto”(说真的,“onto”不是一个坏名字,我将在下面坚持使用,但“上游”在某些情况下会产生误导)。起点之后的所有提交,直到分支的尖端,都被复制(或省略或压缩或其他什么),基本上,一次一个地挑选它们,作为一个新的提交添加到一个增长的分支上目的地。如果原始提交树看起来(部分)是这样的: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'
的 parent 是 c2'
, 等等。全部完成后,它会从 branch
上剥下标签 ( c4
) ,并将其粘贴到指向最后一个新提交 ( c4'
) 上:old -- start-point -- c2 -- c3 -- c4 <-- [no label]
\
onto -- c6 -- c7 <-- another-branch
\
c2' -- c3' -- c4' <-- branch
请注意,旧的提交(
start-point
、 c2
、 c3
和 c4
)仍然存在,只是不再有分支标签。还要注意,在这种特殊情况下(使用所示的 --onto
参数,使用这个特定的提交树),提交名为 start-point
本身变得“不可见”(与 c2
到 c4
的意义相同),因为它不再有任何指向它的分支或标签标签——当然,除非你在执行 rebase 之前或之后设置了一个。 (通常没有这样的“跳过”提交。当然,在交互式 rebase 中,你可以让它跳过一些,但很明显你打算这样做。)未标记(“不可见”或“stash ”)提交只要保留在引用日志中(90 天,除非您更改默认设置)就会一直存在。为了让它们停留更长时间,请设置一个标签(例如分支或标签名称)以指向它们。这就是我对
temp
所做的上面的标签。现在它们再次可见,并且很容易在任何提交树查看器中看到,例如 gitk
或 git log
.(如果您要求交互式 rebase “压缩”多个提交,它只是将更改 merge 为一个提交。由于每个新提交都是一个副本 - 就像“重放”一样 - 很容易继续堆叠更多更改一起,将它们全部提交为一个压缩提交。如果您省略提交,它只会跳过它,只复制剩余的提交。如果您重新排序提交,它只会以新的顺序复制它们。)
1 还有很多拼写方法。事实上,
git log HEAD..temp
以某种方式,即使看起来不对,也能解决问题。 :-) 这些版本都假设 HEAD
仍然是您进行 rebase 的分支的名称。如果您在分行 squiggle
你可以用 git log temp ^squiggle
, 一次 HEAD
例如,已经搬到别处。
关于git - 列出压缩的提交,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18865842/