我阅读了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

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


当前回答

从Subversion到Git(或同时使用两者)的平滑迁移有一个新的解决方案:SubGit。

我自己在做这个项目。我们在我们的存储库中使用SubGit——我的一些队友使用Git和一些Subversion,到目前为止它工作得很好。

要使用SubGit从Subversion迁移到Git,您需要运行:

$ subgit install svn_repos
...
TRANSLATION SUCCESSFUL 

之后,您将获得svn_repos/.Git中的Git存储库,并可以克隆它,或者继续使用Subversion和这个新的Git库:SubGit将确保两者始终保持同步。

如果Subversion存储库包含多个项目,那么将在svn_repo/Git目录中创建多个Git存储库。要在运行翻译之前自定义翻译,请执行以下操作:

$ subgit configure svn_repos
$ edit svn_repos/conf/subgit.conf (change mapping, add authors mapping, etc)
$ subgit install svn_repos

使用SubGit,您可以迁移到纯Git(而不是Git-svn)并开始使用它,同时只要您需要它,就可以保留Subversion(例如,对于您已经配置的构建工具)。

希望这有帮助!

其他回答

将Subversion存储库干净地迁移到Git存储库。首先,您必须创建一个将Subversion提交作者名称映射到Git commiters的文件,比如~/authors.txt:

jmaddox = Jon Maddox <jon@gmail.com>
bigpappa = Brian Biggs <bigpappa@gmail.com>

然后您可以将Subversion数据下载到Git存储库中:

mkdir repo && cd repo
git svn init http://subversion/repo --no-metadata
git config svn.authorsfile ~/authors.txt
git svn fetch

如果您在Mac上,可以通过安装git-core+svn从MacPorts获取git-svn。

如果您的subversion存储库与所需的git存储库位于同一台机器上,那么您可以在init步骤中使用此语法,否则都一样:

git svn init file:///home/user/repoName --no-metadata

将svn子模块/文件夹“MyModule”转换为具有历史记录的git,既没有标记也没有分支。

git-svn clone--无元数据--trunk=SomeFolder1/SomeFolder2/SomeFolder3/MyModulehttp://svnhost:port/repo_root_folder/MyModule_temp-一个C: \ccheetah\svn\authors-transform.txtgit克隆MyModule_temp MyModulecd我的模块git流初始化git远程设置url源https://userid@stashhost/stash/scm/xyzxyz/MyModule.gitgit push-u原始主机gitpush-u源代码开发

要保留svn忽略列表,请在步骤1之后使用以上注释

首先,感谢@cmginty的回答。对我来说,这是一个很好的起点,我将在这里发布的很多内容都借鉴了它。然而,我正在移动的回购已经有多年的历史,这导致了信件回复后出现了一些问题(需要手动移动数百个分支和标签,稍后阅读更多内容)。

因此,经过数小时的搜索和反复尝试,我能够编写一个脚本,使我能够轻松地将几个项目从SVN转移到GIT,我决定在这里分享我的发现,以防其他人也站在我的立场上。

<tl;我们开始吧


首先,创建一个“作者”文件,将基本svn用户转换为更复杂的git用户。最简单的方法是使用命令从要移动的svn repo中提取所有用户。

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

这将生成一个名为authors-transform.txt的文件,其中包含对运行该文件的svn repo进行更改的每个用户的一行。

someuser = someuser <someuser>

更新以包括git的全名和电子邮件

someuser = Some User <someuser@somewhere.com>

现在使用authors文件启动克隆

git svn clone --stdlayout --no-metadata -r854:HEAD --authors-file=authors-transform.txt https://somesvnserver/somerepo/ temp

--stdlayout表示svn repo遵循标准/主干/分支/标签布局--no-metadata告诉git不要在每次git提交时标记与svn提交相关的元数据。如果这不是单向转换,请删除此标记-r854:HEAD仅从854修订版获取历史记录。这是我遇到的第一个障碍;我正在转换的回购在853版本中有一个“损坏”的提交,因此它不会克隆。使用此参数,您只能克隆部分历史记录。temp是要创建以初始化的目录的名称新的git回购

这一步骤可能需要一段时间,特别是在大型或旧回购协议中(我们的一个回购协议大约需要18小时)。您还可以使用-r开关只获取一个小的历史记录来查看克隆,然后再获取其余的历史记录。

移动到新目录

cd temp

如果只在克隆中提取了部分历史记录,则获取任何缺失的历史记录

git svn fetch

标记在克隆期间创建为分支。如果你只有几个,你可以一次转换一个。

git 1.0.0 origin/tags/1.0.0

然而,如果你有数百个标签,这是很乏味的,所以下面的脚本对我很有用。

for brname in `git branch -r | grep tags | awk '{gsub(/^[^\/]+\//,"",$1); print $1}'`; do echo $brname; tname=${brname:5}; echo $tname; git tag $tname origin/tags/$tname; done

您还需要签出所有要保留的分支

git checkout -b branchname origin/branches/branchname

如果你也有很多分支,这个脚本可能会有所帮助

for brname in `git branch -r | grep -v master | grep -v HEAD | grep -v trunk | grep -v tags | awk '{gsub(/^[^\/]+\//,"",$1); print $1}'`; do echo $brname; git checkout -b $brname origin/$brname; done

这将忽略主干分支,因为它已经作为主分支签出,并保存一个步骤,稍后删除重复的分支,以及忽略我们已经转换的/标记。

现在是查看新回购的好时机,并确保您有一个本地分支或标记,可以保存任何您想保留的内容,因为远程分支将在片刻后删除。

好的,现在让我们将我们签出的所有内容克隆到一个干净的repo(此处名为temp2)

cd ..
git clone temp temp2
cd temp2

现在,我们需要再次检查所有分支,然后再将它们推到最后的远程位置,所以请按照上面您最喜欢的方法操作。

如果您正在使用gitflow,您可以重命名工作分支以进行开发。

git checkout -b WORKING
git branch -m develop
git push origin --delete WORKING
git push origin -u develop

现在,如果一切看起来都很好,就可以将其推送到git存储库了

git remote set-url origin https://somebitbucketserver/somerepo.git
git push -u origin --all
git push origin --tags

我确实遇到了最后一个问题,那就是Control Freak最初阻止我推送我没有创建的标签,所以如果您的团队使用Control Freak,您可能需要禁用或调整初始推送的设置。

魔法:

$ git svn clone http://svn/repo/here/trunk

Git和SVN的操作非常不同。你需要学习Git,如果你想跟踪SVN上游的变化,你需要学习Git-SVN。git-svn主页有一个很好的示例部分:

$ git svn --help

我建议在尝试经常使用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协作的时间”