16.1 无需变基合并最近的提交
如果你想要将之前的 x 个提交合并为一个提交,可以使用以下命令:
git reset --soft HEAD~x
git commit
将 x 替换为你希望包含在合并提交中的之前提交的数量。
注意:这将创建一个新的提交,实际上会忘记之前 x 个提交的信息,包括它们的作者、提交消息和日期。你可能希望先复制粘贴一个现有的提交消息。
16.2 合并提交期间的合并
你可以使用 git merge --squash 将一个分支引入的更改合并为一个提交。不会实际创建提交。
git merge --squash <branch>
git commit
这与使用 git reset 大致相同,但在合并具有符号名称的更改时更方便。比较:
git checkout <branch>
git reset --soft $(git merge-base master <branch>)
git commit
16.3 变基期间合并提交
在 git rebase 过程中可以合并提交。建议你在尝试以这种方式合并提交之前先了解变基。
- 确定你想要从哪个提交开始变基,并记下其提交哈希值。
- 运行以下命令:
git rebase -i [commit hash]
或者,你也可以使用 HEAD~4 而不是提交哈希值,以查看最新提交以及它之前的 4 个提交。
- 在运行此命令时打开的编辑器中,确定你想要合并的提交。将这些行开头的
pick替换为squash,以将它们合并到之前的提交中。 - 在选择要合并的提交后,系统将提示你编写提交消息。
示例
假设你有以下提交历史:
> git log --oneline
> 612f2f7 This commit should not be squashed
> d84b05d This commit should be squashed
> ac60234 Yet another commit
> 36d15de Rebase from here
> 17692d1 Did some more stuff
> e647334 Another Commit
> 2e30df6 Initial commit
运行以下命令:
> git rebase -i 36d15de
此时,你的首选编辑器会弹出,让你描述你想要对提交执行的操作。Git 在注释中提供了帮助。如果你保持原样,则不会发生任何变化,因为每个提交都将被保留,且顺序与变基之前相同。在本示例中,我们应用以下命令:
pick ac60234 Yet another commit
squash d84b05d This commit should be squashed
pick 612f2f7 This commit should not be squashed
注意:pick 表示使用提交;squash 表示使用提交,但将其合并到之前的提交中。
提交消息编写完成后,运行 git log --oneline 查看结果:
> git log --oneline
> 77393eb This commit should not be squashed
> e090a8c Yet another commit
> 36d15de Rebase from here
> 17692d1 Did some more stuff
> e647334 Another Commit
> 2e30df6 Initial commit
16.4 自动合并和修复
在提交更改时,可以指定将来将提交合并到另一个提交中,如下所示:
git commit --squash=[commit hash of commit to which this commit will be squashed to]
你也可以使用 --fixup=[commit hash] 作为替代方案。
还可以使用提交消息中的词语而不是提交哈希值,如下所示:
git commit --squash :/things
其中,最近一个包含单词“things”的提交将被使用。这些提交的消息将以“fixup!”或“squash!”开头,后跟将要合并到的提交的消息。
在变基时,应使用 --autosquash 标志以使用自动合并/修复功能。
16.5 自动合并:在变基期间提交你想要合并的代码
给定以下提交历史,假设你进行了一个更改,你想要将其合并到提交 bbb2222 中:
$ git log --oneline --decorate
ccc3333 (HEAD -> master) A third commit
bbb2222 A second commit
aaa1111 A first commit
9999999 Initial commit
一旦你进行了更改,可以像往常一样将它们添加到索引中,然后使用 --fixup 参数提交它们,并引用你想要合并到的目标提交:
$ git add .
$ git commit --fixup bbb2222
这将创建一个新的提交,其提交消息 Git 在交互式变基期间可以识别:
$ git log --oneline --decorate
ddd4444 (HEAD -> master) fixup! A second commit
ccc3333 A third commit
bbb2222 A second commit
aaa1111 A first commit
9999999 Initial commit
接下来,使用 --autosquash 参数进行交互式变基:
$ git rebase --autosquash --interactive HEAD~4
Git 将会提示你将使用 --fixup 创建的提交合并到正确的位置:
pick aaa1111 A first commit
pick bbb2222 A second commit
fixup ddd4444 fixup! A second commit
pick ccc3333 A third commit
为了避免在每次变基时都输入 --autosquash,你可以通过以下命令默认启用此选项:
bash $ git config --global rebase.autosquash true