git revert HEAD~2在没有适当解决方案的情况下产生冲突

时间:2014-02-09 23:20:43

标签: git

假设我们有四个提交(D为头)

A-B-C-D

如果我想删除(还原)提交B中的更改但保留在C和D中所做的更改,您将如何执行此操作?

如果我这样做

git revert HEAD~2

我发生了冲突。选择分辨率时,只有两个选项可以使用 A 中所做的更改,或保持原样(在 D 中进行更改)。

例如

提交A后,文本文件包含

commit 1
提交B后

,它包含

commit 1
commit 2
提交C后

,它包含

commit 1
commit 2
commit 3
提交D后

,它包含

commit 1
commit 2
commit 3
commit 4

因此,如果我现在git revert HEAD~2,我应该最终得到包含

的文本文件
commit 1
commit 3
commit 4

正确?如果没有,你可以解释为什么不,因为这正是恢复Mercurial时发生的事情。

修改:无重写历史记录。

1 个答案:

答案 0 :(得分:1)

好的,让我们通过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'

让我们来看看失败的恢复,看看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 2HEAD中的“当前”版本有四行,commit 1commit 2commit 3commit 4

因此,Git无法删除 last 行(commit 4),该行与要删除的行不匹配;也不能简单地删除行commit 2,因为文件之后没有结束。

您现在应该做的是在一些编辑器中自行修复文件,以创建“删除更改的版本”,然后git add file.txtgit 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”。