Git是一个强大分布式增量版本控件工具,具有非常强大的功能。功能强大同时也意味着使用时有一定的复杂性。本文就以恢复错误为例,就有三条可用的命令:reset, checkout 和 revert。下面就让我们来看看它们有什么不同。
简述
在《【Git实战记录】撤销已经提交至远程的一次变更》一文中,对其比较如下:
相同点:都是用于恢复数据
不同点:
- reset 用于将本地数据从当前版本V1恢复至某个版本V0,同时将V0之后的所有提交全部丢弃
- checkout 仅仅删除当前所有变化,恢复至最后一次同步时的状态
- revert 将某次提交时的变化恢复至本地,作为一次新的变更。
但是,这些描述并不具体,下面我们以实例来看看。
checkout:可以理解为clear,即清除当前所有修改
在这三条命令中,checkout
是最轻量级的恢复。它的作用是在所有数据都是已经同步的状态下,如果对本地文件 a 进行了修改后发现此修改是多余的,且还未对 a 执行 commit
操作,那么就可以使用 checkout
将 a 恢复至原先同时时的状态。在命令执行后,a 的多余的修改不会有任何的记录。一般用于恢复一些仅在本地保存的误操作。
reset:删除本地仓库的提交
如果在以上的修改后,已经对 a 执行了 commit
操作,即已经将对 a 的修改提交至本地库,那么这时候 reset
就是我们的后悔药。设本地仓库有3个历史版本,顺序为:
然后在提交了错误的修改,这时本地仓库历史版本变为:
其中,最新的 为错误的版本。
这时候,我们如果执行 reset
命令,并且指定回到
版本,那么
就会被删除,不会留下任何痕迹,本地仓库历史版本状态会回到初始的三个版本,即
。
注意:已 push
到远程仓库的不允许 reset
。这是因为在提交至远程仓库后,就意味着此版本别人可能已经在使用了,如果仍然允许 reset
,就可能会引发其他人员提交版本的丢失,从而导致灾难性的后果。
revert:用某个历史版本作为最新的提交
虽然 reset
能够撤销错误的版本,但是这种做法很多时候并不推荐,因为这样的做法把错误的版本丢弃了,造成了信息的丢失并不适合Git精神,即记录版本控制过程中的所有变化情况。所以,这里推荐使用 revert
命令。它的作用是,在保留错误版本的前提下,恢复到指定的版本。
同样让我们以上面的三个版本,即
为例。在提交了错误的版本后,变为
。此时,我们执行 revert
恢复至
版本,那么版本历史会变成:
此时,我们会发现历史版本变成了5个,多了一个
,这个版本的内容与
完成一致,但是是作为一个全新的提交而存在。这样即达到了恢复到
版本的目的,同时又保存了错误版本
,从而保证了信息的完全性。当然,这样做肯定会占用更多的磁盘空间,但是我们通常认为信息本身比磁盘更重要,所以推荐使用 revert
命令保留错误的提交。
如果对 revert
和 revert
命令还不理解,可以看一下官方给的一个图例,能够非常好地说明问题(上面是revert,下面是 reset):