如何优雅的进行版本回退

在版本迭代开发过程当中,相信不少人都会有过错误提交的时候(至少良许有过几回这样的体验)。这种状况下,菜鸟程序员可能就会虎驱一震,紧张得不知所措。而资深程序员就会微微一笑,摸一摸锃亮的脑门,而后默默的进行版本回退。git

对于版本的回退,咱们常常会用到两个命令:程序员

  1. git reset
  2. git revert

那这两个命令有何区别呢?先不急,咱们后文详细介绍。3d

git reset

假如咱们的系统如今有以下几个提交:指针

其中:A 和 B 是正常提交,而 C 和 D 是错误提交。如今,咱们想把 C 和 D 回退掉。而此时,HEAD 指针指向 D 提交(5lk4er)。咱们只需将 HEAD 指针移动到 B 提交(a0fvf8),就能够达到目的。code

只要有 git 基础的朋友,必定会想到 git reset 命令。完整命令以下:blog

git reset --hard a0fvf8

命令运行以后,HEAD 指针就会移动到 B 提交下,以下图示:开发

而这个时候,远程仓库的 HEAD 指针依然不变,仍在 D 提交上。因此,若是直接使用 git push 命令的话,将没法将更改推到远程仓库。此时,只能使用 -f 选项将提交强制推到远程仓库:it

git push -f

采用这种方式回退代码的弊端显而易见,那就是会使 HEAD 指针往回移动,从而会失去以后的提交信息。未来若是忽然发现,C 和 D 是多么绝妙的想法,可它们已经早就消失在历史的长河里了。效率

并且,有些公司(好比良许的公司)明令禁止使用 git reset 命令去回退代码,缘由与上述同样。因此,咱们须要找到一个命令,既能够回退代码,又能够保存错误的提交。这时,git revert 命令就派上用场了。基础

git revert

git revert的做用经过反作建立一个新的版本,这个版本的内容与咱们要回退到的目标版本同样,可是HEAD指针是指向这个新生成的版本,而不是目标版本。

使用 git revert 命令来实现上述例子的话,咱们能够这样作:先 revert D,再 revert C (有多个提交须要回退的话须要由新到旧进行 revert):

git revert 5lk4er
git revert 76sdeb

这里会生成两个新有提交:D' 和 C',以下图示:

这里只有两个提交须要 revert,咱们能够一个个回退。但若是有几十个呢?一个个回退确定效率过低并且容易出错。咱们可使用如下方法进行批量回退:

git revert OLDER_COMMIT^..NEWER_COMMIT

这时,错误的提交 C 和 D 依然保留,未来进行甩锅的时候也有依可循。并且,这样操做的话 HEAD 指针是日后移动的,能够直接使用 git push 命令推送到远程仓库里。而这种作法,正是企业所鼓励的。

咱们再举个更难一点的例子。

假如如今有三个提交,但很不巧的是,那个错误的提交恰好位于中间。以下图示:

这时,直接使用 git reset 命令将 HEAD 指针重置到 A 提交显然是不行的,由于 C 提交是正确的,须要保留的。先把 C 提交 及 B 批次所有回退,再使用 cherry-pick 命令将 C 提交从新再生成一个新的提交 C'',这样就实现了将 B提交回退的需求。完整的过程以下:


公众号:良许Linux

有收获?但愿老铁们来个三连击,给更多的人看到这篇文章