git-svn: A workflow
I’ve open sourced some code of mine at googlecode.com, http://async-msgcomp.googlecode.com which uses subversion, but at home I’m using git. Turns out that git supports a bi-directional mechanism for working locally in git but easily using svn as a remote repository.
In my workflow I also have a local server with remote git repository and I’d like to keep all three in sync. My basic workflow is to have the master branch in my local repo represent the trunk of the svn repository. Then make a local git branch for work-in-progress (WIP) and when satisfied all is well I merge the changes from my local branch to master and then dcommit to the svn repo. Furthermore, I will periodically push my local repo to local server as a backup. This means my code is on two computers at home plus at a remote site in svn. Thus I feel very secure as the code is in 3 places.
Assuming we start with a svn repo the workflow is:
*) Clone svn repo to a git working repo named amc, the -s means this is a standard trunk/brances/tags svn repo
lcl~/$: git svn clone -s https://async-msgcomp.googlecode.com/svn amc
*) Create a remote repo named amc.git on srv.
lcl ~/ $ cd amc
lcl ~/amc $: ssh wink@srv
srv ~/ $ cd <path-to-git-repos>
srv ~/git.repos $ mkdir amc.git
srv ~/git.repos $ cd amc.git
srv ~/git.repos/amc.git $ git - - bare init - - shared
srv ~/git.repos/amc.git $ exit
lcl ~/amc $
*) Connect the working repo to srv and push the contents assume we’re in amc
lcl ~/amc $ git remote add origin git://srv/amc.git
lcl ~/amc $ git push - - all
*) Create branch.master.remote and branch.master.merge configuration so git pull defaults to fetching from remote origin and merging with lcl maste
lcl ~/amc $ git config branch.master.remote origin
lcl ~/amc $ git config branch.master.merge refs/heads/master
We now have data on 3 different computers. The general workflow now is to make changes to the code in a branch on lcl, do a git svn rebase, merge changes from lcl branch as into lcl master then do a git svn dcommit to push the changes to svn and git push –all to push changes to srv. Here is an example:
lcl ~/amc $ git checkout -b test1 master
lcl ~/amc $ <edit/compile/test>
lcl ~/amc $ git commit -a
lcl ~/amc $ <repeat edit/compile/test/commits>
lcl ~/amc $ git push
So we created a new branch did some edit/compile/test/commit iterations with some git pushes to srv as desired. Now we’re ready to push the changes to svn. So we checkout master, rebase to get any changes from svn locally then merge test1 and dcommit.
lcl ~/amc $ git checkout master
lcl ~/amc $ git svn rebase
lcl ~/amc $ git merge test1
lcl ~/amc $ <resolve conflicts and test>
lcl ~/amc $ git svn dcommit
lcl ~/amc $ git push - - all
At this point all three repos are synchronized.
Now assume you lost your lcl repo amc. You can partially recover by checking out the srv repo amc.git but the lcl repo won’t be “connected” to svn. To reconnect we need to manipulate amc/.git/config and update .git/remotes. This information comes curtusey of Steve Walter answering a question I had on git-svn segfaulting and is here but with some modifications because I’ve cloned with -s. So the following will reconnect:
lcl ~/ $ git clone git://srv/amc.git amc
lcl ~/ $ cd amc
lcl ~/amc $ git svn init -s http://async-msgcomp.googlecode.com/svn
lcl ~/amc $ rm -rf .git/svn
lcl ~/amc $ cp .git/refs/remotes/origin/master .git/refs/remotes/trunk
lcl ~/amc $ git svn fetch
Migrating from a git-svn v1 layout…
Data from a previous version of git-svn exists, but
.git/svn
(required for this version (1.5.3.8) of git-svn) does not. exist
Done migrating from a git-svn v1 layout
Rebuilding .git/svn/trunk/.rev_db.35bfc53a-2d43-0410-a069-7fc8ebf1512b …
r52 = 2336c1c70e92d572f5a1b248249b4f857142bc51
r51 = 8ce31b64294bdb063c64c50b9358533ac8746af4
…
r2 = 2638419edfbf545d79437650b0772bdd4905035b
r1 = c33b6e02fc70b0792069099e49112cb1b6cf94c4
Done rebuilding .git/svn/trunk/.rev_db.35bfc53a-2d43-0410-a069-7fc8ebf1512b
lcl ~/amc $
Now amc is reconnected to svn and srv and you’ve recovered. Steve points out that its possible to also recover the svn repo from the git repo but neither he nor I have tried.