Working with ASF git repos

This document is work in progress. The bits about dcommitting back to ASF are not finished yet. Be warned !

The following cook-book shows you how to smoothly work with git/github, possibly committing back to ASF SVN.

Please note that with GIT there's always three different ways to do all things, and this guide provides a fairly simple and internally consistent model. If you are a beginner to GIT it is advisable to stick to the things in this guide and not try to mix & match.

The git model at ASF

Basically, an SVN commit hook updates the official ASF git clone. http://github.com/apache pulls from the official ASF git clone. The official git clone should be more or less instantly updated, less is known about the exact replication frequency of the github fork, but with git this is not really important.

Standard solution

As example, we use maven-3, located at http://github.com/apache/maven-3.

1. Go to that URL an choose "fork" in github to create a read/write copy under your own user. There are several reasons to do this:

  • You can keep your own changes before you commit back to SVN, with backup.
  • You can use full version control features like committing, without actually committing to svn.
  • Seasoned git users sometimes commit & push in wildly inconsistent states when compared to what SVN users do. Get this extra freedom of choice.
  • Forking from the official github node also makes your project visible within the github project graph, allowing collaborators to see you. If you haven't read about github's collaborative network visualizer, you might want to read up on this here http://github.com/blog/39-say-hello-to-the-network-graph-visualizer
  • Moving between your laptop and your desktop becomes trivial; the author of this guide frequently finds himself moving between 3 different computers in a 3 hour session; it's how I manage to code with kids.

2. On your local machine, do something like this:

git clone git@github.com:yourgithubusername/maven-3.git

3. Within this clone run:

git remote add asf git://git.apache.org/maven-3.git # Connects your clone to get updates from the official ASF git mirror. 

cd .git; wget http://git.apache.org/authors.txt; cd ..
git config svn.authorsfile ".git/authors.txt"
git svn init --prefix=origin/ --tags=tags --trunk=trunk --branches=branches https://svn.apache.org/repos/asf/maven/maven-3 # needed to commit to ASF
    

4. If you are working on a branch, say it's called "repo" and it's based on maven-3, you could say something like this

git checkout repo # checks out your local branch (skip if already on)
git fetch asf # Updates your local checkout with the latest commits from ASF mirror
git rebase asf/trunk # Puts your work on top of svn HEAD of trunk
git push -f origin # Pushes all your stuff to github.
    

Other than this, you want to be working in you "repo" branch, using the regular "work-loop": code some, commit, code some, commit, push to github for backup, code some, commit, code some commit, push.

When you want to commit to ASF you should do:

git svn dcommit

The next time you fetch/rebase, you'll be up-to date with your own commit.

Overview

If you were not using github for backup & collaboration, you could possibly ditch all the "github" nodes in this diagram.

Technically, with this setup, you can delete all the branches in your local repository (and your personal github repository) that you will not use (you get a lot of them when cloning the official repo). You can always reference them with the "asf" prefix later.

Things you may want to do

Create a branch

git fetch asf; git checkout -b MNG-9999 asf/trunk # Creates a local branch MNG-9999 that is based on ASF trunk

4. If you are working on a branch, say it's called "repo" and it's based on maven-3, you could say something like this

git checkout repo # checks out your local branch (skip if already on)
git fetch asf # Updates your local checkout with the latest commits from ASF mirror
git rebase asf/trunk # Puts your work on top of svn HEAD of trunk
git push -f origin # Pushes all your stuff to github.
    

4.1 When git rebase stops with a conflict
git rebase can stop, much like "svn up", with a conflict. Unlike svn up, it can stop multiple times
with different conflicts. The important thing to note about rebase-conflicts is that until you have completed the rebase, you are inside a state-machine. Exiting this state machine should normally only
be done in one of these two way:
git rebase --abort # Can be done at any time to reset to before-rebase state
for each conflicting file:
fix conflict in file
git add file # "GIT ADD" removes conflict markers
git rebase --continue

"Forgetting" to exit the rebase-state machine properly is a common source of confusion for new users.

Other than this, you want to be working in you "repo" branch, using the regular "work-loop": code some, commit, code some, commit, push to github for backup, code some, commit, code some commit, push.

When you want to commit to ASF you should do:

git svn dcommit

Is this git or git-svn ?

This strategy is not git-svn for the read-update bit, it's git only. The git-svn part needs to be in-place to make dcommit work properly.

 
  • No labels

2 Comments

  1. It might be good to describe how to work with Subversion branches as GIT branches - that would eliminate most cases of the "push directly to github" part of the workflow.

    1. I updated list item 1 with the "why use github" parts to explain the real reasons to back this workflow with github. I think a public repo like this on github actually works as a replacement for a branch in svn; this is one of the ways git blurs the distinction between "committer" and "others"; only "committers" can make branches in svn but anyone can fork in git. But I will get to svn branches too...