前言 {#前言}
进行代码仓库的迁移并非简单地创建 Git repo 把当前项目代码一次性 commit 过去就够了,因为 SVN 中存有长年累月的 commit 历史记录,丢失历史记录将对今后追溯 debug 造成非常大的麻烦,所以如何保留 commit 记录就是迁移的关键。
迁移步骤 {#迁移步骤}
创建用户映射 (例如 users.txt) ,将 SVN 用户和 Git 用户对应起来:
|---------------|-----------------------------------------------------------------------------------------------------|
| 1 2 3
| user1 = First Last Name <email@address.com> user2 = First Last Name <email@address.com> ...
|
如果上面的文件中有用户缺失,后面的 SVN 命令将会停止。不过你可以更新用户映射然后接着再来(类似断点续传)。
现在从 SVN 仓库中拉取所有数据:
|-----------|-----------------------------------------------------------------------------------------------|
| 1
| git svn clone --stdlayout --no-metadata -A users.txt svn://hostname/path dest_dir-tmp
|
这个命令将会在 dest_dir-tmp 新建一个 Git repo,并开始从 SVN 中拉取代码。请注意 "--stdlayout
" 参数表示你的项目在 SVN 中是常见的 "trunk/branches/tags
" 目录结构,如果不是,那你需要使用 --tags
, --branches
, --trunk
参数(请通过 git svn help 自行了解)。
再后面的参数是 SVN 的地址,一些常见协议都是支持的 : svn://
, http://
, https://
。 注意这个 URL 应该指向项目的 base repository,例如 http://svn.mycompany.com/myrepo/repository
. 不要指到了 /trunk
, /tag
或 /branches
里。
如果出现用户名没找到,更新你的 users.txt 文件,然后
|-------------|---------------------------------------|
| 1 2
| cd dest_dir-tmp git svn fetch
|
如果你的项目非常大,你可能需要重复上面的命令好几次,直到所有的 SVN commit 都被抓下来了:
|-----------|-----------------------|
| 1
| git svn fetch
|
完成后,Git 将会 checkout SVN 的 trunk 到一个新的 Git branch,而其他的 SVN branch 将会设为 Git remote,你可以查看所有的 SVN branch:
|-----------|-----------------------|
| 1
| git branch -r
|
如果你想在你的 Git repo 中保留其他的 remote branch,你需要手动创建本地 branch。否则,SVN 的 branch 将不会在最后被 clone。
|-------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8
| git checkout -b local_branch remote_branch # it's ok if local_branch and remote_branch are the same name SVN tags 被当作 branch 导入了,你需要创建本地 branch,打一个 tag,然后删掉那个 branch,这样才会在 Git 中生成 tag。例如 SVN tag "v1": git checkout -b tag_v1 remotes/tags/v1 git checkout master git tag v1 tag_v1 git branch -D tag_v1
|
把上面的 GIT-SVN repo Clone 到一个全新的干净 git repo:
|---------------|-------------------------------------------------------------------------|
| 1 2 3
| git clone dest_dir-tmp dest_dir rm -rf dest_dir-tmp cd dest_dir
|
之前从 remote branch 创建的本地 branch 又会在新 clone 的 repo 中成为 remote branch,于是对每个 branch 再做一次:
|-----------|-----------------------------------------------------------|
| 1
| git checkout -b local_branch origin/remote_branch
|
最后,从干净的 Git repo 中删掉 remote (指向我们刚刚已经删掉的 temp repo)
|-----------|------------------------------|
| 1
| git remote rm origin
|
这样一个全新 Git repo 就已经从 SVN 迁移好了。
完整的命令行操作 {#完整的命令行操作}
|------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| ##clone svn -> git 地址支持协议 : svn://, http://, https://. 注意这个 URL 应该指向项目的 base repository,例如 ##http://svn.mycompany.com/myrepo/repository. 不要指到了 /trunk, /tag 或 /branches 里。 git svn clone svn://10.68.245.11/tclshop --authors-file=users.txt --no-metadata -s dufy-move ##进入clone 的文件夹 cd dfuy-move ##使所有的 SVN commit 都被抓下来了 git svn fetch ##在git中查看svn commit记录信息 git log --pretty=oneline ##查看分支 -- svn tag的被解析为git分支 ,需转换一下 git branch -r ##转换分支-tag git tag tags_20160329_hg origin/tags/tags_20160329_hg ##删除远程的分支(tags) git branch -r -d origin/tags/tags_20160329_hg ##本地初始化git仓库完成 git remote add origin git@10.68.25.20:move/dufy-tclshop-test-two.git #推送到远端的git的仓库中 git push origin master --tags ##切换到分支 git checkout 16130_20151125_hg ##提交分支到远程的仓库中 git push origin 16130_20151125_hg
|