好的,让我们通过 git 进行实际会话,这样我们就可以确定我们都在谈论同一件事。我们从新目录中的新仓库开始:
$ mkdir /tmp/temprepo; cd /tmp/temprepo
$ git init
Initialized empty Git repository in /tmp/temprepo/.git/
$ echo 'commit 1' > file.txt
$ git add file.txt
$ git commit -m commit-A
[master (root-commit) 1898863] commit-A
1 file changed, 1 insertion(+)
create mode 100644 file.txt
$ echo 'commit 2' >> file.txt; git commit -a -m 'commit-B'
[master 1d77fa5] commit-B
1 file changed, 1 insertion(+)
$ echo 'commit 3' >> file.txt; git commit -a -m 'commit-C'
[master 0bf2ede] commit-C
1 file changed, 1 insertion(+)
$ echo 'commit 4' >> file.txt; git commit -a -m 'commit-D'
[master 9980dfd] commit-D
1 file changed, 1 insertion(+)
$ git revert HEAD~2
error: could not revert 1d77fa5... commit-B
hint: after resolving the conflicts, mark the corrected paths
hint: with 'git add <paths>' or 'git rm <paths>'
hint: and commit the result with 'git commit'
让我们看看失败的revert,看看git认为问题出在哪里。请注意,我将 merge.conflictstyle 设置为 diff3 以便在三向合并失败时查看基本版本中的内容:
$ git config --get merge.conflictstyle
diff3
$ cat file.txt
commit 1
<<<<<<< HEAD
commit 2
commit 3
commit 4
||||||| 1d77fa5... commit-B
commit 2
=======
>>>>>>> parent of 1d77fa5... commit-B
这就是为什么 git 需要你,用户帮助的原因:“基本版本”——commit-A 中的版本——有一行,commit 1,然后结束。 “要删除的更改”是在commit 1 之后添加一行,但在文件末尾,包含commit 2。 HEAD 中的“当前”版本有四行,commit 1、commit 2、commit 3 和 commit 4。
因此,Git 无法删除 last 行 (commit 4),该行与要删除的行不匹配;也不能简单地删除行commit 2,因为在那之后文件并没有结束。
您现在应该做的是自己修复文件,在某些编辑器中创建“删除更改的版本”,然后是 git add file.txt 和 git revert --continue。
顺便说一句,让我们在 Mercurial 中执行相同的序列:
$ cd ..
$ rm -rf temprepo/
$ mkdir temprepo
$ cd temprepo
$ hg init
$ echo 'commit 1' > file.txt
$ hg add file.txt
$ hg commit -m commit-A
$ echo 'commit 2' >> file.txt
$ hg commit -m commit-B
$ echo 'commit 3' >> file.txt
$ hg commit -m commit-C
$ echo 'commit 4' >> file.txt
$ hg commit -m commit-D
$ hg backout -r 1
reverting file.txt
merging file.txt
warning: conflicts during merge.
merging file.txt incomplete! (edit conflicts, then use 'hg resolve --mark')
0 files updated, 0 files merged, 0 files removed, 1 files unresolved
use 'hg resolve' to retry unresolved file merges
$ cat file.txt
commit 1
<<<<<<< local
=======
commit 2
commit 3
commit 4
>>>>>>> other
换句话说,Mercurial 的行为与 git 相同:它无法在没有帮助的情况下撤消“commit-B”。