使用 Git Rebase 轻松合并、修改、修订和排序提交
最近(其实也不算最近),我写了一篇文章解释经常被误解的git命令:git rebase。
在那里,我试图确保任何人都能理解其目的和基本应用git rebase。
在本文中,我将解释 rebase 的一个更复杂的应用git rebase。选择这种方式进行 rebase 可以让我清晰地传达提交背后的目的和原因。
我指的是git rebase在可选的交互模式下使用 Git。这是我组织代码变更的首选方法;良好的组织能让 Git 成为更强大的工具。
如果您还不熟悉 rebase,建议您在阅读本文之前先阅读上一篇文章。本文将简要介绍该命令的更多强大应用。
运行此操作git rebase -i会在交互模式下触发变基操作。
为什么叫交互模式?问得好。交互模式允许程序员影响变基的执行方式。在上一篇文章中,我们使用变基将上游的更改合并到我们的分支中,但在此过程中我们没有修改任何提交。
在很多方面,我们之前遵循的流程是理想的;我们不需要做任何工作,git 为我们处理了一切!
遗憾的是,现实世界很少是理想的。
在使用 Git 时,我们经常会提交不完整的更改,忘记包含重要的更改,或者编写糟糕的提交信息。
在我们的场景中,我们可以想象有一个名为 `<branch_name>` 的分支some-feature,其结构大致如下:
47a0a7008b Add a rea322ally cool feature
6dbc838bae WIP forgot something from that feature
f2ee0378f9 WIP fixing a bug
f0978af68d Fixed the very annoying bug
61b6f8ea3e Fix a typo from my doc changes
8340051649 Update documentation
f8a81956e2 Fix documentation formatting
这段 Git 历史记录有几点我们可能不太满意。例如,有几个正在进行中的提交(WIP,即工作进行中)可以删除,其中一个提交里有拼写错误,还有一个提交修复了之前在这个分支上引入的拼写错误。
我们计划将此分支合并到另一个名为 的分支中master。
为了修复此分支中令人讨厌的 git 错误,我们可以使用git rebase -i master.
当你运行git rebase -i另一个分支时,会打开一个文本编辑器,并显示以下提示:
pick 47a0a7008b Add a rea322ally cool feature
pick 6dbc838bae WIP forgot something from that feature
pick f2ee0378f9 WIP fixing a bug
pick f0978af68d Fixed the very annoying bug
pick 61b6f8ea3e Fix a typo from my doc changes
pick 8340051649 Update documentation
pick f8a81956e2 Fix documentation formatting
# Rebase a6305fd0a..4a5782397 onto a6305fd0a (1 command)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup <commit> = like "squash", but discard this commit's log message
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# . create a merge commit using the original merge commit's
# . message (or the oneline, if no original merge commit was
# . specified). Use -c <commit> to reword the commit message.
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out
提示非常有帮助,但有时像这样一大段文字可能会让人望而却步。
在此视图中,git 会显示当前分支中存在但不在主分支中的提交列表master。这些提交将被重放(或添加到主分支的历史记录之上)master。每个提交旁边都有一个“命令”。
例如,显示提交的pick 47a0a7008b Add a rea322ally cool feature命令及其提交信息。pick47a0a7008b
每个命令都有其独特之处,您可以阅读提示符中列出的命令(如果您愿意的话),但我最常用的命令是:squash,,reword和fixup。
要继续进行变基操作,您应该将pick命令替换为您首选的命令,然后保存并关闭文件。
我会这样修改我们的示例历史记录:
reword 47a0a7008b Add a rea322ally cool feature
fixup 6dbc838bae WIP forgot something from that feature
pick f2ee0378f9 WIP fixing a bug
squash f0978af68d Fixed the very annoying bug
pick 8340051649 Update documentation
fixup 61b6f8ea3e Fix a typo from my doc changes
squash f8a81956e2 Fix documentation formatting
发生了一些事。
首先,我将文档相关的提交合并在一起。这样可以更方便地合并更改和跟踪 Git 历史记录。
其次,我选择删除squash一些fixup正在进行中的提交,或者删除一些修复我在该分支上工作时可能创建的问题的提交(小的拼写错误、格式错误、正在进行中的提交)。
最后,我决定重写第一条提交信息,因为它包含一个拼写错误。
保存并关闭此文件后,git 就会开始工作。每次提交被合并或修改时,我都有机会编写新的提交信息。
例如,当我提交第一个版本时,我可以将其修改为“添加一个非常酷的功能”。当我提交到 squash 合并后的版本时,我可以选择合并两个版本的信息,或者完全重写。使用 squash 合并的提交与fixup使用 squash 合并的提交的处理方式完全相同,squash只是提交信息会被完全丢弃。
假设没有合并冲突,变基完成后,git 历史记录可能如下所示:
47a0a7008b Add a really cool feature
f2ee0378f9 Fix a bug
8340051649 Update documentation
这些提交记录更容易理解,应该能让 PR 更简洁。
还有更多……
最近我写了很多文章,还运营了一个播客,并且开始发送新闻简报,汇总我听到的所有精彩故事。
你也可以在Twitter上关注我,我在那里制作搞笑表情包,并谈论作为一名开发者的经历。
文章来源:https://dev.to/jacobherrington/easily-squash-reword-amend-and-sort-commits-with-git-rebase-1pe7