如何告诉git-svn我获取回购后创建的远程分支?

时间:2008-11-17 21:19:50

标签: git git-svn

我正在使用git-svn来处理我公司的中央svn存储库。我们最近在中央仓库中创建了一个新功能分支。我如何告诉git有关它的信息?当我运行git branch -r时,我只能看到fetch针对svn个仓库运行git初始化我的{{1}}回购时存在的分支?

9 个答案:

答案 0 :(得分:284)

您可以手动添加远程分支

git config --add svn-remote.newbranch.url https://svn/path_to_newbranch/
git config --add svn-remote.newbranch.fetch :refs/remotes/newbranch
git svn fetch newbranch [-r<rev>]
git checkout -b local-newbranch -t newbranch
git svn rebase newbranch

答案 1 :(得分:90)

如果要跟踪所有远程svn分支,那么解决方案就像:

一样简单
git svn fetch

这将获取尚未提取的所有远程分支。

额外提示:如果您最初只检查了行李箱,之后您想要跟踪所有分支机构,那么请修改.git/config看起来像这样并重新运行git svn fetch

[svn-remote "svn"]
        url = https://svn/path_to_repo_root/
        fetch = path_to_trunk:refs/remotes/git-svn
        branches = path_to_branches/*:refs/remotes/*

关键点url应指向存储库根目录,fetchbranches中定义的路径应相对于url

如果你只想获取特定的分支而不是ALL,那么git svn --help就有一个很好的例子:

[svn-remote "huge-project"]
        url = http://server.org/svn
        fetch = trunk/src:refs/remotes/trunk
        branches = branches/{red,green}/src:refs/remotes/branches/*
        tags = tags/{1.0,2.0}/src:refs/remotes/tags/*

对于git-svn的旧版本,一旦您指定了这样的分支,您就可能无法获得git svn fetch的新分支。一种解决方法是添加更多fetch行,如下所示:

[svn-remote "huge-project"]
        url = http://server.org/svn
        fetch = trunk/src:refs/remotes/trunk
        fetch = branches/blue:refs/remotes/branches/blue
        fetch = branches/yellow:refs/remotes/branches/yellow
        branches = branches/{red,green}/src:refs/remotes/branches/*

@AndyEstes的另一种解决方法:编辑.git/svn/.metadata并在创建任何新指定的分支或标记之前将branches-maxRevtags-maxRev的值更改为修订版。完成此操作后,运行git svn fetch以跟踪新的svn远程分支。

答案 2 :(得分:53)

看来我只需git svn fetch;不知怎的,我已经说服自己会取出整个回购而不仅仅是改变。

答案 3 :(得分:14)

也许我以某种方式弄乱了它,但我按照vjangus的回答中的说明,几乎工作了。唯一的问题是newbranch似乎没有从行李箱分支。在gitk中,它本身就是一种“浮动”;它与躯干没有共同的祖先。

解决方法是:

  1. 在创建分支之前,找到在主干上发生的最后一次提交的SHA1。
  2. 在新分支上找到第一次提交的SHA1(消息可能是“创建新分支,从trunk @ 12345复制”或其他内容)
  3. git diff-tree <sha1 from step 1> <sha1 from step 2> - 应该没有输出。如果有输出,则可能选择了错误的提交。
  4. git checkout local-newbranch然后git rebase <sha1 from step 1>。这会将local-newbranch重新绑定到新树上,但remotes/newbranch仍会断开连接。
  5. 转到文件.git/refs/remotes/newbranch并对其进行编辑,以包含 new 提交的完整SHA1(在重新定位的newbranch上),该SHA1对应于当前指向的旧提交在。 (或者可以使用git-update-ref refs/remotes/newbranch <new-SHA>。谢谢你。)
  6. 下次git svn dcommitnewbranch时,您会收到一些关于更新某些日志的消息。我认为这是正常的。
  7. 我建议保持gitk --all一直打开并经常刷新以跟踪您正在做的事情。我还是git和git svn的新手,所以请建议改进​​这种方法。

答案 4 :(得分:7)

简化vjangus的回答:

如果你在SVN中使用标准布局并且已经完成了通常的svn init,那么git-svn会为你做配置。只是:

  1. 在SVN中查找分支副本修订
  2. 使用git-svn
  3. 获取该修订版
  4. 创建新的本地分支跟踪远程
  5. 一个例子。 SVN网址为svn+ssh://gil@svn.myplace.com/repo。我正在寻找的SVN分支是newbranch。本地git分支(跟踪远程newbranch)将为git-newbranch

    第1步:找到分支副本修订

        # svn log --stop-on-copy svn+ssh://gil@svn.myplace.com/repo/branches/newbranch | tail -4
        r7802 | someone | 2014-03-21 18:54:58 +0000 (Fri, 21 Mar 2014) | 1 line
    
        branching HEAD to newbranch
        ------------------------------------------------------------------------
    

    因此SVN中的分支点是修订版7802。

    第2步:获取修订版

        # git svn fetch -r 7802
        Found possible branch point: svn+ssh://gil@svn.myplace.com/repo/trunk => svn+ssh://gil@svn.myplace.com/repo/branches/newbranch, 7801
        Found branch parent: (refs/remotes/trunk) 8dcf3c5793ff1a8a79dc94d268c91c2bf388894a
        Following parent with do_switch
        Successfully followed parent
        r7802 = 9bbd4194041675ca5c9c6f3917e05ca5654a8a1e (refs/remotes/newbranch)
    

    git-svn做了所有的工作,现在知道了遥控器:

        # git show-ref | grep newbranch
        2df23af4733f36f5ad3c14cc1fa582ceeb3edb5c refs/remotes/newbranch
    

    步骤3:创建跟踪远程分支的新本地分支:

        # git checkout -b git-newbranch -t newbranch
        Checking out files: 100% (413/413), done.
        Branch git-newbranch set up to track local ref refs/remotes/newbranch.
        Switched to a new branch 'git-newbranch'
    

答案 5 :(得分:5)

我没有找到任何关于此功能的文档,但看起来git svn配置支持多个提取条目。这样,您还可以单独添加分支,而无需在配置中添加另一个远程svn存储库条目,也不需要使用通配符来获取某个目录的所有分支。

假设您的SVN树真的很讨厌,有很多分支,没有任何逻辑,例如它们的位置,例如有分支和子目录包含更多分支。

即。

trunk
branches
  -> branch1
  -> sub-dir1
    -> branch2
    -> branch3
  -> sub-dir2
    -> branch4
    -> sub-dir3
      -> branchX 
<... hundreds more ...>

并且您只想亲自挑选一些要包含在您的git存储库中的分支。

您可以首先使用trunk而不使用任何其他分支来初始化您的存储库:

git svn clone -r 10000:HEAD https://svn.com/MyRepo myrepo --prefix=svn/ --trunk=trunk 

之后您应该看到以下配置:

localhost: elhigu$ git config --get-regexp "svn-remote."
svn-remote.svn.url https://svn.com/MyRepo
svn-remote.svn.fetch trunk:refs/remotes/svn/trunk

当您想要从MyRepo获取新分支时,您只需通过以下方式添加新的获取条目:

git config --add svn-remote.svn.fetch branches/sub-dir2/branch4:refs/remotes/svn/branches/sub-dir2/branch4

或者您可以在.git / config

中编辑相同的配置

要在将新分支添加到配置后获取新分支,只需运行:

git svn fetch -r 10000:HEAD

[编辑] 有时似乎有必要使用--all参数运行fetch来获取新添加的分支:

git svn fetch --all -r 10000:HEAD

答案 6 :(得分:4)

您可以尝试SubGit而不是处理git-svn怪癖。

必须将SubGit安装到Subversion存储库中。之后,可以使用标准的git工作流而不是使用特殊的git-svn命令:

  1. 推送新提交:

    GIT-的svn:

    $ git commit
    $ git svn rebase
    $ git svn dcommit
    

    SubGit:

    $ git commit
    $ git push
    
  2. 获取传入的更改

    GIT-的svn:

    $ git svn rebase
    

    SubGit:

    $ git pull [--rebase]
    
  3. 创建新分支:

    GIT-的svn:

    $ git svn branch foo
    $ git checkout -b foo -t remotes/foo
    $ git commit
    $ git svn dcommit
    

    SubGit:

    $ git checkout -b foo
    $ git commit
    $ git push
    
  4. 有关详细信息,请参阅SubGit documentation

答案 7 :(得分:2)

要添加到vjangus的答案,这对我有帮助,我还发现添加使用git grafts在适当的位置将分支绑定到主干是有用的 - 允许git查看历史记录并正确执行合并。

这只是使用哈希值向.git/info/grafts添加一行:

<initial branch commit> <parent commit in trunk>

例如

378b0ae0902f5c2d2ba230c429a47698810532e5 6c7144991381ce347d4e563e9912465700be0638

归功于http://evan-tech.livejournal.com/255341.html

(我将此添加为评论,但我的名声不够。)

答案 8 :(得分:0)

如果您没有使用有效的布局结帐,则无法结帐远程分支。

这就是我的所作所为:

git svn init -s <svn path with no trunk> local_repo
cd local_repo
git svn fetch 
## wait

之后,您可以切换到远程分支:

git checkout --track -b branch_name branch_name

然后您将自动切换到您的分支。