本文介绍了将Git存储库发布到SVN的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我和我的小团队在Git工作,而较大的团队使用Subversion。我想安排一个cron工作,每小时将我们的仓库当前 HEAD s发布到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

以下是我尝试时发生的情况:

 %git克隆ssh:// me @ gitserver / git-repo / Projects / ProjX px2 
克隆到'ProjX'中...
...

%cd px2

%svn mkdir --parents http:// me @ svnserver / svn / repo / play / me / fromgit / ProjX
承诺修改123.

%git svn init -s http:// me @ svnserver / svn / repo / play / me / fromgit / ProjX
Us更高级别的URL:http:// me @ svnserver / svn / repo / play / me / fromgit / ProjX => http:// me @ svnserver / svn / repo

%git svn fetch
W:忽略来自SVN的错误,路径可能不存在:(160013):Filesystem没有项目:File未找到:版本100,路径'/ play / me / fromgit / ProjX'
W:不要对上述消息感到担忧git-svn只是在积极搜索旧的历史。
这可能需要一段时间才能在大型存储库中

%git rebase trunk master
致命:需要单个修订
无效上游中继

我以前可以发誓这工作,任何人有任何建议?感谢。

解决方案

您的方法存在一些问题:


  • 您似乎正在使用预先存在的git repo,而不是通过 git svn init 初始化的git repo。 Rebasing假定一个共同的祖先,但如果你的git repo是通过 git init 初始化的,那么 git svn init 会创建如果没有 - ,那么第二个根(即,无父母)提交以及从一个提示到另一个提交的投标将不起作用。

  • 使用 -s 选项 git svn init ,这会导致它搜索分行/ 标记/ 干线/ 。由于警告(使用更高级别... )清楚地表明,这导致 git-svn config指向svn repo的顶部,而不是 fromgit / ProjX 子目录。

  • 您引用 trunk ,即使这个分支没有很好的理由存在; git svn init 实际上会创建一个名为 remotes / git-svn 的追踪分支。



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

 #仅限第一次
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



dcommit
,你只需要:

  cd px2 
git svn rebase
git svn dcommit

如果您已经初始化git仓库,开始黑客入侵,并且需要将这些历史记录移植到svn中,然后第一次序列更加困难,因为您需要将所有git历史记录移植到svn中,即使它们不共享共同的祖先:

 #第一次只有
svn mkdir - 父母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

#将原始git分支移植到git-svn分支
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。这个位需要git> = 1.7.2
git cherry-pick $ root_commit..original-git
#对于旧的gits你可以做
#git rev-list $ root_commit..original -git | xargs -n1 git cherry-pick
#或使用git rebase --onto,但需要跳过一些
#hoops来停止移动远程/ git-svn。

随后,执行 svn rebase dcommit 和以前一样。



如果有人想在沙盒中测试这种方法,可以下载。我建议你在运行之前做一个可视化安全审计; - )


I and my small team work in Git, and the larger group uses Subversion. I'd like to schedule a cron job to publish our repositories current HEADs every hour into a certain directory in the SVN repo.

I thought I had this figured out, but the recipe I wrote down previously doesn't seem to be working now:

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

Here's what happens when I attempt:

% 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

I could have sworn this worked previously, anyone have any suggestions? Thanks.

解决方案

There are a few issues with your approach:

  • You seem to be using a pre-existing git repo, rather than one which was initialised via git svn init. Rebasing assumes a common ancestor, but if your git repo was previously initialised via git init, then git svn init will create a second root (i.e. parent-less) commit, and rebasing from one tip to the other will not work without --onto.
  • You use the -s option to git svn init, which causes it to search for branches/, tags/, and trunk/. As the warning (Using higher level...) clearly states, this results in the git-svn config pointing at the top of the svn repo, not the fromgit/ProjX subdirectory.
  • You refer to trunk even though there's no good reason for this branch to exist; git svn init actually creates a tracking branch called remotes/git-svn.

So the actual sequence you want is:

# 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

Now hacking can occur concurrently in git and svn. Next time you want to dcommit from git to svn, you simply do:

cd px2
git svn rebase
git svn dcommit

If you already initialised the git repository, started hacking in it, and need to transplant that history into svn, then the first-time-only sequence is more difficult because you need to transplant all the git history into svn, even though they don't share a common ancestor:

# 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.

Subsequently, do the same svn rebase and dcommit as before.

In case anyone wants to test this approach in a sandbox, you can download my test script. I'd recommend you do a visual security audit before running though ;-)

这篇关于将Git存储库发布到SVN的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-16 10:44
查看更多