将Git历史记录嫁接到SVN分支上

时间:2020-03-06 14:33:48  来源:igfitidea点击:

情况
我有一个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 repo。假设两者的工作原理相同,我几乎失去了几周的工作。

现在,我知道了Git-SVN的荣耀,并在其他几个项目中愉快地使用了它。
我一开始就完全意识到我可能会丢失Git存储库,不得不使用git-svn init来正确地设置一个新的...但是现在已经和Git玩了一段时间了,我敢肯定有一些将Git历史记录入侵SVN的方法。

解决方案

做你想做的事情可能很难。我们可以通过以下方式将git repo导入svn:http://code.google.com/p/support/wiki/ImportingFromGit,但我认为我们会遇到冲突。我们可以根据git repo从头开始重新创建SVN repo。

为了将来参考,仅将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

我认为应该可以通过以下两种方式之一来实现...我现在将它们概述出来,如果可以的话,以后再尝试充实它们。如果有人能看到如何充实零件或者知道零件为何无法工作的话,请发表评论!

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

我们可能要结帐Tailor。我用它把一个git仓库转换成一个svn仓库,这样我的工作就可以托管在我们公司的svn服务器中。它非常灵活,因此可以执行我们想要的操作。

看来这是不可能的。虽然可以将当前的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,并确保历史记录仍在git中,即使它不在svn中也是如此。可以使用以下方法完成此操作:

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修订版。

从我们要迁移到的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应该更友好。