GIT:使用rebase时为什么需要解决两次合并冲突?

10
我非常喜欢git pull --rebase选项,但是当我使用它并遇到合并冲突时,最终需要解决两次冲突。我尝试使用git pull --rebase=preserve,这样应该可以考虑合并操作。
请看下面的例子:
# do a new clone "a"
$ mkdir origin && cd origin && git init --bare --shared && cd ..
$ git clone ./origin a && cd a

# Add, commit, push
a (master) $ echo "foo" > foo && git add foo && git commit -m "foo"
a (master) $ git push origin master

# Create branch "b"
a (master) $ git branch b

# change foo and push
a (master) $ echo "// eof " >> foo && git ci -am "eof - master"
a (master) $ git push origin master

# checkout branch "b", change and push
a (master) $ git checkout b
a (b) $ echo "// EOF " >> foo && git ci -am "EOF b" && git push origin b

# back to master
a (b) $ git checkout master

# merge
a (master) $ git merge b # conflict as expected
a (master) $ git diff
diff --cc foo
index e10b853,1d3cc50..0000000
--- a/foo
+++ b/foo
@@@ -1,2 -1,2 +1,6 @@@
  foo
++<<<<<<< HEAD
 +// eof
++=======
+ // EOF
++>>>>>>> b

# Now, resolve the conflict
a (master|MERGING) $ echo "foo" > foo && echo "// eof" >> foo && git add foo
a (master|MERGING) $ git commit

# In the mean while somewhere else. ############################################
a (master) $ cd ..  && git clone ./origin other && cd other/
other (master) $ echo "bar" > bar && git add bar && git ci -am "bar" && git push # OK

# Back to us ###################################################################
other (master) $ cd ../a
a (master) $ git push # will fail...

# I now do a rebase preserve as I want to rebase my merge commit to the top of master
a (master) $ git pull --rebase=preserve # This command does not do a very good job...
a (master|REBASE-i 1/1) $ git diff
diff --cc foo
index e10b853,1d3cc50..0000000
--- a/foo
+++ b/foo
@@@ -1,2 -1,2 +1,6 @@@
  foo
++<<<<<<< HEAD
 +// eof
++=======
+ // EOF
++>>>>>>> 3cd5d3ac5b870c613233f0a9f1a81df5691ccc7c

如果我用git pull --no-rebase替换git pull --rebase=preserve,那么它会按预期工作(我只需要解决一次冲突),但是我必须查看日志中的所有合并提交。

我该如何让git "rebase"合并和解决冲突,以使其适合新的远程HEAD之上?

2个回答

9
我发现Git的“rerere”功能解决了我的问题。
文档在:`git rerere --help` 或者 http://git-scm.com/docs/git-rerere 将这个功能添加到我的`.gitconfig`文件中。
[rerere]
    enabled = true

解决了我的问题。

1
重新基础(Rebase)基本上是将位于HEADbase之间的提交按顺序应用于base。 这意味着,如果在它们之间进行了一些合并,则会丢失它们,您需要再次解决冲突。 说明:

假设您有以下树:

A--B---M
 \    / 
  `-C'

M 是合并冲突更改 BC 的结果,它是您的 HEAD。现在,如果您运行 git rebase A,那么git将尝试创建以下树形结构:

A-B-C

但当尝试将 C 应用到 B 时,它会遇到冲突。在忽略合并 M 的情况下,它必须要求您解决这个冲突。

此时,您可以从已经合并了这些文件的版本 M 中检出相关文件:git checkout M -- file/with/conflict,但我不知道任何自动执行此操作(例如 rebase 选项)的方法。

说实话,我真的不理解人们对合并的厌恶,个人认为它们很有用,但如果您想要,可以使用 --no-merges 在日志中省略它们。


这意味着如果它们之间有一些合并,它们就会丢失,你必须再次解决冲突。使用 git pull --rebase=preserve 选项相当于 git rebase --preserve-merges,它指示重新基于保留合并。然而,显然那些合并的冲突解决在重新基础时不被考虑。 - Dan Fischer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接