【问题标题】:What is the correct way to convert SVN remote branches and tags into local Git branches/tags during SVN to Git migration在 SVN 到 Git 迁移期间将 SVN 远程分支和标签转换为本地 Git 分支/标签的正确方法是什么
【发布时间】:2010-07-08 17:40:15
【问题描述】:

在将 git-svn init/git-svn fetch 到本地 Git 分支/标签中,然后推送到我的远程 Git 存储库并完全放弃 SVN 之前,正确的方法是什么。

我有:

  • 运行git svn init
  • 将我的 .git/config 文件的 svn-remote "svn" 部分更新为以下内容:

    url = file:///Users/Developers/git_transition/svn_repo
    fetch = cascade/trunk:refs/remotes/svn/trunk
    branches = cascade/branches/{5.0GA_CLEANUP,drag-n-drop-def-builder,help-text,hib-annotations,hibernate-annotations,image-editor,ldapconfig,liquibase,move-rename-prototype,progress-bar,progress-bar2,quartz-upgrade,recyclebin,rendering_metrics,shuttle_upgrade,spring3,web-services-no-nuller}:refs/remotes/svn/*
    branches = cascade/branches/{6.x,5.x,4.x,3.x,archive}/*:refs/remotes/svn/*
    tags = cascade/tags/{3.7.x,4.x,5.x,6.x,old-releases}/*:refs/remotes/svn/tags/*
    
  • 运行git svn fetch

git-svn clone 是否会做一些超出 init/fetch 的操作,将这些分支/标签转换为本地分支/标签?

我尝试了advice on Pro Git,但 .git/refs/remotes/svn/ 目录中除了空的 6.x、5.x、4.x、3.x、标签和存档目录之外什么都没有。我确实通过git branch -r 验证了远程分支是否存在。

有人建议我需要系统地将所有远程分支检查为本地分支:git checkout -b <local_branch_name> <svn_remote_branch_name>,但我在任何地方都没有得到明确的答案。

已经能够使用此脚本转换标签:

git for-each-ref --format="%(refname)" refs/remotes/svn/tags/6.x |
grep -v @ | while read tag; do GIT_COMMITTER_DATE="$(git log -1
--pretty=format:"%ad" "$tag")" GIT_COMMITTER_EMAIL="$(git log -1
--pretty=format:"%ce" "$tag")" GIT_COMMITTER_NAME="$(git log -1
--pretty=format:"%cn" "$tag")" git tag -m "$(git log -1
--pretty=format:"%s%n%b" "$tag")" ${tag#refs/remotes/svn/tags/6.x/}
"$tag"; done

每个标签文件夹。

【问题讨论】:

    标签: git git-svn


    【解决方案1】:

    要做到这一点,只需使用SubGit 项目。您可以将其安装到您的 SVN 存储库中。这样就创建了一个链接的 Git 存储库(将 SVN 标签转换为 Git 标签,将 svn:ignores 转换为 .gitignore 等等)。该 Git 存储库与 SVN 存储库保持同步:当您推送到 Git 存储库时,此更改将转换为 SVN 存储库,反之亦然。

    如果您需要仅限客户端的解决方案,我建议您使用SmartGit。它还在 Git 存储库中保留了 SVN 概念。

    我不建议你使用 git-svn。

    【讨论】:

    • SubGit 不是免费的,你没有提到它。
    • @Onlyjob SubGit 可以免费进行一次性转换,据我所知,这个问题就是这种情况。只有使用 git-svn 镜像模式,同时启用 SVN 和 Git 访问时,才需要为 SubGit 付费。所以我认为德米特里在这方面的回答很好。
    • 我的意思是许可证,见The Free Software Definition
    【解决方案2】:

    根据 Git 邮件列表上的答案,我不需要将这些分支转换为本地分支,然后再将它们推送到我的远程仓库。我只需要这样做:

    git push <remote_git_repo_name> svn/<branch-name>:refs/heads/<branch-name>
    

    【讨论】:

      【解决方案3】:

      对于像这样的一次性操作,在留下 SVN 存储库之前,我喜欢使用 ruby​​ 脚本克隆它svn2git

      === 示例

      假设我在 svn 中有这段代码:

        trunk
          ...
        branches
          1.x
          2.x
        tags
          1.0.0
          1.0.1
          1.0.2
          1.1.0
          2.0.0
      

      git-svn 将通过提交历史来构建一个新的 git repo。
      它将导入所有分支和标签作为远程 svn 分支,而你真正想要的是git-native 本地分支和 git 标签对象。
      所以导入这个项目后我会得到:

        $ git branch
        * master
        $ git branch -a
        * master
          1.x
          2.x
          tags/1.0.0
          tags/1.0.1
          tags/1.0.2
          tags/1.1.0
          tags/2.0.0
          trunk
        $ git tag -l
        [ empty ]
      

      svn2git 完成您的项目后,您会得到这个:

        $ git branch
        * master
          1.x
          2.x
        $ git tag -l
          1.0.0
          1.0.1
          1.0.2
          1.1.0
          2.0.0
      

      【讨论】:

      • 谢谢,我查看了 svn2git,但没有找到一种简单的方法来配置它以在我在配置中提到的所有地方查找分支/标签。 svn2git 使用哪些底层命令将远程分支变为本地分支?
      • @Bradley:运行该脚本后,任何远程 svn 分支都将创建为本地 Git 分支。这个想法不是使用“git-svn”克隆,而是制作一个 new Git repo,通过脚本克隆 svn repo。将您当前的 Git 存储库(来自 git-svn 克隆)放在一边。
      • 我能否在运行脚本时指定 .git/config 文件中提到的 SVN 存储库中的各种分支/标记位置。
      【解决方案4】:

      git svn 转换后,没有简单/直接的方法可以将 SVN 标签分支转换为原生 git 标签。有许多脚本可以转换 SVN 标记,但其中大多数只是标记并删除“master”分支之外的相应分支,因此即使“master”的提交与标记的。

      为了解决这个问题,我最终编写了自己的实用程序“git-svn-convert-tags”,它在“master”分支中查找和标记与 SVN“tags”相同的提交。逻辑很简单:实用程序将当前分支(例如“master”)中的所有提交与标签分支的 HEAD 进行比较。当发现二进制相同的提交时,分配新标签并删除 SVN 标签分支。使用这种方法,我成功地将许多 git-svn 导入存储库中的标签转换为完美的 git 标签布局。

      【讨论】:

      • 实际上您可以使用 svn2git --rebase 主动将 SVN 存储库镜像到具有等效分支/标签的 GIT 存储库。我一直以这种方式使用脚本,效果很好。
      • 您必须确保用于 git svn init/clone 的 --prefix 选项是“svn/”,因为这是 svn2git 脚本本身使用的。如果您克隆时没有前缀,则使用的默认前缀将是“origin/”,这需要一次性转换。有关进行此转换的脚本,请参阅此 gist
      【解决方案5】:

      这是一个关于如何将这些分支引用之一转换为标签的示例:

      # rename the branch reference
      git branch -t rel_20101019 remotes/svn/tags/rel_20101019
      
      # checkout the branch
      git checkout rel_20101019
      
      # create the tag for it
      git tag rel_20101019
      
      # go back to master
      git checkout master
      
      # delete the branch
      git branch rel_20101019 –d
      
      # now you can push your branch and tag changes to your origin
      git push origin –all
      git push origin –tags
      

      【讨论】:

        猜你喜欢
        • 2012-10-19
        • 1970-01-01
        • 2017-04-08
        • 1970-01-01
        • 2012-01-08
        • 1970-01-01
        • 2016-08-18
        • 2021-10-06
        • 2021-04-17
        相关资源
        最近更新 更多