为什么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是指upstreamours现在。)


混淆可能来自工作分支在经典的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 upstreamgit 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