将Git历史记录移植到SVN分支

6

情况
我有一个Git仓库和一个SVN仓库,它们都保存着相同的源代码但是不同的提交历史。Git仓库有很多小的、注释良好的提交...而SVN仓库有一些巨大的提交,注释为"许多东西"。 这两个提交系列遵循了相同的代码更改,并且大致等价。

期望结果
我想切换到使用Git-SVN,不会失去当前Git仓库的详细历史记录。这应该通过将Git仓库的历史记录“嫁接”到项目的一个SVN分支上(从我真正开始使用Git的那个点开始分支)来完成。

为什么要这样做?(历史)
一段时间以前,我开始尝试Git。我首先在我正在使用SVN控制的项目中设置了一个Git仓库。通过一些配置,我同时在相同的源代码上使用Git和SVN。

对我来说,这是学习和玩弄Git的好方法,同时还有SVN的安全网。基本上,这是一个带有真实数据的沙盒。我没有时间真正地学习Git,但我真的想把它玩弄一下。这对我来说实际上是学习Git的一种很好的方式。

起初,在进行一些编辑后,我会先提交到SVN,然后再提交到Git...然后玩弄Git,知道我的更改安全地保存在SVN中。很快,我提交到Git的频率比提交到SVN的还要高...现在,提交到SVN变成了我必须做的烦人的琐事。

当学习git revertsvn revert之间的区别时,我非常高兴我一直在检入SVN仓库。我几乎失去了几周的工作,认为这两个命令的功能相同。

我现在知道了Git-SVN的美妙,并且正在其他几个项目中愉快地使用它。 我开始时完全意识到可能会失去我的Git仓库,不得不“正确”地使用git-svn init设置一个新的仓库......但是现在,我确信有一种方法可以将Git历史记录“黑进”SVN。

6个回答

2
那可能很难做到你想要的。你可以通过类似http://code.google.com/p/support/wiki/ImportingFromGit的方式将git存储库导入svn,但我认为你会遇到冲突。你可以基于你的git存储库从头开始重新创建SVN存储库。

以后参考,使用Git作为SVN客户端可能更容易:

git-svn clone path/to/your/svn/repo
git-commit -a -m 'my small change'
vi some files to change.txt
git-commit -a -m 'another small change' 
git-svn dcommit # sends your little changes as individual svn commits

不幸的是,链接的文章从克隆svn存储库以创建git存储库开始。在我的情况下,由于两者都已创建且非空,这并没有真正帮助。 - Kev

2
似乎这是不可能的。虽然可以将当前的git repo加入到当前的svn repo中,但似乎无法将git repo的历史记录重放到svn repo中。
我遇到的主要问题是让git-svn“锁定”到一个单独的svn提交。解决这个问题的答案似乎是`git-svn set-tree`。这篇博客文章非常有帮助:
http://www.reonsoft.com/~john/blog/2008/06/05/git-first-git-svn-later/ 这就是我尝试在svn中保留历史记录的最远距离:
git branch svn-reconsile HASH_OF_SECOND_COMMIT
git checkout -f svn-reconsile

git svn init file://path/to/repos/myproject/branches/git-import
git svn fetch

git svn set-tree HASH_OF_SECOND_COMMIT

git rebase git-svn

git merge master

git svn dcommit

问题在于git svn dcommit只会在svn中创建一个修订版本,而不是针对master分支中的每个提交都创建一个版本...因此,在svn中压缩了历史记录。
因此,更简单的解决方案是使用set-tree启动git-svn,并满足即使不在svn中,历史记录仍然存在于git中。可以使用以下命令完成:
git svn init file://path/to/repos/myproject/branches/git-import
git svn fetch

git svn set-tree HASH_OF_MOST_RECENT_COMMIT

git rebase git-svn

如果有人知道如何解决压缩问题(我已尝试--no-squash),请评论!如果没有聪明的评论,我将接受保留git历史记录并使用上面的第二个代码块嫁接到最新的svn修订版本。


1
你可能想要查看Tailor。我用它将一个git仓库转换成svn仓库,这样我的工作就可以托管在我们公司的svn服务器上了。它非常灵活,所以也许能够满足你的需求。

看起来这会奏效!对于我来说,我真的希望通过这个练习更深入地了解Git...所以我不会尝试它...但如果其他人在重要任务中遇到与我类似的问题... 这看起来是一个杀手级应用程序! - Kev

1

我认为有两种方法可以实现这个... 我现在会概述它们,如果我能想出更多细节,我会尽量补充。如果有人知道如何完善某个部分或者知道某个部分为什么不起作用,请评论!

1 - 使用 git-svn 直接进行修改
(以下是伪命令,不要使用它们)

rm .svn
(configure git-svn '/myproject/branch/git-remerge')
git svn sync_versions --svn_revision=123 --hash=ad346f221455
git svn dcommit

2 - 使用单独的 git-svn 仓库作为代理
(以下是伪命令,不要使用它们)

mkdir ../svn_proxy
cd ../svn_proxy
git svn init
git checkout hash_of_svn_branch_point
git pull ../messy_repo

0

我在处理来自memcached的git历史记录时,做了很多工作。 我所做的大部分工作是验证每个人是否得到了适当的工作认可。

我建立了一个工具,用于生成报告,显示树在哪里汇聚,而不管提交哈希、git历史记录、作者、提交者等等……请看一下我们用来查看两个不相关的包含相同信息的存储库汇聚位置的示例报告

从那里开始,我进行了大量手动移植和filter-branch操作,经过大量谷歌和邮件列表搜索,找出了这些贡献更改的人是谁。


0

从您正在尝试迁移的 git svn 存储库中,执行以下操作:

git remote add old-repo <path-to-old-repo>
git fetch old-repo
# to browse and figure out the hashes, if that helps
gitk --all &

# for each branch you want to graft
git rebase --onto <new git svn branch base> <old-repo branch base> <old-repo branch tip>

# when done
git remote rm old-repo

顺便提一下,您也可以使用git format-patch和git am来完成同样的操作,但是git rebase应该更加友好。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接