首先,感谢@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,您可能需要禁用或调整初始推送的设置。