克隆git-svn中的主干之后克隆分支的最佳方式是什么? [英] What is the best way to clone branches after cloning just trunk in git-svn?

查看:373
本文介绍了克隆git-svn中的主干之后克隆分支的最佳方式是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定一个包含很多分支的大型Subversion版本库,我想通过克隆 trunk 来开始使用 git-svn 并在稍后添加特定分支。我看到至少有三种方法可以做到这一点,但是它们中的任何一个都是官方的还是有最好的方法?



假设以下布局:

  https://svn-repo.com/svn/company 
+ - 核心
| + - 后备箱
| + - 分支
| | + - fastboot
| | + - 游乐场
| + -tags
+ - mobile
+ - trunk
+ - branches
+ - tags
$ b $ p因此,只克隆项目核心的主干(不分支)版本12345:

  $ git svn clone --username = svnuser -r 12345 -Ttrunk https://svn-repo.com/svn/company/core 

这会将项目 core 克隆到相同的目录中名称并运行 git svn rebase 将引入所有更改(修订版本12345后)。在这一点上 .git / config 应该有这样的内容:

  [svn-remotesvn] 
url = https://svn-repo.com/svn/company
fetch = core / trunk:refs / remotes / trunk

到目前为止这么好。现在,假设我想添加操场分支。这是它有点模糊的地方。






选项1 :更新现有的遥控器 .git / config 加入分支:

  [svn-远程svn] 
url = https://svn-repo.com/svn/company
fetch = core / trunk:refs / remotes / trunk
branches = core / branches / { }}:refs / remotes / branches / *

此时,我能够做到:


  1. 在分支操场



    $ git svn fetch -r 23456


  2. 分支并切换到它



    $ git checkout -b操作分支/操场


  3. 引入最新变化:
    $ b $ p $ git svn rebase

    选项2 :添加新的远程在 .git / config 中(除了现有的):

      [svn-remoteplayground] 
    url = https://svn-repo.com/svn/company
    fetch = core / branches / playground:refs / remotes / playground

    从这里开始,步骤与选项1

      $ git svn fetch playground -r 23456 
    $ git checkout - b操场遥控器/操场
    $ git svn rebase






    :选项3 :我也看到有人在现有的远程中添加新的抓取:

      [svn-remotesvn] 
    url = https://svn-repo.com/svn/company
    fetch = core / trunk:refs / remotes / trunk
    fetch = core / branches / playground:refs / remotes / branches / playground

    我不完全确定这是否正确或如果它甚至会工作。我找不到我在哪里看到。






    目前,我坚持使用 Option 1 ,但我真的很想知道做到这一点的最合适的方法。

你注意到的所有选项都是有效的,并且没有一个规范的方式来做到这一点,部分原因在于(从 git svn 的角度),没有一种规范的方式来布置Subversion存储库。

您选择的选项1和3基本上相同。就个人而言,我会选择3,但结果将与您的选项1相同。



选项2可以工作,但它会阻止Git检测提交历史记录跨越分支--Git通常会尝试检测合并或创建分支的Subversion提交,并在Git提交中记录这些提交,但如果将两个分支视为完全独立的存储库,则不能这样做。



