我正在尝试使用svn2git将SVN项目迁移到git。但是我在保留所有历史方面遇到了问题。原因似乎是因为行李箱过去被移动了。我正在使用的命令是:
$ svn2git http://mysvnserver.com/myproject/iPhone/ --no-minimize-url --authors ../authors.txt
但这只能让我的历史可以追溯到2011年。该项目实际上始于2010年。预计开始时看起来像这样:
myproject
trunk
branches
tags
但在2011年,它改为:
myproject
iPhone
trunk
branches
tags
Android
trunk
branches
tags
旧的主干和分支机构都在iPhone目录下。我从这一举动完成后开始的历史。如果我在iPhone目录中svn log
,我会得到缩短的历史记录。但是,如果我cd trunk; svn log
,那么我将获得完整的历史记录。
我不知道如何将这段历史记录下来。我的想法是以某种方式创建一个git存储库,只有中继的历史可以追溯到2010年。然后我会把它作为我的主仓库中的一个分支拉出来,并做一个rebase来使历史正确。但我没有运气为主干创造这个回购。我试过了:
$ svn2git http://mysvnserver.com/myproject/ --rootistrunk --authors ../authors.txt
和
$ svn2git http://mysvnserver.com/myproject/ --rootistrunk -no-minimize-url --authors ../authors.txt
没有任何成功。
答案 0 :(得分:14)
我自己也遇到了同样的问题。以下是我解决它的方法。
分别克隆两个回购。
git svn clone -s [original-svn-location] [original-clone-directory]
git svn clone -s [new-svn-location] [new-clone-directory]
将旧的克隆数据添加到新仓库。
cd [new-clone-directory]
git remote add oldstuff ../[original-clone-directory]
git fetch oldstuff
现在棘手的部分...... git log
master
和oldstuff/master
(或者trunk
和olstuff/trunk
- 请你设置它并记下新克隆的第一个提交sha和旧克隆的最后一个提交sha(在移动之前)。
git replace [first-commit-sha-from-new-clone] [last-commit-sha-from-old-clone]
要重写SHA哈希所以一切都是犹太人,你不再需要替换参考...
git filter-branch
现在要清理不再需要的参考文献。
git remote rm oldstuff
rm -rf .git/refs/replace
您将丢失历史记录中的第一个提交,但由于这应该是初始移动(即:没有实际文件内容已更改),因此它可能对您不利。
现在所有的历史记录都应该保留,git blame
报告会记住回购曲目的历史记录,再次为您提供准确的信息。
您应该能够根据需要经常重复此操作(取决于您的项目更改其根位置的次数和/或移动的两侧提交了多少个分支)。
PS - 这个解决方案我根据我的需求调整了here(我无法让他的移植方法为我的存储库工作 - 但使用replace似乎工作得非常漂亮)。
答案 1 :(得分:3)
您可以使用SubGit转换SVN存储库。
不幸的是,版本1.0不支持您拥有的复杂布局。但是有1.1 EAP version可以很好地处理它。 1.0和1.1版本都使用本地SVN存储库,因此您必须具有对SVN存储库的管理访问权限。
为了将SVN存储库转换为Git,请执行以下操作:
生成初始配置。
$ subgit configure SVN_REPO
最有可能的是,SubGit将检测此存储库中的两个项目。 AFAIU,您只需要一个Git存储库。所以,你必须在配置文件中只保留一个'git'部分。指定转换所需的所有分支。
$ EDITOR SVN_REPO/conf/subgit.conf
[core]
...
[git "default"]
repository = .git
...
trunk = trunk:refs/heads/master
branches = branches/*:refs/heads/*
tags = tags/*:refs/tags/*
shelves = shelves/*:refs/shelves/*
branches = iPhone/trunk:refs/heads/iPhone/master
branches = iPhone/branches/*:refs/heads/iPhone/*
tags = iPhone/tags/*:refs/tags/iPhone/*
branches = Android/trunk:refs/heads/Android/master
branches = Android/branches/*:refs/heads/Android/*
tags = Android/tags/*:refs/tags/Android/*
...
[daemon]
...
将SVN转换为Git。
$ subgit install SVN_REPO
此时SubGit将所有修订版从SVN转换为Git。您可以在SVN_REPO / .git中找到转换后的Git存储库。此外,SubGit使SVN和Git存储库保持同步,它会安装特殊的钩子来实现这一点。如果需要摆脱这些钩子。
$ subgit uninstall --purge SVN_REPO
这就是全部。现在你已经转换了Git存储库并保留了整个历史记录。
请注意,SubGit是商业产品,但这种一次性转换是免费的。希望,它适合你。