Development Workflow with Git, Part 1: Repository Setup and Working Protocol

30 Jan 2010
Posted by Jeet Sukumaran

Repository Setup

For most major projects, I have at least two, and sometimes three, remote Git repositories upstream of my local one:

  • A shared primary remote repository, that serves as the centralized repository for the in-house project developers, with read/write access for collaborators but closed to the public.
  • A personal secondary remote repository for development, where works-in-progress and/or experiments on topic branches can be committed as back-ups until ready to be merged with the main code base (or simply discarded if not needed or wanted).
  • A public secondary remote repository for general code distribution, where release-ready code is available for read-only anyonymous access.

The shared primary remote repository is designated as the default remote, i.e., "origin", and thus serves as the standard source/destination for pull and push operations. This repository is Gitosis managed, thus allowing for simple yet comprehensive access-control.

The personal secondary remote repository, for experimental and works-in-progress development, is usually hosted on another network-reachable machine, and is reached using a ssh protocol. It is created directly on the remote host by:

$ ssh login@devmachine
$ cd ~/repos/projects
$ mkdir myproject-dev.git
$ cd myproject-dev.git
$ git init --bare

It is added to the local repository by:

$ cd myproject
$ git remote add dev ssh://login@devmachine/~/repos/projects/myproject-dev.git

Basic Working Protocol

A typical developmemnt workflow with the above setup might go something like this:

  1. Update my local repository from the shared primary repository:
    $ git pull
  2. Make sure my development remote is updated as well:
    $ git push dev
  3. Create and switch to a development topic branch:
    $ git checkout -b fancy-new-feature
  4. Propagate the development topic branch to the development repository (which I usually call "dev"):
    $ git push dev fancy-new-feature
  5. Work on code (edit, test, debug, fix, rinse, repeat), committing to the feature branch frequently, and pushing commits through to the development repository, even if the code is in a broken state, until code is ready for incorporation into the main code base:
     $ emacs lib/fancynewfeature.py
     $ git commit -m "add something" lib/fancynewfeature.py
     $ git push dev
     $ python lib/test/test_fancynewfeature.py
     $ emacs lib/fancynewfeature.py
     $ git commit -m "fix something" lib/fancynewfeature.py
     $ git push dev
     $ python lib/test/test_fancynewfeature.py
     $ python setup.py test
     $ emacs lib/fancynewfeature.py
     $ git commit -m "fix something else that I broke by fixing the first something" lib/fancynewfeature.py
     $ git push dev
     $ python setup.py test
     ## etc. ##
  6. When the code is ready for incorporation into the main code base (feature is working, all tests are passing, etc.), then checkout the "master" branch (or whatever branch is the main code trunk), and merge:
    $ git checkout master
    $ git merge fancy-new-feature
  7. Then push the commits through to the shared in-house repository as well as the personal development repository, and, if appropropriate, the public repository as well:
    $ git push origin
    $ git push dev
    $ git push github
  8. If the changes require a new release tag, then the (annotated!) tag must be created and propagated to all upstream repositories:
    $ git tag -a -m "Release 2.1.1: added fancy new feature" v2.1.1
    $ git push --tag origin
    $ git push --tag dev
    $ git push --tag github
  9. Finally, clean-up, where both the local development feature branch as well as its remote parallel are deleted:
    $ git branch -d fancy-new-feature
    $ git push dev :fancy-new-feature

Making Life Easier

Some parts of this workflow are repetitive, tedious, or both (for example, the multiple pushes to different repositories, or the hoops you have to jump through to create a development branch and then delete it again after merging). In addition, other aspects of this workflow, such as having multiple different branches distributed across multiple different repositories, may lead to difficulty in keeping track of things. Part 2 of this article describes some scripts, aliases, and other tools that alleviate much of the tedium and complexity of this workflow.

Tags:

Great git transcript write-up!

Thanks for writing up this transcript of interacting with Git. I'm just getting familiar with git, and I hadn't come across how to propagate tags to a remote repository until I found your page. Much appreciated!

Post new comment

The content of this field is kept private and will not be shown publicly.
CAPTCHA
This question is for testing whether you are a biological visitor and to prevent automated spam submissions.
Image CAPTCHA
Enter the characters shown in the image.