198

git-svn用来处理我公司的中央 Subversion 存储库。我们最近在中央存储库中创建了一个新功能分支。

我如何告诉 Git 呢?当我运行时,git branch -r我只能看到当我fetch针对 Subversion 存储库运行以初始化我的 Git 存储库时存在的分支?

4

9 回答 9

300

您可以手动添加远程分支,

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
于 2009-09-16T03:23:25.443 回答
103

如果要跟踪所有远程 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应该指向存储库根目录,并且在fetch和中定义的路径branches应该是相对于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-maxRev或修改的值。tags-maxRev完成此操作后,运行git svn fetch以跟踪新的 svn 远程分支。

于 2012-04-16T11:49:38.617 回答
53

看来我只需要git svn fetch;不知何故,我说服自己会获取整个 repo 而不仅仅是更改。

于 2008-11-17T21:26:29.820 回答
15

也许我以某种方式把它搞砸了,但我按照 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. 转到文件并对其进行编辑以包含与当前指向的旧提交相对应的提交(在 rebased 上).git/refs/remotes/newbranch的完整 SHA1 。(或者也许使用。谢谢你。)newbranchgit-update-ref refs/remotes/newbranch <new-SHA>
  6. 下一次,你git svn dcommitnewbranch收到一堆关于它更新一些日志的消息。我认为这很正常。

我建议始终保持gitk --all打开状态并经常刷新它以跟踪您在做什么。我对 git 和 git svn 还是有点陌生​​,所以请建议改进​​这个方法。

于 2010-12-11T09:56:28.023 回答
7

vjangus 回答的简化:

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

  1. 在 SVN 中查找分支副本修订
  2. 使用 git-svn 获取该版本
  3. 创建新的本地分支跟踪远程

一个例子。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 | 尾-4
    r7802 | 某人 | 2014-03-21 18:54:58 +0000(2014 年 3 月 21 日星期五)| 1 行

    将 HEAD 分支到 newbranch
    -------------------------------------------------- ----------------------

所以 SVN 中的分支点是修订版 7802。

第 2 步:获取修订版

    # git svn 获取 -r 7802
    找到可能的分支点:svn+ssh://gil@svn.myplace.com/repo/trunk => svn+ssh://gil@svn.myplace.com/repo/branches/newbranch, 7801
    找到分支父级:(refs/remotes/trunk)8dcf3c5793ff1a8a79dc94d268c91c2bf388894a
    跟随父母与 do_switch
    成功关注父母
    r7802 = 9bbd4194041675ca5c9c6f3917e05ca5654a8a1e (refs/remotes/newbranch)

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

    # git 显示参考 | grep 新分支
    2df23af4733f36f5ad3c14cc1fa582ceeb3edb5c refs/remotes/newbranch

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

    # git checkout -b git-newbranch -t newbranch
    签出文件:100% (413/413),完成。
    设置分支 git-newbranch 以跟踪本地 ref refs/remotes/newbranch。
    切换到新分支“git-newbranch”
于 2014-04-02T17:56:46.257 回答
5

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

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

IE

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

并且您只想手动挑选一些要包含到您的 git 存储库中的分支。

你可以先用没有任何额外分支的主干初始化你的存储库:

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
于 2012-02-11T13:46:01.263 回答
4

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

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

  1. 推送新的提交:

    git-svn:

    $ git commit
    $ git svn rebase
    $ git svn dcommit
    

    子Git:

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

    git-svn:

    $ git svn rebase
    

    子Git:

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

    git-svn:

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

    子Git:

    $ git checkout -b foo
    $ git commit
    $ git push
    

有关更多详细信息,请参阅SubGit 文档

于 2012-06-25T10:48:45.470 回答
2

为了添加对我有帮助的 vjangus 的回答,我还发现添加使用 git 移植在适当的点将分支连接到主干很有用 - 允许 git 查看历史记录并正确执行合并。

.git/info/grafts这只是在散列中添加一行的简单情况:

<initial branch commit> <parent commit in trunk>

例如。

378b0ae0902f5c2d2ba230c429a47698810532e5 6c7144991381ce347d4e563e9912465700be0638

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

(我会将其添加为评论,但我没有足够的声誉。)

于 2014-02-17T12:30:58.873 回答
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

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

于 2011-11-15T17:03:08.943 回答