交互式变基:清理你的提交历史

Avatar of Tobias Günther
Tobias Günther

DigitalOcean 为您旅程的每个阶段提供云产品。 立即开始使用 $200 免费信用额度!

本文是我们 “高级 Git” 系列的一部分。 务必 关注 Tower 的 Twitter订阅他们的时事通讯 以了解下一篇文章的信息。

交互式变基是 Git 命令的瑞士军刀:有很多用例和很多可能性! 它确实是任何开发人员工具链中的一款很棒的补充,因为它允许您在与团队其他成员共享工作之前修改本地提交历史记录。

让我们看看您可以使用交互式变基做什么,然后看看一些实际示例。

高级 Git 系列

  1. 第 1 部分: 在 Git 中创建完美的提交
  2. 第 2 部分: Git 中的分支策略
  3. 第 3 部分: 通过拉取请求实现更好的协作
  4. 第 4 部分: 合并冲突
  5. 第 5 部分: 变基与合并
  6. 第 6 部分: 交互式变基 (您就在这里!)
  7. 第 7 部分: 在 Git 中挑选提交
  8. 第 8 部分: 使用 Reflog 恢复丢失的提交

重写您的提交历史记录

简而言之,交互式变基允许您操作您的提交历史记录。 它的目的是优化和清理。 您可以…

  • 更改提交信息
  • 组合多个提交
  • 拆分和编辑现有提交
  • 重新排序提交
  • 删除提交

请记住,交互式变基会重写您的提交历史记录:所有涉及的提交都会获得一个新的哈希 ID。 另外,快速提醒:提交 ID 用于识别提交——它们是 SHA-1 校验和。 因此,通过更改该哈希值,您实际上是在创建全新的提交。 这意味着您不应该对已经推送到共享远程存储库的内容使用交互式变基。 您的同事可能已经基于这些提交完成了他们的工作——当您使用交互式变基重写提交历史记录时,您正在更改这些基础提交。

所有这些意味着交互式变基旨在帮助您在将自己的本地提交历史记录合并(并可能推送)回共享团队分支之前清理和优化它。

交互式变基工作流程

在我们对交互式变基进行测试之前,让我们看一下常规工作流程。 无论我们具体要做什么——删除提交、更改提交信息、组合提交……步骤都是一样的。

第一步是确定要操作的提交范围。 您要追溯到多远的历史记录? 一旦您有了答案,您就可以开始您的交互式变基会话。 在这里,您有机会编辑您的提交历史记录。 例如,您可以通过重新排序、删除、组合它们等来操作所选提交。

在您的第一步中,您始终会查看提交历史记录的当前状态。 您可以使用 git log 命令检查项目的历史记录并显示提交日志。

这是我们将在这篇文章中使用的示例存储库

Showing a Git Tower app screen with the main master branch of a repo selected on the left panel, and a list of existing commits on the right panel.
请注意,我在一些屏幕截图中使用了 Tower Git 桌面 GUI 以便于可视化。

在您检查完列表后,就该开始工作了。 让我们一步一步地进行。 在本文的示例中,我们将执行以下操作

  • 首先,我们更改旧提交的信息。
  • 其次,我们合并两个旧提交。
  • 之后,我们拆分一个提交。
  • 最后,我们删除一个提交。

更改提交信息

在许多情况下,您可能想要更改最近的提交。 请记住,这种情况下有一个捷径,不需要交互式变基

$ git commit --amend

此命令可以修改最近提交的内容和信息,它会打开您的默认文本编辑器。 在这里,您可以进行更改,保存它们并退出编辑器。 这不仅会更新提交信息,而且还会有效地更改提交本身并写入新的提交。

再次提醒,请谨慎,如果您已经将最后一个提交推送到远程存储库,请不要修改它!

对于任何其他提交(比最近的提交旧的任何提交),您必须执行交互式变基。 要以交互方式运行 git rebase,请添加 -i 选项。

