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