当我执行交互式变基后:git rebase -i HEAD~20
,我得到了一个新的提交,例如ea1234ea。
我知道历史记录在reflog中,但是如何获取被压缩到此提交中的提交列表包括它们的标识符(sha)?
git show ea1234ea
会显示一个提交消息,其中列出了被压缩的消息,但不包括标识符。
当我执行交互式变基后: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
的命令包含了在你执行 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
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-point
、c2
、c3
和c4
)仍然存在,只是不再有分支标签。请注意,在这种特殊情况下(使用如上所示的--onto
参数,并使用此特定的提交树),命名为start-point
的提交本身变得“不可见”(与c2
到c4
同义),因为它不再具有任何指向它的分支或标签标签-除非在重新定位之前或之后设置一个标签。 (通常没有这样的“跳过”提交。当然,在交互式重新定义中,您可以让它跳过某些提交,但那时您打算这样做是清楚的。)temp
标记的方式。现在它们又可见了,并且在任何提交树查看器(例如gitk
或git log
)中都很容易看到。git log HEAD..temp
就可以解决问题,尽管看起来有点奇怪。 :-) 这些版本都假设HEAD
仍然是您对其进行重新定义的分支的名称。例如,如果您处于squiggle
分支上,则可以在HEAD
移动到其他位置后使用git log temp ^squiggle
。