为什么git-svn将“我们”和“他们的”的意思颠倒过来了
我使用git-svn,我注意到,当我必须在执行git svn rebase
之后修复合并冲突时,例如git checkout
的--ours
和--theirs
选项的含义是相反的。 也就是说,如果有冲突,我想保留来自SVN服务器的版本并丢弃我在本地所做的更改,那么当我期望它是theirs
时候,我必须使用ours
。
这是为什么?
例:
mkdir test cd test svnadmin create svnrepo svn co file://$PWD/svnrepo svnwc cd svnwc echo foo > test.txt svn add test.txt svn ci -m 'svn commit 1' cd .. git svn clone file://$PWD/svnrepo gitwc cd svnwc echo bar > test.txt svn ci -m 'svn commit 2' cd .. cd gitwc echo baz > test.txt git commit -a -m 'git commit 1' git svn rebase git checkout --ours test.txt cat test.txt # shows "bar" but I expect "baz" git checkout --theirs test.txt cat test.txt # shows "baz" but I expect "bar"
这似乎与基调是一致的。
-
git svn rebase
将从当前HEAD的SVN父节点获取修订版本,并将当前(未提交到SVN)的版本与版本对应。 -
git rebase
确实提到:
请注意,通过在<upstream>
分支之上重播来自工作分支的每个提交,分隔合并工作。
因此,当发生合并冲突时:- 我们所报道的一面是迄今为止重新发布的系列文章,从
<upstream>
, - 他们是工作分支 。
换句话说, 双方交换 。
- 我们所报道的一面是迄今为止重新发布的系列文章,从
git rebase在
<upstream>
分支的顶部重播工作分支的每个提交。
如果你调和两个定义:
- 来自SVN的提交是在本地Git提交重播之上的提交。 他们是“迄今为止重新发布的系列”的一部分,被称为“我们的”(在你的情况下,带有
bar
内容的test.txt
文件) - 工作分支(包含Git提交未知的SVN,在你的情况下,带有
baz
内容的test.txt
文件)是“他们的”,并且每一个本地的Git提交都被重播。
换句话说,SVN与否:
- “
<upstream>
”分支(在其上面重播任何东西,这是迄今为止重新发起的提交的一部分)是“ 我们的 ”。 - 什么是重播(工作分支)是“ 他们的 ”。
CommaToast提示 :
无论HEAD指出的是“我们的”
(首先git rebase upstream
会检查上面的分支,在上面你想要分配:HEAD是指upstream
– ours
现在。)
混淆可能来自工作分支在经典的git merge
的angular色。
当你合并时:
- “工作部门”是包含“迄今为止合并”的部分,被认为是“我们的”
- 而另一个提交代表什么是 – 没有重播,但是 – 合并在工作分支之上,被视为“他们”。
正如git rebase
手册页中所提到的,在rebase期间的合并意味着side被交换。
说同样的事情的另一种方式是考虑到:
- 我们在检出的分支上有“ 我们的 ”,
- 我们所拥有的 (正在被合并或重播)是他们的。
合并时 :
x--x--x--x--x(*) <- current branch B ('*'=HEAD) \ \ \--y--y--y <- other branch to merge
,我们不改变当前的分支'B',所以我们仍然是我们正在工作(我们从另一个分支合并)
x--x--x--x--x---------o(*) MERGE, still on branch B \ ^ / \ ours / \ / --y--y--y--/ ^ their
但是在一个rebase上 ,我们转换方面,因为rebase做的第一件事是检查上游分支! (重播当前的提交)
x--x--x--x--x(*) <- current branch B \ \ \--y--y--y <- upstream branch
git rebase upstream
的git rebase upstream
会首先将B的HEAD
更改为上游分支HEAD
(因此与之前的“当前”工作分支相比,“我们的”和“他们的”的切换)。
x--x--x--x--x <- former "current" branch, new "theirs" \ \ \--y--y--y(*) <- upstream branch with B reset on it, new "ours", to replay x's on it
,然后这个rebase会在新的'我们的'B分支上重放'他们'的提交:
x--x..x..x..x <- old "theirs" commits, now "ghosts", available through reflogs \ \ \--y--y--y--x'--x'--x'(*) <- branch B with HEAD updated ("ours") ^ | upstream branch
git svn rebase
唯一的额外步骤是在代表SVN提交的Git远程分支上首先执行svn“fetch”。
你最初有:
x--x--x--x--x(*) <- current branch B, "ours" for now. \ \ \--y--y--y <- SVN tracking branch, "theirs for now"
,你首先用来自SVN的新提交更新SVN跟踪分支
x--x--x--x--x(*) <- current branch B, still "ours", not for long \ \ \--y--y--y--y'--y' <- SVN tracking branch updated
,那么你将当前分支切换到SVN端(它变成“我们的”)
x--x--x--x--x <- for "B", now "their" during the rebase \ \ \--y--y--y--y'--y'(*) <- SVN tracking branch updated, and branch B: now "ours" (this is "what we now have")
,在重放你正在进行的提交之前(但是在这个rebase期间现在是“他们的”),
x--x..x..x..x <- old "theirs" commits, now "ghosts", available through reflogs \ \ \--y--y--y--y'--y'--x'--x'--x'(*) <- branch B with HEAD updated ("ours") ^ | upstream SVN tracking branch