revert 用来取消置顶的提交的内容git
当讨论 revert 时,须要分两种状况,由于 commit 分为两种:spa
git commit
提交的 commit; 须要明确:在使用 git merge
合并两个分支以后,你将会获得一个新的 merge commit。merge commit 和普通 commit 的不一样之处在于 merge commit 包含两个 parent commit,表明该 merge commit 是从哪两个 commit 合并过来的。code
在上图所示的红框中有一个 merge commit,使用 git show
命令能够查看 commit 的详细信息blog
➜ git show bd86846 commit bd868465569400a6b9408050643e5949e8f2b8f5 Merge: ba25a9d 1c7036f
这表明该 merge commit 是从 ba25a9d 和 1c7036f 两个 commit 合并过来的。开发
而常规的 commit 则没有 Merge 行it
➜ git show 3e853bd commit 3e853bdcb2d8ce45be87d4f902c0ff6ad00f240a
使用 git revert <commit id>
便可,git 会生成一个新的 commit,将指定的 commit 内容从当前分支上撤除。ast
revert merge commit 有一些不一样,这时须要添加 -m
选项以表明此次 revert 的是一个 merge commitclass
但若是直接使用 git revert <commit id>
,git 也不知道到底要撤除哪一条分支上的内容,这时须要指定一个 parent number 标识出"主线",主线的内容将会保留,而另外一条分支的内容将被 revert。bug
如上面的例子中,从 git show 命令的结果中能够看到,merge commit 的 parent 分别为 ba25a9d 和 1c7036f,其中 ba25a9d 表明 master 分支(从图中能够看出),1c7036f 表明 will-be-revert 分支。须要注意的是 -m 选项接收的参数是一个数字,数字取值为 1 和 2,也就是 Merge 行里面列出来的第一个仍是第二个。im
咱们要 revert will-be-revert 分支上的内容,即 保留主分支,应该设置主分支为主线,操做以下:
➜ git revert -m 1 bd86846
假设你本身分支 goudan/a-cool-feature 上开发了一个功能,并合并到了 master 上,以后 master 上又提交了一个修改 h,这时提交历史以下:
忽然,你们发现你的分支存在严重的 bug,须要 revert 掉,因而你们把 g 这个 merge commit revert 掉了,记为 G,以下:
而后你回到本身的分支进行 bug_fix,修好以后想从新合并到 master,直觉上只须要再 merge 到 master 便可
i 是新的 merge commit。但须要注意的是,这 不能 获得咱们指望的结果。由于 d 和 e 两个提交曾经被丢弃过,如此合并到 master 的代码,并不会从新包含 d 和 e 两个提交的内容,至关于只有 goudan/a-cool-feature 上的新 commit 被合并了进来,而 goudan/a-cool-feature 分支以前的内容,依然是被 revert 掉了。
因此,若是想恢复整个 goudan/a-cool-feature 所作的修改,应该先把 G revert 掉:
其中 G' 是对 G 的 revert 操做生成的 commit,把以前撤销合并时丢弃的代码恢复了回来,而后再 merge 狗蛋的分支,把解决 bug 写的新代码合并到 master 分支。
能够通俗的来理解:相对你本身 G 是经过别人来远程操做的 revert 操做,相对于别人来讲此时的 master 分支已经不存在 d 和 e 两个提交的内容,而你本身本地分支上并无进行 revert 操做,相对于其余人来讲你本地认为 master 分支还保存有 d 和 e 提交的内容,若是直接合并的话会报错,故须要你本身在本地直接 revert 操做,将 g 点联系释放掉,和线上原始 master 分支保持干净完整的链路,这样就能够正常的 merge commit 了。