通过GIT使用(不同的)SVN远程存储库的正确方法是什么

时间:2011-01-19 17:46:08

标签: git repository git-svn

环境:

  • 附近的SVN信息库名为svn + ssh:// yourserver / svn / prj
  • 外部SVN存储库名为svn + ssh:// theirserver / svn / prj
  • 一个名为“myrep”的本地git存储库,它是附近的一个git-svn克隆
    • 使用:git svn clone -R nearbysvn -s svn+ssh://yourserver/svn/prj制作,因此有一个行李箱和一些分支(从行李箱r3分叉/复制。
$ git branch -a
* master
 remotes/b1
 remotes/b2
 remotes/trunk

我们来了。

在我的主人(来自遥控器/主干的分支)中进行的简单更改被添加,然后被提交,然后通过git svn dcommit“推送”到SVN。

这么好,到目前为止。 树现在看起来像这样:

$ git log --graph --oneline --all
* 1e6277f change 3 in b2
* 7623755 two new branches
| * 7901fad change3 in b1
| * e83f135 two new branches
|/  
| * 6fac7ad change 3
| * 5858495 new file test3
| * 4cdf2ed change2
| * 511ed7a change1
|/  
* d5c68ab init

结论1:

git svn dcommit将我本地主分支中所做的所有更改发送到远程/中继SVN,然后将其重新绑定 输出和树看起来像这样:

$ git add test

$ git ci
[master 8a03901] modified test via git for SVN trunk
 1 files changed, 1 insertions(+), 1 deletions(-)

$ git svn dcommit
Committing to svn+ssh://yourserver/svn/prj/trunk ...
    M   test
Committed r9
    M   test
r9 = 542eb78f841fc1a4d12f4a72f68e40e3069f3309 (refs/remotes/trunk)
No changes between current HEAD and refs/remotes/trunk
Resetting to the latest refs/remotes/trunk

$ git log --graph --oneline --all
* 542eb78 modified test via git for SVN trunk
* 6fac7ad change 3
* 5858495 new file test3
* 4cdf2ed change2
* 511ed7a change1
| * 1e6277f change 3 in b2
| * 7623755 two new branches
|/  
| * 7901fad change3 in b1
| * e83f135 two new branches
|/  
* d5c68ab init

问题1:

  • 为什么要初始化b1和b2的父级?
  • 为什么我的主人和“init”树一样,不应该是远程的“分支”吗?合并状态仍然是“未合并”,因为只进行了一次改造

问题2:

修补遥控器/ b1的某些更改的正确/最佳方法是什么

我的方式:使用git checkout -b myb1 remotes/b1然后$ git diff master^..master | patch -p1创建一个本地分支myb1然后添加,ci,dcommit

问题3:

如何获取有关我们所属的远程路径/分叉的分支的信息? config没有告诉我任何相关信息:

$ git config --get-regexp svn-remote
svn-remote.nearbysvn.url svn+ssh://yourserver/svn/prj
svn-remote.nearbysvn.fetch trunk:refs/remotes/trunk
svn-remote.nearbysvn.branches branches/:refs/remotes/
svn-remote.nearbysvn.tags tags/:refs/remotes/tags/

问题4:

这有点棘手: 第二个(外部)SVN现在是第一个(外部)的“重复”,但有一个例外:外部也可能被其他人使用。 目前,在“附近”进行的所有更改都必须在外部更改(在第二个工作副本中修补文件,依此类推......

如果删除SVN现在是第二个远程SVN存储库,那么通过git进行合并来“优化”这个最佳做法是什么?

是的,有些人会使用BeyondCompare等(见How to compare source in Git repository between source in SVN repository)。但这不是我最喜欢的“合并”方式

我建议我需要: *本地分支,如myb1,master,master2 *我的工作的分支/分支,如master-taskX(git checkout -b master-taskX) *然后我可能会使用merge将我的更改恢复为master,然后再提交它们?

我很高兴很快听到一些git-svn专家的意见;)

亲切的问候, 〜马塞尔

附录:

仅供参考:这是“附近”的初始SVN历史记录:

------------------------------------------------------------------------
r8 | konqi | 2011-01-19 17:48:51 +0100 (Mi, 19 Jan 2011) | 2 lines
Changed paths:
   M /branches/b2/test3

change 3 in b2

------------------------------------------------------------------------
r7 | konqi | 2011-01-19 17:48:42 +0100 (Mi, 19 Jan 2011) | 2 lines
Changed paths:
   M /branches/b1/test3

change3 in b1

