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



我一直在计算机上本地处理一些代码,使用 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 存储库中找不到 dummy.txt 文件,rebasedcommit 将继续显示相同的错误消息。我做错了什么?

你的签出分支不是来自Subversion,所以git svn不知道如何使用它。

但是,Git 确实如此,因此您需要做的是使用普通git rebase将变基git-svnrefs/remotes/git-svn )。然后历史记录将包含来自 Subversion 的提交,git svn dcommit将知道在哪里提交它。

另一件事是,在尝试变基之前,需要将更改放在正确的子目录中,因为git rebase不支持移动到子目录中。 git merge通过subdirectory策略这样做,但使用 merge 将作为单个提交导出到 Subversion。如果要导出完整历史记录,并且在所有提交中都没有将其放在正确的目录中,则必须使用git filter-branch来修复它。

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 存储库。

有必要创建一个临时分支并挑选第一个提交到 master,因为rebase --onto只会重新确定master~1所做的修改范围(并且只有两次提交时不会存在master~2引用)。

最新更新