概述
继 Git的反悔操作(一),接下来讲讲git
中的重写历史。
文章大部分翻译于 Undoing Changes 和 Rewriting history,并结合了自己的一些理解和补充。
Git
的主要工作是确保你不会丢失一次已提交的改动,但它也被设计为你对开发工作流具有完全的控制,包括让你确切地定义项目历史看起来的样子,但这创造了丢失提交的潜力。Git
提供了一些重写历史的命令,使用它们可能导致丢失内容。
这篇文章讨论了一些最常见的重写已提交快照的原因,展示了如何避免陷入这样做的陷阱。
重写历史(Rewriting history)
git commit –amend
git commit --amend
是修复最近的提交很方便的一种方式,它让你把已暂存的改动和上一次的提交合并在一起,而不是完整地提交一个新的快照,也可以仅仅编辑上一次提交的备注而不用改变它的快照。
amend
并不仅仅改变最近的提交,而是完全地代替它。对Git
而言,它看起来像是一个全新的提交(可视化为上图的星号),在处理公有仓库时牢记这一点很重要。
用法
git commit --amend
合并暂存区的改动和上一次提交,并用最终的快照代替上一次提交。运行这行命令时,如果没有任何东西被添加至暂存区,则只会让你编辑上一次提交的备注,不会改变快照。
在开发过程中,过早地提交一直会发生,很容易就会忘记暂存一个文件或写错了commit的注释,--amend
可以很方便地修复这个小错误。
不要amend
公有的提交
在git reset部分,我们已经讨论了为什么你不应该重置那些与其他开发者共享的提交,amend
也一样,不要修改已经推送到公有仓库的提交。
amend
提交实际上是一个全新的提交,上一个提交会从项目历史中移除,这和reset
一个公有的快照是一样的结果。如果你amend
那些其他开发者在那基础上工作的commits,就像他们以此为基础的工作从项目历史中被销毁一样,这会让开发者们陷入迷惑的境地,并很难恢复原样。
示例
接下来的例子展示了开发中一个普通的场景。我们编辑了一些文件,希望在一个单一的快照提交它们,但却忘记添加其中一个文件至暂存区。修复这个错误只是一个简单的事,把其他文件加入暂存区,然后使用--amend
提交即可。
# Edit hello.py and main.py
git add hello.py
git commit
# Realize you forgot to add the changes from main.py
git add main.py
git commit --amend --no-edit
编辑器将从上一个提交中自动填充注释,使用--no-edit
则你不需要改变提交的注释。如有必要,你也可以修改注释(不使用--no-edit
)。这个最终的提交将会取代不完整的那一个提交,它看起来就像我们只在一个单一的快照中提交了hello.py
和main.py
的改动。