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.
I1 would like to split the problem into a couple of issues:
My proposal is based on SubGit2.
Importing Git repository into SVN
If you have local access to Subversion repository at svnserver, the setup is pretty much straight-forward and well documented at SubGit Book:
Let's assume that Subversion repository is located at $SVN_REPO and Git repository is located at $GIT_REPO. First, run the following command:
Then adjust generated $SVN_REPO/conf/subgit.conf file as follows:
I'm not quite sure regarding translationRoot option for your case. The value must be a project path relative to SVN repository root, please specify a proper one.
Don't forget to remove other 'git' sections, so SubGit won't translate those parts of SVN repository into Git.
Optionally you can adjust $SVN_REPO/conf/authors.txt file in order to specify how Git committer names should be translated into SVN author names:
Finally, import your Git repository into SVN:
At this moment $SVN_REPO and $GIT_REPO have special hooks installed by SubGit. Subversion and Git servers trigger these hooks on every incoming modification. This way SubGit automatically synchronizes SVN and Git repositories. Created mirror is bi-directional, i.e. some of developers may use SVN clients others may choose any Git clients.
In case you don't need such kind of synchronization, just disable it:
If you don't have local access to Subversion repository, things get much more tricky but still possible:
First, fetch the whole SVN repository to your machine, so you can access it locally:
Now keep in mind the latest revision of fetched repository:
Then repeat all the steps from a previous clause. So the local SVN repository should store imported Git history afterwards.
Finally, send the generated history back to SVN:
Note that remote repository must have pre-revprop-change hook enabled in order to make svnsync work.
Automatic synchronization of Git and SVN repositories
If you have local access to Subversion repository, you can keep SubGit working after you've installed it. As I already mentioned it translates changes immediately after they were sent to one of repositories, so there's no need to maintain any cron job in this case.
If you have no local access to Subversion repository but still would like to use SubGit, I'd recommend you to use svnsync to synchronize SVN repository hosted at svnserver and SVN repository controlled by SubGit3.
You may find a guide on how to setup such kind of mirror in this HOW-TO.
Please note that for this case your project should have a separate Subversion repository, otherwise it's very hard to keep svnsync working properly.
If for any reason you decide to use
git-svn
, I'd recommend you to create a fresh clone of Subversion repository after you've imported Git history with SubGit:From my experience, importing Git history into SVN is not what
git-svn
was made for. On the other side SubGit handles that well.1 Full disclosure: I'm one of SubGit developers.
2 SubGit is a commercial product but it is free for small teams with up to 10 committers. I think it applies for your case.
3 Our team is working on SubGit 2.0 which supports synchronization of SVN and Git repositories located on different hosts. Basically, you can create Git repository anywhere and install SubGit into it with SVN URL specified. After that you can work with any of these repositories — changes get translated automatically between them.
We're going to publish an EAP build with that functionality, so may try it soon.
There are a few issues with your approach:
git svn init
. Rebasing assumes a common ancestor, but if your git repo was previously initialised viagit init
, thengit 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
.-s
option togit svn init
, which causes it to search forbranches/
,tags/
, andtrunk/
. As the warning (Using higher level...
) clearly states, this results in thegit-svn
config pointing at the top of the svn repo, not thefromgit/ProjX
subdirectory.trunk
even though there's no good reason for this branch to exist;git svn init
actually creates a tracking branch calledremotes/git-svn
.So the actual sequence you want is:
Now hacking can occur concurrently in git and svn. Next time you want to
dcommit
from git to svn, you simply do: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:
Subsequently, do the same
svn rebase
anddcommit
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 ;-)