Git revert 撤销历史提交
git revert命令可以被认为是“撤消”命令。但是它不是传统的撤消操作。不是从项目历史中删除提交,而是计算出如何反转要撤销的提交所引入的更改,并附加一个新的提交及生成的反向内容。这种方式可以防止 Git 丢失历史记录,这对于我们的修订历史记录的完整性和可靠的协作非常重要。
当想要应用项目历史中提交的逆向时,应该使用 revert。如果我们正在跟踪错误并发现它是由单个提交引入的。此时我们无需手动进入、修复并提交新快照,而是可以使用git revert自动为我们完成所有这些工作。
git revert 运作原理
git revert
命令用于撤消对仓库提交历史的更改。其他“撤消”命令,例如 git checkout 和 git reset,将HEAD和分支引用指针移动到指定的提交。git revert也需要一个指定的提交,但是,它并不会将 ref 指针移动到这个提交。revert 操作将采用反转指定的提交的更改,并创建一个新的“还原提交”。然后更新 ref 指针以指向新的还原提交,使其成为分支的HEAD。
为了方便,我们使用下面的示例创建一个仓库用来做演示:
$ mkdir git_revert_test
$ cd git_revert_test/
$ git init .
Initialized empty Git repository in /git_revert_test/.git/
$ touch demo_file
$ git add demo_file
$ git commit -am"initial commit"
[main (root-commit) 299b15f] initial commit
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 demo_file
$ echo "initial content" >> demo_file
$ git commit -am"add new content to demo file"
[master 1efa82b] add new content to demo file
n 1 file changed, 1 insertion(+)
$ echo "prepended line content" >> demo_file
$ git commit -am"prepend content to demo file"
[master 7eed538] prepend content to demo file
1 file changed, 1 insertion(+)
$ git log --oneline
在这里,我们在新创建的名为 git_revert_test 的目录中初始化了一个仓库。我们已经对仓库进行了 3 次提交,我们在其中添加了一个文件demo_file 并对其内容修改了两次。在 repo 设置过程结束时,我们调用 git log来显示提交历史记录,显示总共进行了 3 次提交。接下来我们准备进行一次 git revert
$ git revert HEAD
git revert 期望后面跟一个提交的引用,如果后面没有的话,则该命令不会执行。这里我们传入了HEAD
引用。这里将恢复最新的提交。与合并类似,revert 将创建一个新的提交,并且会打开配置的系统编辑器,提示输入新的提交消息。一旦输入并保存了提交消息,Git 将开始进行恢复操作。我们现在可以检查仓库的状态,调用git log命令,可以看到有一个新的提交添加到日志中:
$ git log --oneline
注意
:还原后第三次提交仍在项目历史记录中。git revert 只是添加了一个新的提交来撤消其更改。并不是要删除它。
第 2 次和第 4 次提交是完全相同的代码库。而第 3 次提交仍在我们的历史记录中,以防我们以后万一想回该次提交。
常用选项
-e
--edit
这是默认选项,不需要指定。此选项将打开配置的系统编辑器并提示你在提交还原之前编辑提交消息
--no-edit
该选项和 -e
选项的作用相反。还原提交时不会打开编辑器。
-n
--no-commit
该选项将阻止git revert创建与目标提交相反的新提交。此选项不会创建新的提交,而是将反向更改添加到暂存索引和工作目录。这些是 Git 用来管理仓库状态的其他树。
重置与恢复
重要的是要了解 git revert 撤消单个提交 - 它不会通过删除所有后续提交来“恢复”到项目的先前状态。在 Git 中,这实际上称为重置
,而不是还原。
与 reset 相比,revert有两个重要的优势。首先,它不会改变项目历史,这使得它对于已经发布到共享仓库的提交来说是一个“安全”的操作。
其次,git revert能够在历史上的任意点定位单个提交,而git reset只能从当前提交向后工作。例如,如果您想使用 git reset 命令撤消旧的提交,则必须删除在目标提交之后发生的所有提交,然后重新提交所有后续提交。很明显这不是一个优雅的撤销的解决方案。
总结
总的来说 git revert 命令是一种向前移动的撤消操作,提供了一种更安全的撤消更改的方法。不是删除或孤立提交历史中的提交,还原将创建一个与指定更改相反的新提交。Git revert是比git reset更安全的选择。为了演示 git revert 的效果,我们利用了其他的命令:git log,git commit 和 git reset。