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.

Preparation

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.

Example:

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.

Example:

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.

Known issues

Issue A

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.

Example:

git fetch origin refs/subgit/unsynced/heads/master/branchname:refs/heads/newbranchname
git checkout newbranchname

Issue B

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.

Written on November 24, 2016