在SVN到Git迁移期间,将SVN远程分支和标记转换为本地Git分支/标记的正确方法是什么

时间:2010-07-08 17:40:16

标签: git git-svn

在推送到我的远程Git仓库并完全放弃SVN之前,将git-svn init / git-svn提取到本地Git分支/标签之后使远程分支/标记存在的正确方法是什么?

我有:

  • 运行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,但除了空的6.x,5.x,4.x,3.x,标签和存档外,.git / refs / remotes / svn /目录中没有任何内容目录。我确实用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

为每个标签文件夹。

5 个答案:

答案 0 :(得分: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

答案 1 :(得分:3)

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

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

答案 2 :(得分:1)

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

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

我不建议你使用它git-svn。

答案 3 :(得分:1)

git svn转换后,没有简单/直接的方法将SVN标记分支转换为本机git标记。有许多脚本可以转换SVN标签,但大多数只是标记 - 并且 - 删除“master”分支之外的相应分支,因此即使“master”具有相同的提交,新标记也不会出现在提交历史中标记的那些。

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

答案 4 :(得分:0)

这是关于如何将其中一个分支引用转换为标记的示例:

# 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