也就是说,只是在以后的日子里增加新的分支机构,你已经失去了很多历史。考虑以下流程:


  • 您的Git存储库仅包含 git svn
  • 有人从trunk中创建操作系统分支,在该分支中进行一些提交,然后将操场合并到主干中。
  • 使用 git svn 获取主干;它看到合并,但对操作系统分支一无所知,将它作为常规提交添加到Git存储库中。
  • d一直在捡起操场分支,Git会检测到分支并合并,并记录下来。事后添加游戏分支将无济于事,除非使用 git svn reset 来重新提取所有提交,因为 git svn 不会重写旧的提交以记录合并。

    我所做的是直接克隆所有分支,如Chronial在注释中所建议的。这是一个缓慢的过程(我已经完成了100,000个提交Subversion版本库,包含近300个分支和标签),可能需要几天时间才能完成,但您可以将其保留在后台,并且完成后有完整的Subversion历史记录。


    Given a large Subversion repository with many branches, I want to start using git-svn by cloning trunk first and adding specific branches later. I saw at least three ways to do this, but are any of them "official" or is there a best way?

    Assume the following layout:

    https://svn-repo.com/svn/company
       +--core
       |  +--trunk
       |  +--branches
       |  |  +--fastboot
       |  |  +--playground
       |  +-tags
       +--mobile
          +--trunk
          +--branches
          +--tags
    

    So, to clone only the trunk (no branches) revision 12345 of project core:

    $ git svn clone --username=svnuser -r 12345 -Ttrunk https://svn-repo.com/svn/company/core
    

    This will clone project core into a directory of the same name and running git svn rebase will pull in all the changes (after revision 12345). At this point .git/config should have something like this in it:

    [svn-remote "svn"]
      url = https://svn-repo.com/svn/company
      fetch = core/trunk:refs/remotes/trunk
    

    So far so good. Now, let's say I want to add the playground branch. This is where it gets a bit hazy.


    Option 1: Update the existing remote in .git/config by adding the branch there:

    [svn-remote "svn"]
      url = https://svn-repo.com/svn/company
      fetch = core/trunk:refs/remotes/trunk
      branches = core/branches/{playground}:refs/remotes/branches/*
    

    At this point, I was able to do:

    1. Pull in revision 23456 of branch playground

      $ git svn fetch -r 23456

    2. Create a local branch and switch to it

      $ git checkout -b playground branches/playground

    3. Pull in the latest changes:

      $ git svn rebase


    Option 2: Add a new remote in .git/config (in addition to the existing one):

    [svn-remote "playground"]
      url = https://svn-repo.com/svn/company
      fetch = core/branches/playground:refs/remotes/playground
    

    From here, the steps are similar to the ones from Option 1:

    $ git svn fetch playground -r 23456
    $ git checkout -b playground remotes/playground
    $ git svn rebase
    


    Option 3: I've also seen someone add a new fetch in the existing remote:

    [svn-remote "svn"]
      url = https://svn-repo.com/svn/company
      fetch = core/trunk:refs/remotes/trunk
      fetch = core/branches/playground:refs/remotes/branches/playground
    

    I'm not completely certain if that's correct or if it will even work. I can't find where I saw that.


    Currently, I'm sticking with Option 1, but I would really like to know the most appropriate way to do this.

    解决方案

    All the options you note are valid, and there's no one "canonical" way to do this, partly because (from git svn's point of view) there's no one canonical way of laying out a Subversion repository.

    Options 1 and 3 that you've picked out are essentially equivalent. Personally, I'd have gone with option 3, but the result will be identical to your option 1.

    Option 2 would work, but it would prevent Git detecting commit history that crosses branches – Git will normally try to detect Subversion commits that merge or create branches, and record those as such in the Git commits, but it can't do that if it's treating the two branches as entirely separate repositories.

    That said, by only adding the new branches at a later date, you're losing a lot of history already. Consider the following flow:

    • Your Git repository only contains git svn fetches of trunk.
    • Someone creates the playground branch from trunk, makes some commits in that branch, then merges playground to trunk.
    • You use git svn to fetch trunk; it sees the merge, but knowing nothing about the playground branch, adds it to the Git repository as a regular commit.

    If you'd been picking up the playground branch all along, Git would have detected the branch and merge, and recorded them as such. Adding the playground branch afterwards won't help, unless you use git svn reset to re-fetch all the commits, because git svn won't rewrite the old commits to note the merge.

    What I've done is to clone all the branches straight away, as Chronial suggested in the comments. It's a slow process (I've done this with a 100,000 commit Subversion repository with almost 300 branches and tags) that may take a few days to complete, but you can just leave it going in the background, and when it's done you'll have the complete Subversion history.

    这篇关于克隆git-svn中的主干之后克隆分支的最佳方式是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