Open includeios opened 5 years ago
平时合代码时,难免会将一些不需要的代码合到主分支里。 像我就经常遇到合完qa_test后,又和我说这个功能今天上不了了,希望我能把这部分功能从qa_test里踢出去。以前我的做法都是找到那条合代码的commit记录,checkout到之前版本,在新起个分支作为这次上线的qa_test,就怕莫名其妙的删除和回滚导致后面代码合不上去…. 后来弄懂了git reset 和 git revert,才知道自己的做法是多么的傻逼。
平时合代码时,难免会将一些不需要的代码合到主分支里。
像我就经常遇到合完qa_test后,又和我说这个功能今天上不了了,希望我能把这部分功能从qa_test里踢出去。以前我的做法都是找到那条合代码的commit记录,checkout到之前版本,在新起个分支作为这次上线的qa_test,就怕莫名其妙的删除和回滚导致后面代码合不上去….
后来弄懂了git reset 和 git revert,才知道自己的做法是多么的傻逼。
git reset git revert
这两个命令具体有什么区别呢?怎么用他们做回滚呢?
假设我们系统里有下面这些提交记录:
A版本和B版本是我们正常的提交,C版本和D版本是错误提交,现在我们希望回退到B版本。
此时,HEAD指针指向D(5lk4er),我们只要将HEAD指针指向B(a0fvf8),就OK了,于是:
git reset --hard a0fvf8
运行完命令后,本地HEAD指针如期望指向了B,如下图:
然而此时,远程仓库的HEAD指针依旧指向D,这个时候是提交不上去的。所以我们只能强制提交,覆盖掉远程分支的记录:
git push -f
采用这种方法回滚的弊端显而易见:他会强制HEAD指针往回移动,丢弃后面版本的代码,如果后来发现C和D是多么绝妙的想法,他们也丢失在历史的长河了。
revert不一样的是他会反向新创建一个版本,这个版本的内容与我们需要回滚的版本内容一样,HEAD会指向这个新的版本,而不是回退到之前版本。
还是上面那个例子,想要回滚到版本B,我们先需要回滚一下D,再回滚一下C(根据提交的顺序反向回滚):
git revert 5lk4er git revert 76sdeb
这个时候我们会新生成两个对应的分支D'和C',HEAD指向我们最后生成的C'版本,其中的代码和B版本一模一样。如下图:
这里是需要回退两个版本,那如果有好多个版本有没有什么简便的快捷写法呢:
//git revert 最后一个要回滚的版本号^..第一个要回滚的版本号 git revert OLDER_COMMIT^..NEWER_COMMIT
这种回滚,错误C和D依旧有迹可循,也可以在历史的长河里再次拾起这两枚遗珠。而且,这里HEAD是往后移的,push到远程分支直接push就好。
上面那个例子还是比较简单的,现实场景中我们经常遇到下面这种情况:错误提交的版本刚好在中间,希望既保留A又保留C,只把B踢了:
直接revert到A肯定是不够的,我们还需要保留C的代码,常见做法是先回退C,回退B,再通过cherry-pic命令添加C版本的代码:
git revert 76sdeb^..a0fvf8 git cherry pic 76sdeb
最后,感谢这篇文章让我重获新生:https://www.itcodemonkey.com/article/13010.html
感谢,写得很详细
谢谢,太棒了!
git revert 76sdeb^..a0fvf8
这里是不是反了
git revert 76sdeb^..a0fvf8 这里是不是反了
确实写反了 应该把最老的commit放前面
如何优雅的进行版本回退
回滚的常用两个命令
这两个命令具体有什么区别呢?怎么用他们做回滚呢?
git reset
假设我们系统里有下面这些提交记录:
A版本和B版本是我们正常的提交,C版本和D版本是错误提交,现在我们希望回退到B版本。
此时,HEAD指针指向D(5lk4er),我们只要将HEAD指针指向B(a0fvf8),就OK了,于是:
运行完命令后,本地HEAD指针如期望指向了B,如下图:
然而此时,远程仓库的HEAD指针依旧指向D,这个时候是提交不上去的。所以我们只能强制提交,覆盖掉远程分支的记录:
采用这种方法回滚的弊端显而易见:他会强制HEAD指针往回移动,丢弃后面版本的代码,如果后来发现C和D是多么绝妙的想法,他们也丢失在历史的长河了。
git revert
revert不一样的是他会反向新创建一个版本,这个版本的内容与我们需要回滚的版本内容一样,HEAD会指向这个新的版本,而不是回退到之前版本。
还是上面那个例子,想要回滚到版本B,我们先需要回滚一下D,再回滚一下C(根据提交的顺序反向回滚):
这个时候我们会新生成两个对应的分支D'和C',HEAD指向我们最后生成的C'版本,其中的代码和B版本一模一样。如下图:
这里是需要回退两个版本,那如果有好多个版本有没有什么简便的快捷写法呢:
这种回滚,错误C和D依旧有迹可循,也可以在历史的长河里再次拾起这两枚遗珠。而且,这里HEAD是往后移的,push到远程分支直接push就好。
玩个高级点的
上面那个例子还是比较简单的,现实场景中我们经常遇到下面这种情况:错误提交的版本刚好在中间,希望既保留A又保留C,只把B踢了:
直接revert到A肯定是不够的,我们还需要保留C的代码,常见做法是先回退C,回退B,再通过cherry-pic命令添加C版本的代码:
最后,感谢这篇文章让我重获新生:https://www.itcodemonkey.com/article/13010.html