I found [nvie's git branching model](http://nvie.com/posts/a-successful-git-branching-model/) simple enough to grasp and suitable for my projects - but the frontend supplied at GitHub was far too complex for me to understand. Hence, I wrote this script to start and finish tasks, automatically running the related commands to speed it all up a bit (without it becoming *too* abstract/complex). I've read a handful of tutorials on writing shell scripts but found it difficult to find one that emphasized on portability/POSIX compliancy. I'd like the script to run just fine in sh, dash, bash and zsh. Any feedback is appreciated - for one thing, I'm a bit unsure about where to use $variable and ${variable}... <br /> <br /> Intended usage ============== When I want to create a new branch for a task I run this: gittask.sh new feature name_of_feature When I'm done: gittask.sh done Finishing a task has it automatically deduce by the branch name prefix (feature/release/hotfix) what to do next. * Features are merged back into the development branch. * Releases are continuously merged back into the development branch (bugfixes) and, once the release branch is considered stable enough (decided upon by the user), merged into master (with a tag), ending the release branch. * Hotfixes are merged back into both the master (with a tag) and the development branch. <br /> <br /> Branch model ============ I use two persistent/remote branches, master and development, as well as three temporary/local branches, feature, release and hotfix. **Master branch** * Persistent * Remote branch * Each merge into master equals a new tag **Development branch** * Persistent * Remote branch **Feature branches** * Temporary * Branch off from development * Merge back into development * Naming: "subject" or "issue#" if on issue tracker ("feature/" is prepended) **Release branches** * Temporary * Branch off from development * Merge back into development (continuously) and master (when done) * Naming: "major.minor.z", e.g. "1.2.0" (z is defined by hotfix, "release/" is prepended) * Signed tag needed when merging with master **Hotfix branches** * Temporary * Branch off from master * Merge back into development and master * Naming: "x.y.fix", e.g. "1.2.1" (x, y is defined by release, "hotfix/" is prepended) * Signed tag needed when merging with master <br /> <br /> Script ====== #!/bin/sh # gittask: taskbased git branch management utility usage() { echo "Usage:" echo " gittask.sh new feature name_of_feature" echo " gittask.sh new release name_of_release" echo " gittask.sh new hotfix name_of_hotfix" echo " gittask.sh done (affects current branch)" } delete_branch() { while true; do echo "Delete branch $current? " read yn case $yn in [Yy]* ) git branch -d ${current} break ;; [Nn]* ) echo "Leaving branch $current as it is." break ;; * ) echo "Error: Please answer (y)es or (n)o." ;; esac done } define_tag() { while [ -z ${version_number} && -z ${version_note} ]; do echo "Enter version number (major.minor.fix): " read version_number echo "Enter version number note: " read version_note done } # Check if we're in a git repository, abort if not git status >/dev/null 2>&1 || { echo "Error: You're not in a git repository."; exit 1; } if [ "$1" == "new" ] && [ -n "$2" ] && [ -n "$3" ]; then case $2 in feature ) git checkout development git checkout -b "feature/$3" ;; release ) git checkout development git checkout -b "release/$3" ;; hotfix ) git checkout master git checkout -b "hotfix/$3" ;; * ) echo "Error: You didn't specify feature, release or hotfix." usage exit 1 ;; esac elif [ "$1" == "done" ]; then current=`git branch | awk '/\*/{print $2}'` case ${current} in feature* ) echo "Merging into development branch..." git checkout development git merge ${current} git push origin development delete_branch exit 0 ;; release* ) echo "Merging into development branch..." git checkout development git merge ${current} git push origin development while true; do echo "Merge into master (make a release)? " read yn case $yn in [Yy]* ) git checkout master git merge ${current} define_tag git tag -s $version_number -m $version_note git push --tags origin master delete_branch exit 0 ;; [Nn]* ) echo "Leaving branch master as it is." exit 0 ;; * ) echo "Error: Please answer (y)es or (n)o." ;; esac done exit 0 ;; hotfix* ) git checkout master git merge ${current} define_tag git tag -s $version_number -m $version_note git push --tags origin master git checkout development git merge ${current} git push origin development delete_branch exit 0 ;; * ) echo "Error: You're not on a feature, release or hotfix branch." usage exit 1 ;; esac else echo "Error: You didn't specify whether you want to start or finish a task." usage exit 1 fi