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

GIT: Why do I need to solve my merge conflicts twice when using rebase?

我真的很喜欢 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 的顶部?

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,但我没有知道自动执行此操作的任何方法(例如变基选项)。

老实说,我真的不理解人们不喜欢合并,我个人认为它们很有用,但如果你愿意,可以在日志中省略它们 --no-merges

我发现 Git "rerere" 功能解决了我的问题。

记录在:git rerere --helphttp://git-scm.com/docs/git-rerere

将此添加到我的 .gitconfig

[rerere]
    enabled = true

解决了我的问题。