Git操作:撤销提交B的改动并保留提交C、D(不修改历史)
问题
提交历史:
A -- B -- C -- D (HEAD)
文件test.txt内容(每个提交对应添加一个字母):
A B C D
需求:不修改Git历史,仅调整工作区,撤销提交B的改动,同时保留C、D的改动。若出现冲突保留冲突分隔符,期望效果如下:
diff --git a/t.txt b/t.txt index 8422d40..d9a85ba 100644 --- a/t.txt +++ b/t.txt @@ -1,4 +1,3 @@ A -B C D
补充说明
我尝试执行git revert -n B,但触发了C、D所有改动的冲突:
$ git revert -n 440e9c Auto-merging t.txt CONFLICT (content): Merge conflict in t.txt error: could not revert 440e9c1... B hint: after resolving the conflicts, mark the corrected paths hint: with 'git add <paths>' or 'git rm <paths>' $ git diff diff --cc t.txt index 8422d40,760a73a..0000000 --- a/t.txt +++ b/t.txt @@@ -1,4 -1,2 +1,8 @@@ A ++<<<<<<< HEAD +B +C +D ++======= + ++>>>>>>> parent of 440e9c1 (B)
解决方案
方法一:手动编辑(适合简单场景)
直接打开test.txt,删除B所在的行即可,这是最直接的方式。
方法二:Git命令自动处理(适合复杂改动)
如果提交B的改动更复杂,不想手动编辑,可以通过反向应用B的提交补丁来实现:
- 先获取提交B相对于其父提交的改动:
这个命令会输出B提交中对git diff B^ B -- test.txttest.txt做的修改(也就是添加了B行)。 - 反向应用这个补丁到工作区,撤销B的改动:
git diff B^ B -- test.txt | git apply -R
若已执行git revert -n导致冲突
先撤销未完成的revert操作:
git revert --abort
之后再用上面任意一种方法处理。
内容的提问来源于stack exchange,提问作者Tom Huntington
相关产品推荐
相关产品推荐

