将Git存储库发布到SVN

Ken*_*ams 4 svn git mirroring

我和我的小团队在Git工作,而较大的团队使用Subversion.我想安排一个cron作业,HEAD每小时将我们的存储库当前发布到SVN 仓库中的某个目录中.

我以为我已经想到了这一点,但我之前写下的食谱现在似乎没有起作用:

git clone ssh://me@gitserver/git-repo/Projects/ProjX px2
cd px2
svn mkdir --parents http://me@svnserver/svn/repo/play/me/fromgit/ProjX
git svn init -s http://me@svnserver/svn/repo/play/me/fromgit/ProjX
git svn fetch
git rebase trunk master
git svn dcommit
Run Code Online (Sandbox Code Playgroud)

这是我尝试时会发生的事情:

% git clone ssh://me@gitserver/git-repo/Projects/ProjX px2
Cloning into 'ProjX'...
...

% cd px2

% svn mkdir --parents http://me@svnserver/svn/repo/play/me/fromgit/ProjX
Committed revision 123.

% git svn init -s http://me@svnserver/svn/repo/play/me/fromgit/ProjX
Using higher level of URL: http://me@svnserver/svn/repo/play/me/fromgit/ProjX => http://me@svnserver/svn/repo

% git svn fetch
W: Ignoring error from SVN, path probably does not exist: (160013): Filesystem has no item: File not found: revision 100, path '/play/me/fromgit/ProjX'
W: Do not be alarmed at the above message git-svn is just searching aggressively for old history.
This may take a while on large repositories

% git rebase trunk master
fatal: Needed a single revision
invalid upstream trunk
Run Code Online (Sandbox Code Playgroud)

我本来可以发誓这个曾经有过工作,有人有什么建议吗?谢谢.

Ada*_*ers 9

您的方法存在一些问题:

  • 您似乎正在使用预先存在的git repo,而不是通过初始化的git repo git svn init.重新定义假设一个共同的祖先,但如果您的git repo之前已经初始化git init,那么git svn init将创建第二个根(即无父级)提交,并且从一个尖端到另一个尖端的重新定位将不起作用--onto.
  • 您可以使用该-s选项git svn init,这会导致它搜索branches/,tags/trunk/.正如warning(Using higher level...)明确指出的那样,这会导致git-svn配置指向svn repo的顶部,而不是fromgit/ProjX子目录.
  • 你指trunk的是这个分支没有充分理由存在; git svn init实际创建一个名为的跟踪分支remotes/git-svn.

所以你想要的实际顺序是:

# 1st time only
svn mkdir --parents http://me@svnserver/svn/repo/play/me/fromgit/ProjX
mkdir px2
cd px2
git svn init http://me@svnserver/svn/repo/play/me/fromgit/ProjX
git svn fetch
Run Code Online (Sandbox Code Playgroud)

现在黑客可以在git和svn中同时发生.下次你想dcommit从git到svn,你只需:

cd px2
git svn rebase
git svn dcommit
Run Code Online (Sandbox Code Playgroud)

如果您已经初始化了git存储库,开始入侵它,并且需要将该历史记录移植到svn中,那么第一次使用的序列就更难了,因为你需要将所有的git历史记录移植到svn中,即使它们没有共享一个共同的祖先:

# 1st time only
svn mkdir --parents http://me@svnserver/svn/repo/play/me/fromgit/ProjX
git clone ssh://me@gitserver/git-repo/Projects/ProjX px2
cd px2
git svn init http://me@svnserver/svn/repo/play/me/fromgit/ProjX
git svn fetch

# transplant original git branch onto git-svn branch
root_commit=$( git rev-list --reverse HEAD | head -n1 )
git tag original-git
git reset --hard $root_commit
git reset --soft git-svn
git commit -C $root_commit
# N.B. this bit requires git >= 1.7.2
git cherry-pick $root_commit..original-git
# For older gits you could do
#   git rev-list $root_commit..original-git | xargs -n1 git cherry-pick
# or use git rebase --onto but that requires jumping through some
# hoops to stop moving remotes/git-svn.
Run Code Online (Sandbox Code Playgroud)

随后,svn rebasedcommit以前一样.

如果有人想在沙盒中测试这种方法,您可以下载我的测试脚本.我建议你在跑步前进行视觉安全审核;-)