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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/296975/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 05:58:05  来源:igfitidea点击:

How do I tell git-svn about a remote branch created after I fetched the repo?

gitgit-svn

提问by Hank Gay

I'm using git-svnto work against my company's central Subversion repository. We've recently created a new feature branch in the central repo.

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

How do I tell Git about it? When I run git branch -rI can only see the branches that existed when I ran fetchagainst the Subversion repo to initialize my Git repo?

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

回答by vjangus

You can manually add the remote branch,

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

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

回答by janos

If you want to track ALL the remote svn branches, then the solution is as simple as:

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

git svn fetch

This will fetch ALL the remote branches that have not been fetched yet.

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

Extra tip: if you checked out only the trunk at first, and later you want to track ALL branches, then edit .git/configto look like this and re-run 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/*

The key points are urlshould point to the repository root, and the paths defined in fetchand branchesshould be relative to url.

关键点是url应该指向存储库根目录,并且在fetch和 中定义的路径branches应该是相对于url.

If you want to fetch only specific branches instead of ALL, there is a nice example in git svn --help:

如果你只想获取特定的分支而不是 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/*

With older versions of git-svn, once you specified branches like this, you might not be able to get new branches with git svn fetch. One workaround is adding more fetchlines, like this:

对于旧版本的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/*

Another workaround by @AndyEstes: edit .git/svn/.metadataand change the value of branches-maxRevor tags-maxRevto a revision before any newly-specified branches or tags were created. Once you've done this, run git svn fetchto track the new svn remote branch.

另一种解决方法由@AndyEstes:编辑.git/svn/.metadata和改变的值branches-maxRev或者tags-maxRev任何新指定的分支或标签之前修订创建。完成此操作后,运行git svn fetch以跟踪新的 svn 远程分支。

回答by Hank Gay

It appears I just needed to git svn fetch; somehow I had convinced myself that would fetch the entire repo instead of just the changes.

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

回答by MatrixFrog

Maybe I messed it up somehow but I followed the instructions in vjangus' answer and it almostworked. The only problem was that newbranch didn't appear to be branched from the trunk. In gitk, it was kind of "floating" all on its own; it had no common ancestor with the trunk.

也许我以某种方式把它搞砸了,但我按照 vjangus 的回答中的说明进行了操作,它几乎奏效了。唯一的问题是 newbranch 似乎没有从主干中分支出来。在 gitk 中,它完全靠自己“浮动”;它与树干没有共同的祖先。

The solution to this was:

对此的解决方案是:

  1. Find the SHA1 of the last commit that happened on trunk before the branch was created.
  2. Find the SHA1 of the first commit on the new branch (message is probably "Created new branch, copied from trunk@12345" or something)
  3. git diff-tree <sha1 from step 1> <sha1 from step 2>-- there should be no output. If there is output, you may have selected the wrong commits.
  4. git checkout local-newbranchthen git rebase <sha1 from step 1>. This will rebase local-newbranchonto the new tree but remotes/newbranchwill still be disconnected.
  5. Go to the file .git/refs/remotes/newbranchand edit it to contain the full SHA1 of the newcommit (on the rebased newbranch) that corresponds to the old commit it's currently pointing at. (Or maybe use git-update-ref refs/remotes/newbranch <new-SHA>. Thank you inger.)
  6. The next time you git svn dcommitto newbranch, you'll get a bunch of messages about it updating some log. This is normal I think.
  1. 查找在创建分支之前在主干上发生的最后一次提交的 SHA1。
  2. 在新分支上找到第一次提交的 SHA1(消息可能是“创建新分支,从主干@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并编辑它以包含与当前指向的旧提交相对应的提交(在 rebased 上newbranch)的完整 SHA1 。(或者也许使用git-update-ref refs/remotes/newbranch <new-SHA>。谢谢inger。)
  6. 下次你git svn dcommitnewbranch,你会收到一堆关于它更新一些日志的消息。我觉得这很正常。

I recommend keeping gitk --allopen the whole time and refreshing it often to keep track of what you're doing. I'm still sort of new to git and git svn so please suggest improvements to this method.

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

回答by Gil Hamilton

A simplification of vjangus' answer:

vjangus 答案的简化:

If you're using the standard layout in SVN and have done the usual svn init, git-svn will do the config stuff for you. Just:

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

  1. Find branch-copy revision in SVN
  2. Fetch that revision with git-svn
  3. Create new local branch tracking remote
  1. 在 SVN 中查找分支副本修订版
  2. 使用 git-svn 获取该修订版
  3. 创建新的本地分支跟踪远程

An example. SVN url is svn+ssh://[email protected]/repo. SVN branch I'm looking for is newbranch. Local git branch (tracking remote newbranch) will be git-newbranch.

一个例子。SVN 网址是svn+ssh://[email protected]/repo. 我正在寻找的 SVN 分支是newbranch. 本地 git 分支(跟踪远程newbranch)将是git-newbranch.

Step 1: find the branch-copy revision

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

    # svn log --stop-on-copy svn+ssh://[email protected]/repo/branches/newbranch | tail -4
    r7802 | someone | 2014-03-21 18:54:58 +0000 (Fri, 21 Mar 2014) | 1 line

    branching HEAD to newbranch
    ------------------------------------------------------------------------

So the branch point in SVN is revision 7802.

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

Step 2: Fetch the revision

第 2 步:获取修订版本

    # git svn fetch -r 7802
    Found possible branch point: svn+ssh://[email protected]/repo/trunk => svn+ssh://[email protected]/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 did all the work and now knows about the remote:

git-svn 完成了所有工作,现在知道远程:

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

Step 3: Create your new local branch tracking the remote one:

第 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'

回答by Mikael Lepist?

I have not found any documentation about this feature, but looks like git svn configuration supports multiple fetch entries. This way you can also add branches separately without need to add another remote svn repository entry to your config nor using wildcards to get all branches of certain directory.

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

Assume that your SVN tree is really nasty having lots of branches without any logic how they are located, e.g. having branches and sub-directories containing more branched.

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

i.e.

IE

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

and you just want to hand pick some of the branches to be included to your git repository.

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

You may first init your repository with only trunk without any additional branches:

您可以首先仅使用主干初始化您的存储库,而无需任何其他分支:

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

After that you should see following configuration:

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

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

when ever you want to fetch new branch from MyRepo you can just add new fetch entries to configuration by:

当您想从 MyRepo 获取新分支时,您可以通过以下方式向配置添加新的获取条目:

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

Or you may edit the same configuration in .git/config

或者你可以在 .git/config 中编辑相同的配置

To fetch the new branches after adding them to config just run:

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

git svn fetch -r 10000:HEAD

[Edit]Sometimes it seems to be necessary to run fetch with --all parameter to fetch newly added branches:

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

git svn fetch --all -r 10000:HEAD

回答by vadishev

Instead of dealing with the git-svn quirks you may try SubGit.

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

One has to install SubGit into Subversion repository. After that one can use standard git workflow instead of using special git-svn commands:

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

  1. Pushing new commits:

    git-svn:

    $ git commit
    $ git svn rebase
    $ git svn dcommit
    

    SubGit:

    $ git commit
    $ git push
    
  2. Fetching incoming changes

    git-svn:

    $ git svn rebase
    

    SubGit:

    $ git pull [--rebase]
    
  3. Creating a new branch:

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

See SubGit documentationfor more details.

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

回答by Haddon CD.

To add to vjangus' answer, which helped me, I also found it useful to add use git grafts to tie the branches to the trunk at the appropriate point - allowing git to see the history and perform merges correctly.

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

This is simply a case of adding a line to .git/info/graftswith the hashes:

这只是.git/info/grafts向散列添加一行的情况:

<initial branch commit> <parent commit in trunk>

eg.

例如。

378b0ae0902f5c2d2ba230c429a47698810532e5 6c7144991381ce347d4e563e9912465700be0638

Credit to http://evan-tech.livejournal.com/255341.html

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

(I'd add this as a comment, but I've not enough reputation.)

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

回答by MikeHoss

If you don't check out with a valid layout, you won't be able to checkout a remote branch.

如果您不使用有效布局签出,您将无法签出远程分支。

This is what I do:

这就是我所做的:

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

After that, you can switch to a remote branch:

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

git checkout --track -b branch_name branch_name

Then you will automatically be switched to your branch.

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