我阅读了Git手册、常见问题解答、Git-SVN速成课程等,他们都解释了这一点和那一点,但你找不到像这样的简单说明:

SVN存储库位于:svn://myserver/path/to/svn/repos

Git存储库位于:git://myserver/path/to/git/repos

git-do-the-magic-svn-import-with-history \
svn://myserver/path/to/svn/repos \
git://myserver/path/to/git/repos

我不希望它这么简单,也不希望它是一个命令。但我确实希望它不要试图解释任何事情——只是说在这个例子中应该采取什么步骤。


当前回答

我已经发布了一个将svn转换为git的分步指南(这里),包括将svn标记转换成git标记,将svn分支转换成git分支。

简短版本:

1) 从特定版本号克隆svn。(修订号必须是要移植的最旧版本)

git svn clone --username=yourSvnUsername -T trunk_subdir -t tags_subdir -b branches_subdir -r aRevisionNumber svn_url gitreponame

2) 获取svn数据。这一步是最耗时的一步。

cd gitreponame
git svn fetch

重复git-svn获取,直到无错误完成

3) 更新主分支

git svn rebase

4) 通过复制引用从svn分支创建本地分支

cp .git/refs/remotes/origin/* .git/refs/heads/

5) 将svn标记转换为git标记

git for-each-ref refs/remotes/origin/tags | sed 's#^.*\([[:xdigit:]]\{40\}\).*refs/remotes/origin/tags/\(.*\)$#\2 \1#g' | while read p; do git tag -m "tag from svn" $p; done

6) 将存储库放在更好的地方,如github

git remotes add newrepo git@github.com:aUser/aProjectName.git
git push newrepo refs/heads/*
git push --tags newrepo

如果你想了解更多细节,请阅读我的帖子或询问我。

其他回答

创建一个用户文件(即users.txt),用于将SVN用户映射到Git:

user1 = First Last Name <email@address.com>
user2 = First Last Name <email@address.com>
...

您可以使用这一行程序从现有SVN存储库构建模板:

svn log -q | awk -F '|' '/^r/ {gsub(/ /, "", $2); sub(" $", "", $2); print $2" = "$2" <"$2">"}' | sort -u > users.txt

如果SVN找到丢失的SVN用户(而不是在文件中),它将停止。但在那之后,您可以更新文件并从您停止的地方恢复。

现在从存储库中提取SVN数据:

git svn clone --stdlayout --no-metadata --authors-file=users.txt svn://hostname/path dest_dir-tmp

该命令将在dest_dir-tmp中创建一个新的Git存储库,并开始拉动SVN存储库。请注意,“--stdlayout”标志表示您具有通用的“trunk/,branches/,tags/”SVN布局。如果您的布局不同,请熟悉--tags、--branches和--trunk选项(在一般的git-svn帮助中)。

允许使用所有通用协议:svn://、http://、https://。URL应该以基本存储库为目标,例如http://svn.mycompany.com/myrepo/repository.URL字符串不能包含/trank、/tag或/branches。

请注意,在执行此命令后,操作通常看起来像是“挂起/冻结”,并且在初始化新存储库后,它可能会被卡住很长一段时间,这很正常。最终,您将看到指示它正在迁移的日志消息。

还要注意,如果省略--no元数据标志,Git将在提交消息中附加有关相应SVN修订的信息(即Git-SVN-id:svn://svn.mycompany.com/myrepo/<branchname/trank>@<RevisionNumber><RepositoryUUID>)

如果找不到用户名,请更新users.txt文件,然后:

cd dest_dir-tmp
git svn fetch

如果您有一个大型项目,则可能需要重复最后一个命令几次,直到获取所有Subversion提交:

git svn fetch

完成后,Git将把SVN主干签出到一个新的分支中。任何其他分支都设置为远程。您可以通过以下方式查看其他SVN分支:

git branch -r

如果要在存储库中保留其他远程分支,则需要手动为每个远程分支创建一个本地分支。(跳过trunk/master。)如果不这样做,分支将不会在最后一步中被克隆。

git checkout -b local_branch remote_branch
# It's OK if local_branch and remote_branch are the same names

标记作为分支导入。您必须创建一个本地分支,创建一个标记并删除该分支,以便在Git中将它们作为标记。要使用标记“v1”:

git checkout -b tag_v1 remotes/tags/v1
git checkout master
git tag v1 tag_v1
git branch -D tag_v1

将GIT-SVN存储库克隆到干净的GIT存储库中:

git clone dest_dir-tmp dest_dir
rm -rf dest_dir-tmp
cd dest_dir

以前从远程分支创建的本地分支将仅作为远程分支复制到新克隆的存储库中。(跳过主干/主干。)对于要保留的每个分支:

git checkout -b local_branch origin/remote_branch

最后,从干净的Git存储库中删除指向现已删除的临时存储库的远程:

git remote rm origin

这里的几个答案涉及https://github.com/nirvdrum/svn2git,但对于大型存储库,这可能会很慢。我试过使用https://github.com/svn-all-fast-export/svn2git相反,它是一个同名的工具,但用于将KDE从SVN迁移到Git。

设置它的工作稍微多了一些,但当为我完成转换时,其他脚本花费了数小时的时间。

GitHub现在具有从SVN存储库导入的功能。但我从未尝试过。

我强烈推荐我刚刚发现的这一系列短片。作者将指导您完成基本操作,并展示一些更高级的用法。

我建议在尝试经常使用Git-svn之前,先熟悉Git,即保持svn作为集中存储库并在本地使用Git。

然而,对于具有所有历史记录的简单迁移,以下是几个简单步骤:

初始化本地回购:

mkdir project
cd project
git svn init http://svn.url

标记要开始导入修订的时间:

git svn fetch -r42

(或仅对所有版本使用“gitsvn-fetch”)

事实上,从那时起,获取一切:

git svn rebase

您可以使用Gitk检查导入的结果。我不确定这是否适用于Windows,但适用于OSX和Linux:

gitk

当您在本地克隆了SVN repo后,您可能希望将其推送到集中的Git repo,以便于协作。

首先创建空的远程存储库(可能在GitHub上?):

git remote add origin git@github.com:user/project-name.git

然后,可选地同步您的主分支,这样当远程主机和本地主机都包含新内容时,拉操作将自动合并远程主机:

git config branch.master.remote origin
git config branch.master.merge refs/heads/master

之后,您可能会有兴趣尝试我自己的git_remote_branch工具,它有助于处理远程分支:

第一篇解释文章:“Git远程分支”

跟进最新版本:“git与git_remote_branch协作的时间”