I have a standalone Git repository, which I would like to migrate to a new SVN repository. At a minimum, I'd like to migrate the master branch with full history, but ideally I'd like to migrate all branches and tags. I only need to do a one-time migration; I do not need to repeat this or do any two-way synchronizations or anything like that.
Based on what I can find online, the best tool to do this seems to be git-svn. I feel like I'm missing something obvious, that there's some parameter to git svn init
or git svn dcommit
that I need to pass that will make all of this just work, but I just can't find it.
Here's what I've done to try this so far:
Try 1: git svn dcommit to a blank svn repo.
[dyaw@localhost v1]$ mkdir svngit ; cd svngit
[dyaw@localhost svngit]$ git svn init svn://server/emptyRepo --stdlayout
Initialized empty Git repository in /home/dyaw/stackoverflow/v1/svngit/.git/
[dyaw@localhost svngit]$ git svn fetch
[dyaw@localhost svngit]$ git config receive.denyCurrentBranch ignore
[dyaw@localhost svngit]$ cd ..
[dyaw@localhost v1]$ git clone /mnt/sharedDrive/sharedRepo/ plaingit
Cloning into 'plaingit'...
done.
[dyaw@localhost v1]$ cd plaingit/
[dyaw@localhost plaingit]$ git remote add svntest /home/dyaw/stackoverflow/v1/svngit
[dyaw@localhost plaingit]$ git branch -a | grep remotes/origin | grep -v -- '->' | cut -d/ -f3 | xargs -L1 git checkout
Branch 'Foo' set up to track remote branch 'Foo' from 'origin'.
Switched to a new branch 'Foo'
Switched to branch 'master'
Your branch is up to date with 'origin/master'.
[dyaw@localhost plaingit]$ git push svntest --all
Enumerating objects: 2719, done.
Counting objects: 100% (2719/2719), done.
Delta compression using up to 8 threads.
Compressing objects: 100% (2591/2591), done.
Writing objects: 100% (2719/2719), 4.67 MiB | 18.55 MiB/s, done.
Total 2719 (delta 2011), reused 237 (delta 123)
remote: Resolving deltas: 100% (2011/2011), done.
To /home/dyaw/stackoverflow/v1/svngit
* [new branch] Foo -> Foo
* [new branch] master -> master
[dyaw@localhost plaingit]$ git push svntest --tags
Enumerating objects: 8, done.
Counting objects: 100% (8/8), done.
Delta compression using up to 8 threads.
Compressing objects: 100% (8/8), done.
Writing objects: 100% (8/8), 1.32 KiB | 1.32 MiB/s, done.
Total 8 (delta 0), reused 0 (delta 0)
To /home/dyaw/stackoverflow/v1/svngit
* [new tag] Many tags pushed
[dyaw@localhost plaingit]$ cd ../svngit/
[dyaw@localhost svngit]$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
deleted: Every single file in the repository
[dyaw@localhost svngit]$ git reset --hard
HEAD is now at 3161afd
[dyaw@localhost svngit]$ git status
On branch master
nothing to commit, working tree clean
[dyaw@localhost svngit]$ git svn dcommit
Unable to determine upstream SVN information from HEAD history.
Perhaps the repository is empty. at /usr/libexec/git-core/git-svn line 872.
- "Perhaps the repository is empty." Yes, it's definitely empty. That's the entire point, I currently have zero content in SVN and I need to move all the work there.
- This is with a completely empty SVN repo. Not even the trunk/tags/branches directories exist.
Try #2: git svn dcommit to a repo with the basic structure in place (trunk/tags/branches).
- Same basic result.
- The output of
git svn fetch
in the newly-created svngit working copy was:[dyaw@localhost svngit]$ git svn fetch r1 = 81aad897c91af332c969ece7655a86f8f670bfec (refs/remotes/origin/trunk) Checked out HEAD: svn://server/basicRepo/trunk r1
- The first
git push svntest --all
failed with "Updates were rejected because the remote contains work that you do not have locally. This is usually caused by another repository pushing to the same ref. You may want to first integrate the remote changes (e.g., 'git pull ...') before pushing again.". After doing agit pull svntest master --allow-unrelated-histories
and committing that merge, the push succeeded. - In the end,
git svn dcommit
gave the same error about an empty repository.
Try #3: Use GitHub's SVN bridge
- Git repositories on GitHub can be accessed via SVN.
- I pushed my Git repo to GitHub, and I was able to access it from SVN. (
svn co https://github.com....
) - Normally,
svnrdump
would be able to dump an SVN repo given a URL (as opposed tosvnadmin dump
which needs to be given the repo as files in the local filesystem), but svnrdump returnssvnrdump: E200007: The requested report is unknown.
- I am able to
svnrdump dump -r
a single revision. Any revision seems to work, but specifying--incremental
or a range of revisions (-r 1:2
or the default of everything) causes that error to be reported. - Apparently GitHub's implementation of SVN over HTTPS doesn't include support for incremental dumps.
- I could do non-incremental dumps of 1 through HEAD, but I don't know of any way to turn those sequential non-incremental dumps back into an incremental so that it can have the full history.
Try #4: Do an initial commit in SVN then dcommit from there
Per Jeff Mercado's answer.
I created an empty file in the trunk of SVN before doing all the git svn stuff. My first time through, the dcommit had the link to SVN, but didn't actually commit anything on the initial branch, then gave the error when switching to the other branch and when switching back to master. When I repeated those steps to capture the output for posting here, it gave the error right away. Looking back at the command history, I don't see a difference. Regardless, I still can't dcommit.
[dyaw@localhost v4]$ svn co svn://server/emptyRepo svn
Checked out revision 0.
[dyaw@localhost v4]$ cd svn
[dyaw@localhost svn]$ mkdir trunk tags branches
[dyaw@localhost svn]$ svn add trunk tags branches
A trunk
A tags
A branches
[dyaw@localhost svn]$ cd trunk/
[dyaw@localhost trunk]$ touch dummyMigrationFile
[dyaw@localhost trunk]$ svn add dummyMigrationFile
A dummyMigrationFile
[dyaw@localhost trunk]$ svn ci -m "Added directory structure and dummy file"
Adding .
Adding dummyMigrationFile
Transmitting file data .done
Committing transaction...
Committed revision 1.
[dyaw@localhost trunk]$ cd ../..
[dyaw@localhost v4]$ mkdir svngit ; cd svngit
[dyaw@localhost svngit]$ git svn init svn://server/emptyRepo --stdlayout
Initialized empty Git repository in /home/dyaw/stackoverflow/v4/svngit/.git/
[dyaw@localhost svngit]$ git svn fetch
A dummyMigrationFile
r1 = a934fa2864bd46f0090c2cdf486c924ceb09fb52 (refs/remotes/origin/trunk)
Checked out HEAD:
svn://svn1/Data/00000999-migrate/trunk r1
[dyaw@localhost svngit]$ git config receive.denyCurrentBranch ignore
[dyaw@localhost svngit]$ cd ..
[dyaw@localhost v4]$ git clone /mnt/sharedDrive/sharedRepo/ plaingit
Cloning into 'plaingit'...
done.
[dyaw@localhost v4]$ cd plaingit/
[dyaw@localhost plaingit]$ git remote add svntest /home/dyaw/stackoverflow/v4/svngit
[dyaw@localhost plaingit]$ git branch -a | grep remotes/origin | grep -v -- '->' | cut -d/ -f3 | xargs -L1 git checkout
Branch 'Foo' set up to track remote branch 'Foo' from 'origin'.
Switched to a new branch 'Foo'
Switched to branch 'master'
Your branch is up to date with 'origin/master'.
[dyaw@localhost plaingit]$ git push svntest --all
Enumerating objects: 2719, done.
Counting objects: 100% (2719/2719), done.
Delta compression using up to 8 threads.
Compressing objects: 100% (2591/2591), done.
Writing objects: 100% (2719/2719), 4.67 MiB | 18.62 MiB/s, done.
Total 2719 (delta 2011), reused 237 (delta 123)
remote: Resolving deltas: 100% (2011/2011), done.
To /home/dyaw/stackoverflow/v4/svngit
* [new branch] Foo -> Foo
! [rejected] master -> master (fetch first)
error: failed to push some refs to '/home/dyaw/stackoverflow/v4/svngit'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
[dyaw@localhost plaingit]$ git pull svntest master --allow-unrelated-histories --no-edit
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From /home/dyaw/stackoverflow/v4/svngit
* branch master -> FETCH_HEAD
* [new branch] master -> svntest/master
Merge made by the 'recursive' strategy.
dummyMigrationFile | 0
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 dummyMigrationFile
[dyaw@localhost plaingit]$ git push svntest --all
Enumerating objects: 593, done.
Counting objects: 100% (593/593), done.
Delta compression using up to 8 threads.
Compressing objects: 100% (552/552), done.
Writing objects: 100% (552/552), 4.05 MiB | 19.00 MiB/s, done.
Total 552 (delta 417), reused 0 (delta 0)
remote: Resolving deltas: 100% (417/417), completed with 30 local objects.
To /home/dyaw/stackoverflow/v4/svngit
a934fa2..127ed95 master -> master
[dyaw@localhost plaingit]$ git push svntest --tags
Enumerating objects: 8, done.
Counting objects: 100% (8/8), done.
Delta compression using up to 8 threads.
Compressing objects: 100% (8/8), done.
Writing objects: 100% (8/8), 1.32 KiB | 1.32 MiB/s, done.
Total 8 (delta 0), reused 0 (delta 0)
To /home/dyaw/stackoverflow/v4/svngit
* [new tag] Lots of tags
[dyaw@localhost plaingit]$ cd ../svngit/
[dyaw@localhost svngit]$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
deleted: All the files that were in the original git
[dyaw@localhost svngit]$ git reset --hard
HEAD is now at 127ed95 Merge branch 'master' of /home/dyaw/stackoverflow/v4/svngit
[dyaw@localhost svngit]$ git status
On branch master
nothing to commit, working tree clean
[dyaw@localhost svngit]$ git svn dcommit
Unable to determine upstream SVN information from HEAD history.
Perhaps the repository is empty. at /usr/libexec/git-core/git-svn line 872.
[dyaw@localhost svngit]$ ll
total 4128
-rw-r--r--. 1 dyaw domain users 0 Aug 12 12:47 dummyMigrationFile
-rw-r--r--. 1 dyaw domain users 553 Aug 12 12:48 All the files of the original git
[dyaw@localhost svngit]$ git log | head -n 20
commit 127ed959dd48230e100b24878014b290f795d298
Merge: 3161afd a934fa2
Author: David Yaw <dyaw@localhost>
Date: Wed Aug 12 12:47:49 2020 -0400
Merge branch 'master' of /home/dyaw/stackoverflow/v4/svngit
commit a934fa2864bd46f0090c2cdf486c924ceb09fb52
Author: (no author) <(no author)@057915ec-d7cd-45ea-bdf3-a57c6415ee48>
Date: Wed Aug 12 16:13:26 2020 +0000
Added directory structure and dummy file
git-svn-id: svn://server/emptyRepo/trunk@1 057915ec-d7cd-45ea-bdf3-a57c6415ee48
commit 3161afdcb9272a6b047725ccbd1f125b973c7d68
Author: someone else
Date: Mon May 11 10:10:26 2020 -0400
This is the last commit on master of the original git repo
[dyaw@localhost svngit]$