第一步是确定基础提交:要更改的提交的父提交。 您可以通过使用提交的哈希 ID 或进行一些计数来实现这一点。 要更改最后三个提交信息(或至少其中一个),您可以像这样定义父提交

$ git rebase -i HEAD~3

一个编辑器窗口会打开,您可以看到您选择的三个提交(“选择”是指提交的范围:从 HEAD 一直到 HEAD~3)。 请注意反向顺序:与 git log 不同,此编辑器在顶部显示最旧的提交(HEAD~3),在底部显示最新的提交。

Animated screenshot showing an open terminal that edits the commit and adds a reword command on another line.

在此窗口中,您不会实际更改提交信息。 您只会告诉 Git 您想执行哪种操作。 Git 为此提供了一系列关键字——在我们的示例中,我们将单词 pick 更改为 reword,这允许我们更改提交信息。 保存并关闭编辑器后,Git 会显示实际的提交信息,您可以更改它。 再次保存并退出,就这样!

组合两个提交

在下一个示例中,我们将组合两个提交——“7b2317cf 更改页面结构”和“6bcf266 优化标记”,使它们成为一个单独的提交。 同样,作为第一步,您需要确定基础提交。 同样,我们必须至少追溯到父提交

$ git rebase -i HEAD~3

编辑器窗口再次打开,但不是 reword,我们输入 squash。 确切地说,我们在第 2 行将 pick 替换为 squash,以将其与第 1 行组合。 这是一个需要牢记的重要细节:squash 关键字将您标记的行与其上方的行组合在一起!

Showing an open terminal with a squash on line 2 and giants words in red pointing to that line saying that squash combines the marked up line with the line above it.

保存更改并关闭窗口后,一个新的编辑器窗口会弹出。 为什么会这样? 通过组合两个提交,我们正在创建……好吧……一个新的提交! 并且这个新的提交需要一个提交信息。 输入信息,保存并关闭窗口……您就成功地将两个提交组合在一起。 功能强大!

最后,一个小“专业提示”献给那些使用 “Tower” Git 桌面 GUI 的人:要执行合并,您只需将提交拖放到彼此之上,直接在提交视图中。 并且如果您想更改提交信息,只需右键单击要更改的提交,然后从上下文菜单中选择“编辑提交信息”。

Animated screenshot showing the process of dragging one commit message on top of another, squashing the message, then editing the commit message.

删除提交

我们的最后一个示例将采用更强大的工具:我们将从我们的提交历史记录中删除一个修订版! 为此,我们将使用 drop 关键字来标记我们要删除的提交

drop 0023cdd Add simple robots.txt
pick 2b504be Change headlines for about and imprint
pick 6bcf266 Optimizes markup structure in index page

这可能是回答您可能已经问了很久的一个问题的最佳时机:如果您在变基操作的中间,并且心想,“哦,不,这可不是一个好主意”,您该怎么办? 没问题——您始终可以中止! 只需输入以下命令,即可返回到启动变基之前存储库的状态

$ git rebase --abort

更改过去

这些只是交互式变基可以做的一些例子。还有很多其他的可能性来控制和修改你的本地提交历史。

如果你想深入了解高级 Git 工具,请随时查看我的(免费!) “高级 Git 工具包”:它是一组关于分支策略、交互式变基、Reflog、子模块等等主题的短视频。

祝您变基和黑客编程愉快—我们将在下一期 “高级 Git” 系列中与您相见!

高级 Git 系列

  1. 第 1 部分: 在 Git 中创建完美的提交
  2. 第 2 部分: Git 中的分支策略
  3. 第 3 部分: 通过拉取请求实现更好的协作
  4. 第 4 部分: 合并冲突
  5. 第 5 部分: 变基与合并
  6. 第 6 部分: 交互式变基 (您就在这里!)
  7. 第 7 部分: 在 Git 中挑选提交
  8. 第 8 部分: 使用 Reflog 恢复丢失的提交