Publish Git repository to SVN

git, mirroring, svn

Solution

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 ;-)

Problem

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.

Original source

Related problems