假设我有一些提交:
<sha1> bug due to function1
<sha2> bug due to function2
... other commits
我想将提交1和2压缩在一起,只保留第二次提交的消息,然后我会使用git rebase -i
,编辑到:
pick <sha1> bug due to function1
squash <sha2> bug due to function2
... other commits
我总是需要编辑组合的消息并删除第一个消息。
我知道我可以重新排列提交并使用fixup
这样:
pick <sha2> bug due to function2
fixup <sha1> bug due to function1
pick <sha3> other commit
但是我有风险,扭转两次提交的顺序,可能会有一些冲突。
如何以较少的操作实现相同的结果,尤其是避免编辑组合消息。请注意,在提交1之前和提交2之后可能会有许多提交。
答案 0 :(得分:2)
首先执行git log
查看最后四次提交的哈希值。重置为要压缩的两个之前的最后一次提交:
git reset --hard <sha0>
...在你要挤压的那两个之前的最后一次提交。
然后,按顺序尝试以下命令:
git cherry-pick -n <sha1>
git cherry-pick -n <sha2>
git commit
git cherry-pick <sha3>
前两个命令会将<sha1>
和<sha2>
合并到您的本地登台沙箱中。当您执行git commit
没有参数时,它将使用上次提交的提交消息提交更改。您需要做的就是在查看提交消息后退出编辑器。最后的挑选应用最后一次提交,不变。
答案 1 :(得分:0)
完全自动化的版本。假设这样的git历史:
... (as many commits as you like)
6acdc6f - commit message 3
46c9468 - commit message 2
9b28fd5 - commit message 1
然后重新定位将提交1和2压缩并保持提交消息2 :
git rebase -i 9b28fd5~
然后像这样编辑:
pick 9b28fd5 commit message 1
pick 46c9468 commit message 2
exec HH=$(git rev-parse HEAD); git reset --soft HEAD~2; git commit -C $HH
pick 6acdc6f commit message 3
shell命令的一个小解释:
HH=$(git rev-parse HEAD) # store the HEAD sha1 in a variable; since the next call will change HEAD to HEAD~2
git reset --soft HEAD~2 # destroy the last two commits keeping the changes staged.
git commit -C $HH # now commit all changes reusing the commit message from commit2 (using the sha1 that we saved in the variable)
答案 2 :(得分:0)
自从 OP 提出问题以来,请注意交互式 rebase 的行为确实发生了变化(现在已修复,2021 年第一季度)。
当 "git rebase -i
"(man) 处理 fixup insn 时,没有理由清理提交日志消息,但我们做了通常的 stripspace 处理。< br/>
这已在 Git 2.31(2021 年第一季度)中得到纠正。
请参阅 commit f7d42ce 的 Johannes Schindelin (dscho
)(2021 年 1 月 28 日)。
(2021 年 2 月 10 日在 Junio C Hamano -- gitster
-- 被 commit 7e94720 合并)
rebase -i
:在修复中保持提交信息完整无缺!链报告人:Vojtěch Knyttl
帮助:Martin Ågren
签字人:约翰内斯·辛德林
在 6e98de7 ("sequencer (rebase -i): add support for the 'fixup' and 'squash' commands", 2017-01-02, Git v2.12.0-rc0 -- {{3} } 在 merge 中列出),该开发人员错误地引入了行为更改:当遇到 fixup!
提交(或多个 fixup!
提交)而没有抛出任何 squash!
提交时,最后的 batch #8(git commit
) 是用 --cleanup=strip
调用的。
在该提交之前,已调用提交命令而没有该 --cleanup
选项。
由于在这种情况下我们从文件中明确读取原始提交消息,因此强制进行清理确实没有意义。
我们实际上需要主动抑制清理,以免配置的 commit.cleanup
可能会干扰我们想要做的事情:保持提交消息不变。