Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

如何优雅的进行版本回退 #12

Open
includeios opened this issue Sep 17, 2019 · 4 comments
Open

如何优雅的进行版本回退 #12

includeios opened this issue Sep 17, 2019 · 4 comments
Labels

Comments

@includeios
Copy link
Owner

includeios commented Sep 17, 2019

如何优雅的进行版本回退

平时合代码时,难免会将一些不需要的代码合到主分支里。

像我就经常遇到合完qa_test后,又和我说这个功能今天上不了了,希望我能把这部分功能从qa_test里踢出去。以前我的做法都是找到那条合代码的commit记录,checkout到之前版本,在新起个分支作为这次上线的qa_test,就怕莫名其妙的删除和回滚导致后面代码合不上去….

后来弄懂了git reset 和 git revert,才知道自己的做法是多么的傻逼。

回滚的常用两个命令

git reset
git revert

这两个命令具体有什么区别呢?怎么用他们做回滚呢?

git reset

假设我们系统里有下面这些提交记录:
image

A版本和B版本是我们正常的提交,C版本和D版本是错误提交,现在我们希望回退到B版本。

此时,HEAD指针指向D(5lk4er),我们只要将HEAD指针指向B(a0fvf8),就OK了,于是:

git reset --hard a0fvf8

运行完命令后,本地HEAD指针如期望指向了B,如下图:
image

然而此时,远程仓库的HEAD指针依旧指向D,这个时候是提交不上去的。所以我们只能强制提交,覆盖掉远程分支的记录:

git push -f

采用这种方法回滚的弊端显而易见:他会强制HEAD指针往回移动,丢弃后面版本的代码,如果后来发现C和D是多么绝妙的想法,他们也丢失在历史的长河了。

git revert

revert不一样的是他会反向新创建一个版本,这个版本的内容与我们需要回滚的版本内容一样,HEAD会指向这个新的版本,而不是回退到之前版本。

还是上面那个例子,想要回滚到版本B,我们先需要回滚一下D,再回滚一下C(根据提交的顺序反向回滚):

git revert 5lk4er
git revert 76sdeb

这个时候我们会新生成两个对应的分支D'和C',HEAD指向我们最后生成的C'版本,其中的代码和B版本一模一样。如下图:
image

这里是需要回退两个版本,那如果有好多个版本有没有什么简便的快捷写法呢:

//git revert 最后一个要回滚的版本号^..第一个要回滚的版本号
git revert OLDER_COMMIT^..NEWER_COMMIT

这种回滚,错误C和D依旧有迹可循,也可以在历史的长河里再次拾起这两枚遗珠。而且,这里HEAD是往后移的,push到远程分支直接push就好。

玩个高级点的

上面那个例子还是比较简单的,现实场景中我们经常遇到下面这种情况:错误提交的版本刚好在中间,希望既保留A又保留C,只把B踢了:
image

直接revert到A肯定是不够的,我们还需要保留C的代码,常见做法是先回退C,回退B,再通过cherry-pic命令添加C版本的代码:

git revert 76sdeb^..a0fvf8
git cherry pic 76sdeb

image

最后,感谢这篇文章让我重获新生:https://www.itcodemonkey.com/article/13010.html

@includeios includeios added the git label Sep 17, 2019
@dogelin
Copy link

dogelin commented Nov 18, 2020

感谢,写得很详细

@Seayon
Copy link

Seayon commented Nov 23, 2020

谢谢,太棒了!

@zhang156
Copy link

git revert 76sdeb^..a0fvf8

这里是不是反了

@LIUXUCHONG
Copy link

git revert 76sdeb^..a0fvf8

这里是不是反了

确实写反了 应该把最老的commit放前面

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants