0%

Git 系列(二)如何 squash 你的提交

引言

squash 选项通常在分支合并时,将多个 commits 记录合并成一个的操作。squash 并非一个 git 命令,而是 rebase 或者 merge 的一个选项。

何时需要 Squash

正如引言所说,squash 只是用来合并多个提交记录。至于是否需要这样做,从某种程度上来说,这只是一个偏好问题。对于有些团队来说,像 master 或者 main 这样的长期运行的分支,squash 可能是最好的方式。
但是为什么我们需要它呢? 让我们用一个比较典型的功能分支为例进行说明:在这个 feature 分支中,我们可能产生多次提交记录,当功能越复杂时,记录可能会越多。当你打算合并该分支到主分支时,我们可以根据以下几点来决定是否需要进行 squash:

  • 如果在 merge 之前进行 squash,那么该分支之前的所有提交记录都会变成单一 commit。那么主分支上就只是显示单条 commit 信息。
  • 如果不 squash 的话,那么该分支上的所有 commit 都会保留到合并的主分支上。

有些团队觉得个人提交的记录并非必要,那么保留主分支提交记录的干净性 squash 就变得很有用了。

然而两种方案各有利弊,是否进行 squash 变成为了一个偏好问题。这里并不会有一个最佳答案。

如何 Squash

有不同的方式跟工具帮你 squash 你的提交信息。本文,我们只讨论 交互式的 rebase 跟 merge 这两种命令作为 squash 的主要方法。

交互式的 rebase

在任何使用交互式的 rebase 时,都可以手动 squash 你的提交记录。本文不会进行更深入的讲解 rebase,只是通过一个简单的例子进行说明:

如下图所示,我们在 feature/login 分支上完成了开发的全部任务,我们打算把它合并到 main 分支。在合并之前,我们可以清理并压缩它们:

我们执行以下命令:

1
$ git rebase -i HEAD~3

此时会打开编辑窗口,你可以选择并操作你的提交历史。交互式的 rebase 允许你在你的提交历史上执行多种不同的操作,比如我们要做的 squash。只要记录被标记为 squash,那么它们都会被合并:

最后,为 squash 之后生成的新提交编写提交信息。整个操作就完成了,三个老的提交记录就已经被合并了。

Merge

当进行分支合并的时候,也可以进行 squash:

1
2
3
4
5
6
7
$ git merge --squash feature/login

Auto-merging imprint.html
Removing img/iconBlog.png
Auto-merging about.html
Squash commit -- not updating HEAD
Automatic merge went well; stopped before committing as requested

跟 rebase 的 squash 很类似,所有的变更都会合并为一个常规的 merge。变更的记录存在本地仓库中,需要进行手动的提交。

最后,使用 squash 可以避免因合并而自动创建提交记录。使它看上去更像是只产生了一个单一提交。

Pull Requests

当合并时进行 squash 通常用于在 Pull Request 关闭的时候。像 GitHub、GitLab 或者 Bitbucket 这些代码管理平台都支持当合并一个 Pull Request 时 squash。


原文