【问题标题】:Why is the meaning of “ours” and “theirs” reversed with git-svn为什么用 git-svn 颠倒“我们的”和“他们的”的意思
【发布时间】:2011-02-26 21:59:27
【问题描述】:

我使用 git-svn,我注意到当我必须在执行 git svn rebase 后修复合并冲突时,--ours--theirs 选项的含义例如git checkout 被反转。也就是说,如果有冲突,我想保留来自 SVN 服务器的版本并丢弃我在本地所做的更改,我必须使用ours,而我希望它是theirs

这是为什么呢?

例子:

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 git-svn


【解决方案1】:

这似乎与变基的作用一致。

  • git svn rebase 将从当前 HEAD 的 SVN 父级获取修订版,并针对它重新设置当前(未提交到 SVN)工作。

  • git rebase 确实提到:
    请注意,rebase 合并通过在 <upstream> 分支之上重播工作分支中的每个提交来工作。
    因此,当发生合并冲突时:

    • 我们报道的一方是迄今为止重新改编的系列,从<upstream>开始
    • 他们是工作分支
      换句话说,双方交换了

git rebase 在<upstream> 分支之上重放工作分支的每个提交。

如果你协调这两个定义:

  • 来自 SVN 的提交是在其之上重放本地 Git 提交的提交。它们是“迄今为止重新定位的系列”的一部分,并被称为“我们的”(在您的情况下,test.txt 文件与 bar 内容)
  • 工作分支(包含 SVN 未知的 Git 提交,在您的情况下,是具有 baz 内容的 test.txt 文件)是“他们的”,并且正在重播这些本地 Git 提交中的每一个。

换句话说,SVN与否:

  • <upstream>”分支(在其之上重放任何内容,并且是迄今为止重新定位的提交的一部分”)是“ours”。
  • 正在重放的内容(工作分支)是“他们的”。

好的mnemonic tipCommaToast:

HEAD 所指的都是“我们的”

git rebase upstream 做的第一件事就是检出你想要在其上变基的 upstream 分支:HEAD 指的是 upstream -- ours 现在。)


混淆可能来自经典 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

但是在变基上,我们切换到一边,因为变基所做的第一件事就是检查上游分支! (在其之上重播当前提交)

x--x--x--x--x(*) <- current branch B
    \
     \
      \--y--y--y <- upstream branch

A 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“获取”。
您最初:

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

【讨论】:

  • 哇,多么好的答案,谢谢!我一定完全错过了git rebase 手册页中的那句话...
  • @epologee:不客气。当您仅使用 git 时,它也很有用,可以了解 rebase 与合并期间发生的情况。它添加到上游定义:stackoverflow.com/questions/2739376/…
  • 我的上帝!!! Torvalds 服用了哪些药物?这太复杂了! Git 是一个非常危险的工具。如果您尝试使用外部知识或直觉,您可以轻松地破坏您的所有工作。软件开发已陷入困境!
  • @user148298 这个函数没有错。除非您是 git 专家,否则您不必知道所有这些事情。如果您确实需要高级功能,则必须先学习它。
猜你喜欢
  • 1970-01-01
  • 2020-11-21
  • 2011-04-30
  • 2018-05-27
  • 2014-10-23
  • 1970-01-01
  • 2018-08-29
  • 1970-01-01
相关资源
最近更新 更多