Get Started

SubGit for GitHub

SVN to GitHub How-To

1. Two-way mirror

At the moment SubGit requires file-level access to Git repository which is not feasible with repositories hosted at GitHub. However, due to distributed nature of Git, one can establish reliable two-way mirror between SVN and SubGit-managed Git repository and then synchronize that Git repository with GitHub.

1.1 Download SubGit

As the first step get the latest version of SubGit from download page and unpack it. For more details and platform-specific installation information refer to SubGit book.

up

1.2 Configure repository

Run the following command in order to configure Git repository to mirror SVN project:

$ subgit configure --layout auto https://domain/svn/project project.git

Review and adjust Git/SVN authors mapping, you may use dynamic authors mapping replacing authors.txt with a script. Script sample could be found at project.git/subgit/samples directory:

$ edit project.git/subgit/authors.txt

Review and adjust branches mapping configuration:

$ edit project.git/subgit/config

And specify the following option there:

[svn]
    ...
    triggerSvnPostReceive = true
    ...

up

1.3 Install SubGit

As soon as you have Git repository configured, enable Git-SVN mirror by running the following command:

$ subgit install project.git

As result SubGit performs initial import from Subversion repository to Git repository at project.git and keeps these repositories in sync.

up

1.4 Sync Git repository with GitHub

At this stage you have Git-SVN mirror and then you’d need to establish Git-Git mirror with GitHub repository: GitHub SVN mirror

$ cd project.git
$ git remote add github https://github.com/org/project
$ git push github --all --follow-tags

In order to send new commits from SubGit-managed repository to GitHub add the following user-post-receive hook and make sure it is an executable file:

$ echo 'git push --all --follow-tags github' > project.git/hooks/user-post-receive
$ chmod ug+x project.git/hooks/user-post-receive

Alternatively, you can specify only those branches you’re going to synchronize between Subversion and GitHub repositories:

git push github foo bar

Note that the user-post-receive hook gets triggered on every push to SubGit-managed repository and also every time SubGit fetches new revisions from Subversion repository as svn.triggerPostReceive option enables exactly that behavior.

up

1.5 Fetch changes from GitHub

In order to maintain reliable two-way mirror using setup described above, Git users have to push their changes to SubGit-managed Git repository rather than submitting changes to GitHub repository directly.

We recommend to disable write access to GitHub repository and submit any Git changes through SubGit mirror only.

However, often times it is required to synchronize changes arrived to GitHub with Subversion repository. In this case you’d need to setup a periodical job that fetches new commits from GitHub repository and applies them to SVN side of the mirror.

GitHub SVN mirror

We do not recommend fetching new commits from GitHub repository to project.git repository directly. Instead, clone SubGit-managed Git repository to another location:

$ git clone --bare project.git clone.git
$ cd clone.git
$ git remote add github --mirror=fetch https://github.com/org/project

And then create the following executable file that synchronizes new commits arrived to GitHib with Subversion repository:

$ edit /path/to/script.sh
cd /path/to/clone.git
git fetch github
git push origin --all --follow-tags

Finally add this executable file to the cron table:

$ crontab -e
*/20 * * * * /path/to/script.sh

In this example cron job tries to synchronize GitHub and SVN repositories every 20 minutes.

Note that in case the same branch is concurrently updated from both SVN and GitHub sides, git push origin --all --follow-tags command fails to push and synchronize new changes. This is the primary reason why Git users have to publish their changes through SubGit-managed Git repository rather than through GitHub repository.

In order to avoid possible concurrent access to the same branch from both Git and SVN sides, consider configuring SubGit mirror to fetch SVN revisions to a separate namespace:

trunk = trunk:refs/heads/svn/trunk
branches = branches/*:refs/heads/svn/*
tags = tags/*:refs/tags/svn/*

And then merge GitHub and Subversion histories manually:

$ git checkout master
$ git merge svn/trunk
$ git push origin master

up

2. GitHub to SVN mirror

In order to maintain read-write access to GitHub repository and still keep it in sync with Subversion repository, one may setup one-way mirror. In this case any changes submitted to GitHub repository get applied to SVN repository, however, Subversion server has to remain read-only for all SVN users.

GitHub SVN mirror

2.1 Download SubGit

Just as in the previous example, the first step is getting the latest version of SubGit from download page and unpacking it. For more details and platform-specific installation information refer to SubGit book.

up

2.2 Configure repository

Run the following command in order to configure Git repository to mirror SVN project:

$ subgit configure --layout auto https://domain/svn/project project.git

Review and adjust Git/SVN authors mapping, you may use dynamic authors mapping replacing authors.txt with a script. Script sample could be found at project.git/subgit/samples directory:

$ edit project.git/subgit/authors.txt

Review and adjust branches mapping configuration:

$ edit project.git/subgit/config

up

2.3 Install SubGit

As soon as you have Git repository configured, enable Git-SVN mirror by running the following command:

$ subgit install project.git

As result SubGit performs initial import from Subversion repository to Git repository at project.git and keeps those repositories in sync.

up

2.4 Sync Git repository with GitHub

At this stage you have Git-SVN mirror and now you’d need to prepare Git repository for periodical synchronization with GitHub repository:

$ cd project.git
$ git remote add github --mirror=fetch https://github.com/org/project

Then create an executable file that fetches new changes from GitHub repository and applies them to Subversion repository:

$ edit /path/to/script.sh
cd /path/to/project.git
git fetch github
subgit fetch .

And finally add this executable to the cron table:

$ crontab -e
*/20 * * * * /path/to/script.sh

In this example cron job tries to synchronize GitHub and SVN repositories every 20 minutes.

up

2.5 Limitations

One-way GitHub to SVN mirror relies on the fact that no changes arrive to Subversion repository directly, every revision has to be committed to SVN repository via SubGit-managed Git repository. Here’s what happens when one commits a new revision to SVN repository directly:

  • subgit fetch command fetches new revision from Subversion repository and applies this modification to corresponding Git branch;

  • on next sync attempt git fetch github command overwrites that Git branch, so it matches GitHub repository;

  • immediately after fetching changes from GitHub repository, subgit fetch command tries to apply these changes to Subversion repository and so it tries to replace SVN branch to its previous revision; in case svn.allowBranchReplacement option is enabled, SubGit deletes that SVN branch and re-creates it from its previous revision, otherwise this synchronization attempt fails with corresponding error message.

We strongly recommend to disable write access to Subversion repository and submit any SVN changes through SubGit mirror of GitHub repository.

up

Contact us

Please fill out all fields.


By clicking on this button you agree to provide us your personal data for the purpose of creating a software license for you. Please read our Privacy policy for more details.

Thank you for contacting us!
We will get back to you soon.

We are sorry, something went wrong. Please try again or contact us.