Developing With Git and Mercurial

This page is to discuss possible usage patterns for distributed version control systems (DVCS) in the Cloudy project. DVCS systems are being increasingly widely used, and offer range of useful facilities, including fast repository queries, improved merges and the ability to commit to the local repository when not connected to the internet or at a remote site with poor connectivity.

Both Git and Mercurial (aka Hg) can be used as clients for a Subversion repository, although the need to map back onto the simpler svn history limits the use of DVCS facilities.



Access to svn repositories is available using  git-svn.

Note that git repositories have both a working directory and an index, an intermediate staging area in which commits are assembled. It's may be as well to ignore this until it's actually needed.

Instructions are available at  a blog page for how to set up a git mirror. should now be kept up to date automatically by a post-commit hook.

Setting up a git clone

You can create a clone (i.e. local working copy) using the git mirror, and then create the necessary references to provide direct access to svn:

git clone -o mirror
cd cloudy
git svn init --prefix=mirror/ -s
git svn rebase

Note that you will need to have a git 1.7.x version client for this to work -- otherwise the first will complain about not being able to find references.

You can keep up to date either by pulling from the git mirror:

git pull --rebase

or directly from subversion:

git svn rebase

See the original blog post for further details.


Comparison of commands

Undo changes in a checkout

svn revert -R .
git reset --hard

Add a file to track

svn add file
git add file

git add is also used to place changes to an already-tracked file into the index.

Commit changes

svn commit
git commit -a

git commits to the local repository. The flag -a means the commit will include all changes to local tracked files: without it, only changes which have been previously added to the index are commited.

Pushing changes to the server

svn commit
git svn dcommit

git push commits changes to a remote git server. However, due to the way that git svn rewrites history in the local repository, if it is being used then you should not push to any other git repository (note that this means that you can't use a git repo on a removable drive to back up work).

Pulling changes from the server

svn update
git svn fetch

git svn fetch updates the local mirrors of all svn branches (remotes), but doesn't copy them into user branches which mirror them.

Updating a working copy

svn update
git svn rebase

git svn rebase pulls in changes from the server into the (one) remote which tracks the current branch, and rebases them onto the user branch. It rewrites these commits so they appear on the local history subsequent to commits pulled from the server: conflicts may arise in the rebase, which will need to be resolved. This also updates the current working copy.

Switching branches

svn switch ...
git checkout <branch>

The git checkout checks out a local branch. To create a new local branch which tracks a remote svn branch

git branch <branch> remotes/svn/<branch>

-- once this is done, the local branch can be checked out, and rebase/dcommit will trade updates with the server.

Merging branches

svn merge ...
git checkout -b merge_temp; git merge master; git format-patch XXXX ; git checkout <branch>; git am XXXX; git branch -D merge_temp

XXXX are details which I've not fully clarified yet. A simple git merge would handle the case where the repository wasn't trying to talk to svn, but trying to turn the merge into something svn can cope with leads to all the complexity.

Return to main wiki page