3

假设我有一些提交:

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

4

3 回答 3

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使用任何参数时,它将使用上次提交的提交消息提交更改。您需要做的就是在查看提交消息后退出编辑器。最后的樱桃选择应用最后一次提交,不变。

于 2016-01-06T11:47:22.430 回答
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)
于 2018-04-12T14:41:14.470 回答
0

由于 OP 的问题,请注意交互式 rebase 的行为确实发生了变化(现在已修复,2021 年第一季度)。

当 " git rebase -i" ( man )处理 fixup insn 时,没有理由清理提交日志消息,但我们进行了通常的 stripspace 处理。
这已在 Git 2.31(2021 年第一季度)中得到纠正。

请参阅Johannes Schindelin ( ) 的提交 f7d42ce(2021 年 1 月 28 日(由Junio C Hamano 合并 -- --提交 7e94720中,2021 年 2 月 10 日)dscho
gitster

rebase -i:请务必在修复中保持提交消息完整!链条

报告人:Vojtěch Knyttl
帮助人:Martin Ågren
签字人:Johannes Schindelin

6e98de7(“sequencer (rebase -i): add support for the 'fixup' and 'squash' commands”, 2017-01-02, Git v2.12.0-rc0 -- merge列在第 #8 批中)中,这个开发者介绍了错误的行为改变:当遇到一个fixup!提交(或多个fixup!提交)而没有任何squash!提交时,最终man被调用. 在该提交之前,已在没有该选项的情况下调用了提交命令。git commit--cleanup=strip
--cleanup

由于在这种情况下我们明确地从文件中读取了原始提交消息,因此强制进行清理确实没有任何意义。

我们实际上需要主动抑制清理,以免配置commit.cleanup可能干扰我们想要做的事情:保持提交消息不变。

于 2021-02-14T04:49:04.717 回答