为什么“我们”和“他们的”的含义与git相反

我使用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会检查upstream分支,然后在其上面重新分配:HEAD指的是upstream - 现在是oursupstream分支。)


    混淆可能来自工作分支在经典git merge的角色。
    当你合并时:

  • “工作部门”是包含“迄今为止合并”的部分,被认为是“我们的”,
  • 而另一个提交表示正在进行的 - 不重播,但是 - 在工作分支之上合并,并被视为“他们”。
  • 正如git rebase手册页所提到的,在rebase期间的合并意味着该边被交换。


    说同样的事情的另一种方式是考虑到:

  • 我们在检出分支上有' 我们 ',
  • 我们所拥有的 (并被合并或重播)是他们的。

  • 合并时

    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")
    

    ,在重放您正在进行的提交之前(但是在重新绑定期间现在是“他们的”),

    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
    
    链接地址: http://www.djcxy.com/p/1109.html

    上一篇: Why is the meaning of “ours” and “theirs” reversed with git

    下一篇: How do I jump to the next/prev diff in GIT difftool?