git版本回退
版本回滚(撤销提交)
当讨论 revert 时,需要分两种情况,因为 commit 分为两种: 一种是常规的 commit,也就是使用 git commit 提交的 commit; 另一种是 merge commit,在使用 git merge 合并两个分支之后,你将会得到一个新的 merge commit
merge commit 和普通 commit 的不同之处在于 merge commit 包含两个 parent commit, 代表该 merge commit 是从哪两个 commit 合并过来的。
使用 git show commitID 可以查看 commit 的详细信息,一般在git log 命令中就可也看得到下面的信息
commit 8d9161a6858070f9271ec119b16e5463c25a6429 (HEAD -> test3)
Merge: e234da1 5849fe4
Author: liuhao
Date: Wed Jan 16 20:22:47 2019 +0800
Merge branch 'test1' into test3
上面这代表该 merge commit 是从 5849fe4 和 e234da1 两个 commit 合并过来的。 而Merge: e234da1 5849fe4 代表是从5849fe4合并到e234da1的 e234da1 为当前分支,而5849fe4为合并过来的分支 就是,在e234da1分支上做的git merge 5849fe4 做revert的时候前面的e234da1就是parent 1,而后面的5849fe4就是parent 2 git revert XXX -m 1 就是保留parent 1,也就是e234da1
而常规的 commit 则没有 Merge 行
➜ git show 3e853bd
commit 3e853bdcb2d8ce45be87d4f902c0ff6ad00f240a
操作
git reset --hard Head 重置所有操作到该Head
git reset --soft Head 仅仅把HEAD指向该次commit, 所有操作全部保留
git revert Head 生成一个新的提交用以撤销前一次 commit
git revert HEAD^ 生成一个新的提交用以撤销前前一次 commit
撤销某次操作(通过新的提交来撤销某一个commit中的操作)
git revert commitId(普通操作,不能用来撤销一个merge) 通过一个新的commit来进行一次撤销指定commitId的操作.
git revert 一个Merge commit,会报错:is a merge but no -m option was given
这是因为revert的那个commit是一个merge commit,
它有两个parent, Git不知道base是选哪个parent,就没法diff,所以就抱怨了,
所以要显示告诉Git用哪一个parent。
比如:git revert commitID -m 1 这样就选parent 1,
那么parent 1又是哪一个呢?
通过git log 可以看到每次merge的parent
一般来说,
如果你在master上merge的testBranch,那么parent 1就是master,parent 2就是testBranch.
可以git log 或者git show commitID来看下详细信息找到他的 Merge: e234da1 5849fe4 这一栏.
前面的e234da1就是parent 1,而后面的5849fe4就是parent 2
git revert 8d9161a6858070f9271ec119b16e5463c25a6429 -m 1 即保留parent 1,也就是e234da1
如果不清楚parent 1和parent 2里改了什么可以通过分别git show 他的Merge: e234da1 5849fe4 即可.
revert注释:
revert过程有可能遇到冲突,要么git revert --abort终止此次revert操作,
代码还原至revert命令前。要么手动消除冲突(同普通的冲突解决),然后add commit;
reset 是直接将版本撤回到指定的位置,revert 是通过再次提交一个版本来取消某一次的提交,仅仅是某一次.
如果在revert到某个commit的时候而该commit是一个merge commit的时候,可以git log 或者git show commitID
来看下详细信息找到他的Merge: e234da1 5849fe4这一栏.前面的就是parent 1后面的就是parent 2
git reset和git revert的区别:
1. reset 是直接将版本撤回到指定的位置,revert是通过再次提交一个版本来取消某一次的提交,仅仅是某一次.
2. 在回滚这一操作上看,效果差不多。但是在日后继续merge以前的老版本时有区别。因为git revert是用一次逆向的commit“中和”之前的提交,因此日后合并老的branch时,导致这部分改变不会再次出现,但是git reset是之间把某些commit在某个branch上删除,因而和老的branch再次merge时,这些被回滚的commit应该还会被引入。
3. git reset 是把HEAD向后移动了一下,而git revert是HEAD继续前进,只是新的commit的内容和要revert的内容正好相反,能够抵消要被revert的内容。