Git 版本回退(实际工作中基本都会遇到)

1,441 阅读3分钟

「这是我参与11月更文挑战的第7天,活动详情查看:2021最后一次更文挑战」。

在日常工作中,我们可能会和多个同事在同一个分支进行开发,有时候我们可能会出现一些错误提交,这些错误提交如果想撤销,可以有两种解决办法:回退( reset )、反做(revert)

回退 (reset)

git reset 操作就是修改 HEAD 指向的位置,将 HEAD 当前指向的位置回退到指定的某个版本,例如针对某个分支我们提交了三次:

image-20211107205122157

如图所示,这是 reset 之前的三个 commit 记录,目前 HEAD 指向的是 commit 3的位置,如果我们想把代码回退到 commit 1的位置,怎么操作呢?

% git reset --hard  'commit 1 的提交id'

image-20211107205418616

操作完之后 commit 2和 commit 3 的提交记录就没有了,直接回退到了commit 1。

我们实战演练下: image-20211107205910044

image-20211107210059198

通过 git log 可以看到, 我总共提交了三次,目前第三次提交就是当前HEAD指向的节点

现在我要回退到第一次提交的节点

使用“ git reset --hard 目标版本号 ” 命令将版本回退

% git reset --hard e15faaf4                                
HEAD is now at e15faaf test1

image-20211107210448548

可以看到我们直接回退到了第一次提交的时候,第二次和第三次提交记录就消失了。

我们再看下日志

image-20211107210626425

反做 git revert

什么是反做?

git revert是用于“反做”某一个版本,以达到撤销该版本的修改的目的。比如,我们commit了三个版本(版本一、版本二、 版本三),突然发现版本二不行(如:有bug),想要撤销版本二,但又不想影响撤销版本三的提交,就可以用 git revert 命令来反做版本二,生成新的版本四,这个版本四里会保留版本三的东西,但撤销了版本二的东西。如下图所示:

反做前:

image-20211107210951735

反做后:

image-20211107211039545

实际操作:

还是按照我们上面的例子,我们目前提交了三次,我们要把 commit 2 进行反做,也就是说保留 commit1 和commit3 的内容,去除 commit2 的内容

image-20211107211226846

使用“git revert -n 版本号”反做,并使用“git commit -m 版本名”提交:

这里反做 test2 可能会出现冲突,我们需要自己解决冲突后进行commit

% git revert -n 30df3872497b1c56814adf53c1022dc1342e1c93
% git commit -m 'test4'

image-20211107212800088

如何找回因回退或反做而消失的commit记录

上述两种操作会造成有些 commit 记录消失,但是如果自己又后悔了,想找回来,我们该怎么操作呢

git reflog

可以查看所有分支的所有操作记录(包括已经被删除的 commit 记录和 reset 的操作)

 java % git reflog
faa135e (HEAD -> master) HEAD@{0}: commit: test3
783ef0a HEAD@{1}: commit: test2
2288ba8 HEAD@{2}: commit: test1
abddace HEAD@{3}: commit: test3
30df387 HEAD@{4}: commit: test3

从这里我们可以找到之前所有的 commit 记录,然后找到你需要恢复到 commit id 进行恢复即可。

关于 git reset 还有一个命令我这里也给大家说一下:

% git reset --soft 'commit id'

git reset –-soft:回退到某个版本,只回退了 commit 的信息,但是内容不会消失,工作区的文件内容都还在。如果还要提交,直接 commit 即可。

这种操作的友好性就是如果我们本身只是想把commit的操作给回退,但是不想还原内容,保持所有内容都还在,这种操作就很合适,保证了代码不会丢失。

总结

本文我们主要说了 reset 和 revert 操作,这两种操作的本质区别如果用一句话总结就是,git reset --hard 撤销到某次提交 git revert 撤销某次提交,在实际工作中,这两种操作我们都要谨慎使用,以免因为误操作造成代码丢失。