git revert再merge的坑
用 git 很久了,一直以来都觉得已经玩转了 git 。但是最近遇到了一个 git revert 的一个坑: 使用 git revert 后,如果再 merge 的话,会显示 Already up to date ,但是其实并没有 merge 进去,原因是什么呢?让我们一起一探究竟。
问题重现
一开始我们有两个分支 : master 和 dev
dev: 7a320e3(改动A)
/
master: 9075d0e -- 2d38af8 -- 7bd9ae8
把 dev 分支 merge 到 master 分支
dev: 7a320e3(改动A)
/ \
master: 9075d0e -- 2d38af8 -- 7bd9ae8 -- 7a320e3(改动A)
git revert 7bd9ae8
dev: 7a320e3(改动A)
/ \
master: 9075d0e -- 2d38af8 -- 7bd9ae8 -- 7a320e3(改动A) -- 3575f4c(Revert "改动A")
现在如果再次把 dev 分支 merge 到 master 分支,会出现
Already up to date
为什么
问题
- 很多人就会问了(其实我遇到这个问题一开始也是这么想的..),为什么没法 merge 呢?不是已经回到 7bd9ae8 了吗?
注意: 3575f4c 和 7bd9ae8 具有相同的内容。
答案
- 你说的对,先让我们再看看目前的 dev 和 master 两个分支的情况:
dev: 7a320e3(改动A)
/ \
master: 9075d0e -- 2d38af8 -- 7bd9ae8 -- 7a320e3(改动A) -- 3575f4c(Revert "改动A")
- 可以看到,master 确实回到了 7bd9ae8,但是 master 还是包含着 dev 的所有 commits 。
- 所以,即使 dev 中的 7a320e3 和 3575f4c 不同,但是 7a320e3 不会被 merge 到 3575f4c 后面。
- 相反,因为 master 中已经有 7a320e3 了,所以会显示 Already up to date
如何解决
- 进入 dev 分支
git checkout dev
- 回到 7bd9ae8 ,记得加上 mixed 参数
扩展阅读:
What’s the difference between git reset —mixed, —soft, and —hard? - Stack Overflow
git reset 7bd9ae8 --mixed
- 把 7a320e3(改动 A) 存进 stash
git stash -u
- Rebase master
git rebase master
- 把 7a320e3 从 stash 中 pop 出来
git stash pop
- 重新提交 7a320e3(改动 A)
git add ./
git commit -m "改动A"
- 切换到 master 分支
git checkout master
- 最后一步,现在才可以把 dev 分支 merge 到 master 分支
git merge dev
- 经过了上面的过程,现在的 dev 和 master 分支长这个样子:
dev: 7a320e3(改动A)
/ \
master: 9075d0e -- 2d38af8 -- 7bd9ae8 -- 7a320e3(改动A) -- 3575f4c(Revert "改动A") -- 7f5eedc
↑ ↑
内容和7bd9ae8一样 内容和7a320e3一样
结论
revert 之后再 rebase 之后有坑,使用 revert 请谨慎:(