问题描述
我和我的小团队在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 HEAD
s 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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!