我一直在计算机上本地处理一些代码,使用 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
文件,rebase
和 dcommit
将继续显示相同的错误消息。我做错了什么?
你的签出分支不是来自Subversion,所以git svn
不知道如何使用它。
但是,Git 确实如此,因此您需要做的是使用普通git rebase
将变基git-svn
(refs/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
引用)。