![](/img/trans.png)
[英]git-svn: branch renamed in svn repository, how do I tell git-svn?
[英]How do I tell git-svn about a remote branch created after I fetched the repo?
我正在使用git-svn
来处理我公司的中央 Subversion 存储库。 我们最近在中央仓库中创建了一个新的功能分支。
我如何告诉 Git 呢? 当我运行git branch -r
我只能看到当我对 Subversion 存储库运行fetch
以初始化我的 Git 存储库时存在的分支?
您可以手动添加远程分支,
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
如果要跟踪所有远程 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 远程分支。
看来我只需要git svn fetch
; 不知何故,我说服自己将获取整个 repo 而不仅仅是更改。
也许我以某种方式把它搞砸了,但我按照 vjangus 的回答中的说明进行了操作,它几乎奏效了。 唯一的问题是 newbranch 似乎没有从主干中分支出来。 在 gitk 中,它完全靠自己“浮动”; 它与树干没有共同的祖先。
对此的解决方案是:
git diff-tree <sha1 from step 1> <sha1 from step 2>
- 应该没有输出。 如果有输出,您可能选择了错误的提交。git checkout local-newbranch
然后git rebase <sha1 from step 1>
。 这会将local-newbranch
到新树上,但remotes/newbranch
仍将断开连接。.git/refs/remotes/newbranch
并编辑它以包含与当前指向的旧提交相对应的新提交的完整 SHA1(在重新设置的newbranch
)。 (或者也许使用git-update-ref refs/remotes/newbranch <new-SHA>
。谢谢你。)git svn dcommit
到newbranch
,你会收到一堆关于它更新日志的消息。 我觉得这很正常。 我建议保持gitk --all
打开并经常刷新它以跟踪你在做什么。 我对 git 和 git svn 还是个新手,所以请建议改进这个方法。
vjangus 答案的简化:
如果您在 SVN 中使用标准布局并完成了通常的 svn init,git-svn 将为您完成配置。 只是:
一个例子。 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'
我还没有找到关于此功能的任何文档,但看起来 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
您可以尝试SubGit ,而不是处理 git-svn 怪癖。
必须将 SubGit 安装到 Subversion 存储库中。 之后就可以使用标准的 git 工作流程而不是使用特殊的 git-svn 命令:
推送新提交:
git-svn:
$ git commit $ git svn rebase $ git svn dcommit
子Git:
$ git commit $ git push
获取传入的更改
git-svn:
$ git svn rebase
子Git:
$ git pull [--rebase]
创建一个新分支:
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 文档。
为了添加对我有帮助的 vjangus 的答案,我还发现添加 use gitrafts 以在适当的点将分支连接到主干很有用 - 允许 git 查看历史记录并正确执行合并。
这只是在.git/info/grafts
中添加一行带有哈希值的情况:
<initial branch commit> <parent commit in trunk>
例如。
378b0ae0902f5c2d2ba230c429a47698810532e5 6c7144991381ce347d4e563e9912465700be0638
归功于http://evan-tech.livejournal.com/255341.html
(我将此添加为评论,但我没有足够的声誉。)
如果您不使用有效布局签出,您将无法签出远程分支。
这就是我所做的:
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
然后您将自动切换到您的分支。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.