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 基本上只是接受 HEAD
和 base
之间的提交,并按顺序将它们应用到 base
。这意味着如果您在它们之间进行了一些合并,它们就会丢失并且您必须再次解决冲突。插图:
假设您有以下树:
A--B---M
\ /
`-C'
M
是冲突更改 B
和 C
的合并,它是您的 HEAD
。现在,如果您 运行 git rebase A
那么 git 将尝试创建以下树:
A-B-C
但是当尝试将 C
应用到 B
时,它遇到了冲突。忽略合并 M
它必须要求用户解决它。
此时您可以从已经合并的修订 M
中检出有问题的文件:git checkout M -- file/with/conflict
,但我没有知道自动执行此操作的任何方法(例如变基选项)。
老实说,我真的不理解人们不喜欢合并,我个人认为它们很有用,但如果你愿意,可以在日志中省略它们 --no-merges
我发现 Git "rerere" 功能解决了我的问题。
记录在:git rerere --help
或 http://git-scm.com/docs/git-rerere
将此添加到我的 .gitconfig
[rerere]
enabled = true
解决了我的问题。
我真的很喜欢 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 基本上只是接受 HEAD
和 base
之间的提交,并按顺序将它们应用到 base
。这意味着如果您在它们之间进行了一些合并,它们就会丢失并且您必须再次解决冲突。插图:
假设您有以下树:
A--B---M
\ /
`-C'
M
是冲突更改 B
和 C
的合并,它是您的 HEAD
。现在,如果您 运行 git rebase A
那么 git 将尝试创建以下树:
A-B-C
但是当尝试将 C
应用到 B
时,它遇到了冲突。忽略合并 M
它必须要求用户解决它。
此时您可以从已经合并的修订 M
中检出有问题的文件:git checkout M -- file/with/conflict
,但我没有知道自动执行此操作的任何方法(例如变基选项)。
老实说,我真的不理解人们不喜欢合并,我个人认为它们很有用,但如果你愿意,可以在日志中省略它们 --no-merges
我发现 Git "rerere" 功能解决了我的问题。
记录在:git rerere --help
或 http://git-scm.com/docs/git-rerere
将此添加到我的 .gitconfig
[rerere]
enabled = true
解决了我的问题。