------------------------------------------------------------------------
r6 | konqi | 2011-01-19 17:46:07 +0100 (Mi, 19 Jan 2011) | 2 lines
Changed paths:
   M /trunk/test3

change 3

------------------------------------------------------------------------
r5 | konqi | 2011-01-19 17:36:13 +0100 (Mi, 19 Jan 2011) | 3 lines
Changed paths:
   A /branches/b1 (from /trunk:1)
   R /branches/b1/test (from /trunk/test:2)
   R /branches/b1/test2 (from /trunk/test2:3)
   A /branches/b1/test3 (from /trunk/test3:4)
   A /branches/b2 (from /trunk:1)
   R /branches/b2/test (from /trunk/test:2)
   R /branches/b2/test2 (from /trunk/test2:3)
   A /branches/b2/test3 (from /trunk/test3:4)

two new branches


------------------------------------------------------------------------
r4 | konqi | 2011-01-19 17:30:05 +0100 (Mi, 19 Jan 2011) | 2 lines
Changed paths:
   A /trunk/test3

new file test3

------------------------------------------------------------------------
r3 | konqi | 2011-01-19 17:28:46 +0100 (Mi, 19 Jan 2011) | 2 lines
Changed paths:
   M /trunk/test2

change2

------------------------------------------------------------------------
r2 | konqi | 2011-01-19 17:28:34 +0100 (Mi, 19 Jan 2011) | 2 lines
Changed paths:
   M /trunk/test

change1

------------------------------------------------------------------------
r1 | konqi | 2011-01-19 17:28:10 +0100 (Mi, 19 Jan 2011) | 2 lines
Changed paths:
   A /branches
   A /tags
   A /trunk
   A /trunk/test
   A /trunk/test2

init

------------------------------------------------------------------------

2 个答案:

答案 0 :(得分:0)

我会为2个svn回购制作2个独立的git回购。然后,通过其中一个Git存储库中的rebase等协调更改。

答案 1 :(得分:0)

  • 为什么要初始化b1和b2的父级?
    • 因为在svn的历史中,init创建'branches'文件夹,git-svn将其视为所有分支提交的父级。最后,它只是一个惯例,对任何功能都不是特别重要。
  • 为什么我的主人和“init”树一样,不应该是远程的“分支”吗?
    • 它是来自远程的分支,但是git提交不是分支的一部分,这不是git的想法。对于git,“branch”是指向提交的指针,其中包括暗示所有父提交。提交本身并不了解或关心它们所属的分支。
  • 合并状态仍然是“未合并”,因为只进行了一次改造
    • (不知道你在这里谈论什么)

问题2:

  • 修补遥控器/ b1的某些更改的正确/最佳方法是什么
    • 如果您没有进行完全合并,请尝试使用git cherry-pick(请参阅git help cherry-pick);它或多或少是一种更容易,更可靠的方式来做你已经在做的事情

问题3:

  • 如何获取有关我们所属的远程路径/分叉的分支的信息?
    • 您可以检查它们并运行git svn info,或者使用git log和grep作为提交消息底部的svn行,其中列出了源的路径和转速。后者是git-svn对svn提交来源的权威来源。

问题4:

  • 这有点棘手:第二个(外部)SVN现在是第一个的“重复”,但有一个例外:外部也可能被其他人使用。目前,在“附近”进行的所有更改都必须在外部更改(在第二个工作副本中修补文件,依此类推......

    如果删除SVN现在是第二个远程SVN存储库,那么通过git进行合并来“优化”这个最佳做法是什么?

    是的,有些人会使用BeyondCompare等(请参阅如何比较SVN存储库中源代码之间的Git存储库中的源代码)。但这不是我最喜欢的“合并”方式

    我建议我需要:*本地分支,如myb1,master,master2 * forks / branch for my work for my work,如master-taskX(git checkout -b master-taskX)*然后我可能会使用merge来获取我的更改掌握,然后dcommit他们??

    • 我在同一台机器上有两个git存储库,一个(让我们称之为A和B)设置为跟踪每个svn repo。做你的开发A,设置跟踪附近的回购。在git svn clone之后,让B将A注册为常规git“remote”(git remote add / path / to / repo / A)。一旦你准备好在A上提交你的提交,在B中使用git fetch -f将它们带到那里。然后git svn dcommit在A;在B中使用像git checkout -b temp A/master; git rebase --onto trunk HEAD^; git svn dcommit; git checkout master; git branch -D temp之类的东西来提交对repo B的更改。要提交多个rev,你可以整齐地调整rebase命令中的克拉数。

请注意,根据我的经验,git merge与git-svn不兼容,所以你可能想要坚持上面那些不在git历史中创建双父提交的技术。