git rebase squash接第二条消息(如fixup)

时间:2016-01-06 11:15:40

标签: git git-rebase git-rewrite-history git-squash

假设我有一些提交:

<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之后可能会有许多提交。

3 个答案:

答案 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 f7d42ceJohannes 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 可能会干扰我们想要做的事情:保持提交消息不变。