Synchronization of Git and an empty SVN repository
In this guide we will overview synchronization of Git and SVN repositories via SubGit.
To commit a synchronization you will require:
- An SVN repository
- A server with installed Git
- SubGit application located on the server
Let’s begin with an installation of Git repository on the server.
The first requirement is, of course, to obtain any version of SubGit. To obtain the application follow this link and instructions presented within.
The second requirement is a Git repository. There are many ways to create Git repository, you could either create a bare repository on a filesystem using
git init --bare repo.git
…or use Git server software like Gogs.
The third requirement is an SVN repository. You could either create repository via command line using the following command:
svnadmin create repo.svn
…or use SVN server software like VisualSVN server.
Step 1: Configure the SubGit mirror
After successfully obtaining SubGit and creating an SVN repository, run the following command to configure the mirror between SVN and Git repositories:
subgit configure --layout auto --trunk trunk SVN_URL REPOS.GIT
SVN_URL stands for link to an SVN repository located on a remote server and REPOS.GIT for a path to the Git repository located on the same work station as SubGit.
subgit configure --layout auto --trunk trunk http://example.com/svn/Repository /home/User/gogs-repository/user/repository.Git
Step 2: Install the SubGit mirror
Installation of a mirror that will translate every Git commit to revision of SVN is quite simple, just run the following command:
subgit install REPOS.GIT
REPOS.GIT still stands for a path to Git repository located on the same work station as SubGit.
subgit install /home/User/gogs-repository/user/repository.Git
Congratulations, the mirror is set up. If something gone wrong or you are unsatisfied with the result, please look through the next chapter.
The data is gone!
Issue: I set up a mirror to synchronize my Git repository with an empty SVN repository with “trunk”, “branch” and “tags” directories inside, but after the translation ‘master’ branch of my Git repository disappeared and nothing is translated. What happened and how do I recover ‘master’ branch?
Explanation: The very issue itself is that an SVN repository with a trunk directory inside is not considered as an empty repository. By default ‘trunk’ corresponds to ‘master’ branch in Git. This is defined by this rule:
trunk = trunk:refs/heads/master
In SubGit REPOS.GIt/subgit/config file. So, in the end, SubGit tried to synchronize non-empty SVN repository containing ‘trunk’ with non- empty Git repository which contained its own ‘master’, what lead to a conflict situation.
SubGit proposes the following way to recover this situation:
subgit install --recover REPOS.GIT
This command puts all conflicting Git references (Git ‘master’ in this example) to refs/subgit/unsynced/… namespace during installation process.
Solution: In such conflict situations SubGit prioritizes SVN repository, replacing Git branches with translated SVN commits and putting replaced Git branches into /refs/subgit/unsynced/ namespace. Just fetch those branches and switch on them.
git fetch origin refs/subgit/unsynced/heads/master/branchname:refs/heads/newbranchname git checkout newbranchname
I put the files in the SVN, but they won’t synchronize
Issue: Files located in the SVN directory do not synchronize with Git repository, although SubGit showed no error messages.
Explanation: It could happen, if you did put files to the project root of an SVN repository, while it is meant to be put into “trunk” directory.
Files located right in the SVN project root directory as well as other files and directories not listed in trunk/branches/tags/shelves options:
trunk = trunk:refs/heads/master branches = branches/*:refs/heads/* shelves = shelves/*:refs/shelves/* tags = tags/*:refs/tags/*
Do not synchronize with Git repository, and SubGit won’t show any error messages if they are missing. This is expected behavior.
Solution: Move all the files into “trunk” directory inside of SVN repository.