Git

Like so many software developers, for me the rise of Git (in about 2010 from where I sat) was accompanied by many moments of "but it's not like Subversion!", followed by slow understanding... this page documents the things that I've figured out and what I've settled on as 'reasonably good'. They may, of course, be quite wildly off the mark!

Contributing to Github-hosted projects

[Some](https://github.com/diaspora/diaspora/wiki/Git-Workflow) [projects](http://matthew-brett.github.com/pydagogue/gitwash/development_workflow.html) provide information about how people should fork and contribute to them. This is my general approach (included here, obviously, for my own edification):

 1. Fork a project: _Github clickity-click_
 2. Clone it locally: `git clone git@github.com:username/project.git`
 3. Add the upstream project: `git remote add upstream https://github.com/upstream/project.git`
 4. Create a ‘personal-master’ named with your username: `git branch [username] master`
 5. Set this to be the default branch on Github: _Github clickity-click_
 6. [Delete the master branch](http://matthew-brett.github.com/pydagogue/gh_delete_master.html): `git branch -D master; git push origin :master`
 7. Create branches that solve one feature or issue each, named whatever, and branched from upstream master: `git branch [feature-name] upstream/master`
 8. Rebase topical branches to the upstream master (unless, of course, they get pulled upstream): `git rebase [feature-name]`
 9. Merge all personal feature branches into your personal-master branch, so you’ve got a branch that represents all your development (the no-fast-forward [keeps the feature’s commits as a discrete group](http://nvie.com/posts/a-successful-git-branching-model/), after the feature branch has gone): `git checkout [username]; git merge --no-ff [feature-name]`

My main goal is to create discrete branches, based on the upstream master, for features that I want to push back upstream.

(No doubt I’m missing obvious things, and any git-geek will see instantly the gaps in my knowledge.)

Tag and Release

If a project has submodules then Github’s automatic tarballing and zipping doesn’t work, so I use the following script instead (which also results in the release being tagged). This works well also for PHP projects using Composer where there’s a requirement to create a release tarball that includes all required packages (normally I think projects should be running their own `composer install` though).

#!/bin/bash

if [ -z $1 ]; then
	echo "Usage: $0 <tag_name>"
	exit 1
fi

TAG=$1
echo "Creating Git tag: $TAG"
git tag -af "$TAG"

FILENAME="$TAG.tgz"
echo "Creating release file: $FILENAME"
tar -czf $FILENAME \
  --exclude-vcs \
  --exclude-from='.gitignore' \
  --exclude='nbproject' \
  --exclude='*.sh' \
  --exclude='*.tar' \
  --exclude='*.tgz' \
  *

Rebasing

The Wikimedia way is to rebase changes.

If you have encountered a merge conflict you can do this
git checkout --ours file