SVN 项目移植 Git
由于公司 SVN 服务不再维护,同时我没有项目的 SVN 管理权限,需将当前项目移植至 Git 上。
这类需求应该很普遍,Google 之,果然发现一条靠谱的答案:https://stackoverflow.com/a/3972103。
这里简单翻译下这篇文,加上本人的实践操作,做些笔记备忘。
提取人员信息
svn log -q \
| awk -F '|' '/^r/ {sub("^ ", "", $2); sub(" $", "", $2); print $2" = "$2" <"$2">"}' \
| sort -u > users.txt
拉取 SVN 记录
如果你的 SVN 仓库是标准结构(trunk/,branches/,tags/),
git svn clone \
--stdlayout \
--no-metadata \
--authors-file=users.txt \
https://hostname/path \
dest_dir-tmp/
否则需要另加参数(详细请看 git svn help
),
git svn clone --no-metadata \
--tags=tag \
--branches=branch \
--trunk=baseline \
--authors-file=users.txt \
https://hostname/path \
dest_dir-tmp/
PS: 如果去掉 --no-metadata
参数,Git 会把相应的 SVN revision 加入提交信息中。
(git-svn-id: svn://svn.mycompany.com/myrepo/<branchname/trunk>@<RevisionNumber> <Repository UUID>)
拉取过程可能比较漫长,需要耐心等待……
如果因为在 users.txt 中找不到相应用户而导致 SVN 停止,可以自己手动更新 users.txt,然后继续。
# In dest_dir-tmp
git svn fetch
分支、Tag 处理
完成后,Git 将 SVN 「trunk」检出作为新分支,而其他分支设置为远程分支。
可以通过以下命令查看:
git branch -r
检出分支
如果你想保存其他远程分支,你需要自己手动创建本地分支(排除 trunk/master)。
否则,最后一步无法 clone 到这些分支。
git checkout -b local_branch remote_branch
# It's OK if local_branch and remote_branch are the same name
检出 Tag
Tag 被当作分支导入。你需要创建一个本地分支,打 tag 然后删除该本地分支。
git checkout -b tag_v1 remotes/tags/v1
git checkout master
git tag v1 tag_v1
git branch -D tag_v1
懒 style
上面的操作一个个操作下来要爆炸,所以自己弄了点 shell 脚本。
执行相应脚本,只会打印相应操作。确保操作正确后,去掉脚本中的 echo
即可实际执行脚本。
另外,这里用的是 GNU 的 awk 和 sed。
# 检出所有远程分支,根据情况自己修改
git branch -rvv \
| awk -e '{print $1}' \
| sed -ne 'h;s!^origin/!!;p;g;p;' \
| xargs -n2 echo git checkout -b
# 执行上面脚本后,才能执行此脚本
# 给带 tag 的本地分支打标签,根据情况自己修改
git checkout master
git branch \
| grep tags \
| awk -e '{print $1}' \
| sed -ne 'h;s!^tags/!v!;p;g;p;' \
| xargs -n2 echo git tag
# 删除 tag 分支
git branch | grep tags | xargs git branch -D
干净的 Git 仓库
git clone dest_dir-tmp dest_dir
rm -rf dest_dir-tmp
cd dest_dir
前一步创建的本地分支在这里又变为远程分支,需要再来一遍(可以参考上一步骤):
git checkout -b local_branch origin/remote_branch
最后清除 remote,
git remote rm origin