git-svn:将现有git存储库的完整历史记录提交到一个空的Subversion子目录中

时间:2016-01-26 08:25:33

标签: git svn version-control git-svn

我一直在我的计算机上本地处理一些代码,使用git跟踪修改(没有远程)。 该代码现在变成一个更大项目的模块,其代码库存储在Subversion中(类似于https://svnserver/svnroot/project/trunk/module_x),所以我想我可以使用git-svn来管理Subversion存储库作为远程。我记得之前为另一个项目做过但却找不到运作方式(中间更换了计算机)。

以下是我的尝试:

cd ~/mygitrepo/
git svn init https://svnserver/svnroot/project/trunk/module_x
git svn fetch
git svn rebase

最后一个命令产生以下错误消息:

Unable to determine upstream SVN information from working tree history

我在某处看到它可能是因为Subersion中的目录是空的所以我尝试将一个虚拟文件分别提交给SVN然后运行:

git svn fetch
    A   dummy.txt
r10744 = 89294ba713c6fed368f3b879c8dc7744b1015308 (refs/remotes/git-svn)

但是,我在git repo中找不到dummy.txt文件,rebasedcommit都会继续显示相同的错误消息。 我做错了什么?

2 个答案:

答案 0 :(得分:2)

您签出的分支不是来自颠覆,因此git svn不知道如何使用它。

但是,Git确实如此,所以您需要使用简单的git rebase来重新定位到git-svnrefs/remotes/git-svn)。然后历史记录将包含来自subversion的提交,git svn dcommit将知道在何处提交它。

另一件事是你需要在之前将更改放在正确的子目录中,因为git rebase不支持移入子目录。 git merge通过subdirectory策略执行,但使用merge会将Subversion导出为单个提交。如果您要导出完整的历史记录,并且未在所有提交中的正确目录,则必须使用git filter-branch进行修复。

答案 1 :(得分:2)

Jan提供的答案给出了我遇到的错误的基本原理,并指出普通的旧git rebase --onto作为正确的解决方案,但缺少实际的命令。

我最初提出这些命令作为他的答案的编辑,但它被拒绝了,所以这里是:

git checkout -b svnrebase git-svn            # create a temporary branch
git cherry-pick master~1                     # cherry pick the first  commit
git rebase --onto svnrebase master~1 master  # rebase the 2nd through current commit
git svn dcommit                              # finally commit the results to svn

注意必须更改master~1以引用您对git master的第一次提交。在这里,我们假设我们有一个只有两次提交的git repo。

有必要创建一个临时分支并挑选第一个要掌握的提交,因为rebase --onto仅重新定义 master~1之后所做的修改范围(以及{仅使用两次提交就不存在{1}}引用。