Merge branch 'release-0.1'
diff --git a/README b/README
deleted file mode 100644
index e69de29..0000000
--- a/README
+++ /dev/null
diff --git a/README.mdown b/README.mdown
new file mode 100644
index 0000000..86635b6
--- /dev/null
+++ b/README.mdown
@@ -0,0 +1,84 @@
+gitflow
+=======
+A collection of Git wrapper scripts to provide high-level repository operations
+for Vincent Driessen's [branching model](http://nvie.com/archives/323 "original
+blog post").
+
+
+Release 0.1
+-----------
+A quick release of version 0.1 has arrived. The main script are functional and
+should be usable under "normal" use.
+
+There have barely been any real-world tests, but I encourage you to start using
+it actively. [Feedback](http://github.com/nvie/gitflow/issues) is also very
+welcome. See the "Please help out" section below, also.
+
+**Make sure to validate the modifications to your repo after running any of the
+`gitflow` commands, before pushing them permanently.**
+
+
+Installing gitflow
+------------------
+There isn't a real Unix installer available, but the project is so small that
+installing it is easy.
+
+Either:
+
+- Put the `gitflow` directory anywhere on your Unix `PATH` variable; or
+- Run:
+
+ $ git clone git://github.com/nvie/gitflow
+ $ cd gitflow
+ $ cp gitflow* /usr/local/bin
+
+
+Please help out
+---------------
+This project is still under development. What is available today is merely its
+foundation. However, it is functional in its current form and should be usable
+under normal use. (Don't try to create multiple release branches next to each
+other and stuff like that, yet.)
+
+Feedback and suggestions are very welcome and I encourage you to use the
+[Issues list](http://github.com/nvie/gitflow/issues) on Github to provide that
+feedback.
+
+Feel free to fork this repo and to commit your additions.
+
+
+Example uses:
+-------------
+
+* To start a new feature branch, use:
+
+ gitflow start feature <name> [<base>]
+ gitflow start feature foo-support
+
+ `base` is `develop` by default.
+
+* To finish this feature and have it merged into `develop`, use:
+
+ gitflow finish feature <name>
+ gitflow finish feature foo-support
+
+* To start a new release branch for 2.0, based on the 1.1 production release, use:
+
+ gitflow start release <release>
+ gitflow start release 2.0
+
+* To finish the release branch (i.e. to make an actual production release), use:
+
+ gitflow finish release <release>
+ gitflow finish release 2.0
+
+* To start a new hotfix branch for 2.1, based on the 2.0 production release, use:
+
+ gitflow start hotfix <release> [<base-release>]
+ gitflow start hotfix 2.1 2.0
+
+* To finish the hotfix branch, use:
+
+ gitflow finish hotfix <release>
+ gitflow finish hotfix 2.1
+
diff --git a/TODO.mdown b/TODO.mdown
new file mode 100644
index 0000000..0bb08db
--- /dev/null
+++ b/TODO.mdown
@@ -0,0 +1,15 @@
+TODO-list
+=========
+
+General configuration
+---------------------
+- Support configurable naming for fixed branch names 'master' and 'develop'
+- Support configurable naming conventions (i.e. name prefixes) for supporting
+ branches, instead of fixed 'release-\*' and 'hotfix-\*'
+
+Release branch support
+----------------------
+- Take care of the situation where two release branches live next to each
+ other. In that situation, a "finish release" action should merge back changes
+ into the other release, not into 'develop'. Or at least warn about it. Or not
+ support creating a new release branch if the other isn't finished yet.
diff --git a/bump-version b/bump-version
new file mode 100755
index 0000000..60eac0d
--- /dev/null
+++ b/bump-version
@@ -0,0 +1,13 @@
+#!/bin/sh
+usage() {
+ echo "usage: bump-version <version-id>"
+}
+
+if [ $# -ne 1 ]; then
+ usage
+ exit 1
+fi
+
+echo "GITFLOW_VERSION=$1" > gitflow-version
+git add gitflow-version
+git commit -m "Bumped version number to $1" gitflow-version
diff --git a/gitflow b/gitflow
new file mode 100755
index 0000000..28da0af
--- /dev/null
+++ b/gitflow
@@ -0,0 +1,62 @@
+#!/bin/sh
+#
+# gitflow -- A collection of Git wrapper scripts to provide high-level
+# repository operations for Vincent Driessen's branching model:
+#
+# Original blog post presenting this model is found at:
+# http://nvie.com/archives/323
+#
+# Feel free to contribute to this project at:
+# http://github.com/nvie/gitflow
+#
+# Copyright (c) 2010 by Vincent Driessen
+#
+
+export GITFLOW_DIR=$(dirname "$0")
+
+usage() {
+ . "$GITFLOW_DIR/gitflow-version"
+ echo "gitflow, version $GITFLOW_VERSION"
+ echo ""
+ echo "usage: gitflow <start|finish> <type> <args>"
+ echo ""
+ echo "arguments:"
+ echo "type can be any of: \"feature\", \"release\", \"hotfix\""
+ echo ""
+}
+
+check_incoming() {
+ if [ "$ACTION" != "start" -a "$ACTION" != "finish" ]; then
+ usage
+ exit 1
+ fi
+
+ if [ "$BTYPE" != "feature" -a "$BTYPE" != "release" -a "$BTYPE" != "hotfix" ]; then
+ usage
+ exit 1
+ fi
+}
+
+if [ $# -lt 2 ]; then
+ usage
+ exit 1
+fi
+
+# Set & check arguments
+ACTION="$1"
+BTYPE="$2"
+shift 2
+check_incoming
+
+# Now, $ACTION and $BTYPE are set
+# It's time to call the appropriate subcommand
+. "$GITFLOW_DIR/gitflow-sh-setup"
+. "$GITFLOW_DIR/gitflow-$BTYPE"
+
+if [ "$ACTION" = "start" ]; then
+ start "$@"
+elif [ "$ACTION" = "finish" ]; then
+ finish "$@"
+else
+ usage
+fi
diff --git a/gitflow-feature b/gitflow-feature
new file mode 100755
index 0000000..90c9f4c
--- /dev/null
+++ b/gitflow-feature
@@ -0,0 +1,99 @@
+#!/bin/sh
+#
+# gitflow -- A collection of Git wrapper scripts to provide high-level
+# repository operations for Vincent Driessen's branching model:
+#
+# Original blog post presenting this model is found at:
+# http://nvie.com/archives/323
+#
+# Feel free to contribute to this project at:
+# http://github.com/nvie/gitflow
+#
+# Copyright (c) 2010 by Vincent Driessen
+#
+
+usage() {
+ echo "usage: gitflow start feature [<options>] <name> [<base>]"
+ echo " gitflow finish feature [<options>] <name>"
+ # TODO
+ #echo ""
+ #echo "options:"
+ #echo "--option Explanation"
+ #echo ""
+ #echo "start-only options:"
+ #echo "--option Explanation"
+ #echo ""
+ #echo "finish-only options:"
+ #echo "--rebase Rebases the feature branch on top of develop, instead of merging"
+ #echo "--squash Squashes all commits of the feature branch into a single commit"
+ #echo " on develop"
+ #echo "--push Push to the origin repo when finished"
+}
+
+parse_args() {
+ FEATURE="$1"
+ if [ $# -eq 2 ]; then
+ BASE="$2"
+ else
+ BASE="develop"
+ fi
+ if [ "$FEATURE" = "" ]; then
+ echo "Missing argument <release>"
+ usage
+ exit 1
+ fi
+}
+
+start() {
+ parse_args "$@"
+
+ # Checks
+ gitflow_check_clean_working_tree
+ gitflow_require_branch_absent "$FEATURE"
+ if [ "$BASE" = "develop" ]; then
+ gitflow_require_branches_equal 'develop' 'origin/develop'
+ fi
+
+ # All checks passed, ready to roll
+ git checkout -b "$FEATURE" "$BASE"
+
+ echo ""
+ echo "Summary of actions:"
+ echo "- A new branch '$FEATURE' was created, based on '$BASE'"
+ echo "- You are now on branch '$FEATURE'"
+ echo ""
+ echo "Now, start committing on your feature. When done, use:"
+ echo ""
+ echo " gitflow finish feature '$FEATURE'"
+}
+
+finish() {
+ parse_args "$@"
+
+ # Checks
+ gitflow_check_clean_working_tree
+ gitflow_require_branch "$FEATURE"
+ gitflow_require_branches_equal 'develop' 'origin/develop'
+
+ # All checks passed, ready to roll
+ git checkout develop
+
+ # In case there has been only a single commit in the feature branch, don't
+ # use --no-ff, since it has no extra advantages
+ FF_FLAG="--no-ff"
+ if [ "$(git rev-list develop.."$FEATURE" | wc -l)" -eq 1 ]; then
+ FF_FLAG="--ff"
+ fi
+ git merge "$FF_FLAG" "$FEATURE"
+ # TODO: How do we handle merge conflicts here??
+ git branch -d "$FEATURE"
+
+ echo ""
+ echo "Summary of actions:"
+ echo "- The feature branch '$FEATURE' was merged into 'develop'"
+ #echo "- Merge conflicts were resolved" # TODO: Add this line when it's supported
+ echo "- Feature branch '$FEATURE' has been removed"
+ echo "- You are now on branch 'develop'"
+ echo ""
+}
+
diff --git a/gitflow-hotfix b/gitflow-hotfix
new file mode 100755
index 0000000..b1e8834
--- /dev/null
+++ b/gitflow-hotfix
@@ -0,0 +1,95 @@
+#!/bin/sh
+#
+# gitflow -- A collection of Git wrapper scripts to provide high-level
+# repository operations for Vincent Driessen's branching model:
+#
+# Original blog post presenting this model is found at:
+# http://nvie.com/archives/323
+#
+# Feel free to contribute to this project at:
+# http://github.com/nvie/gitflow
+#
+# Copyright (c) 2010 by Vincent Driessen
+#
+
+usage() {
+ echo "usage: gitflow start hotfix <release>"
+ echo " gitflow finish hotfix <release>"
+ # TODO
+ #echo ""
+ #echo "options:"
+ #echo "--option Explanation"
+ #echo ""
+ #echo "start-only options:"
+ #echo "--option Explanation"
+ #echo ""
+ #echo "finish-only options:"
+ #echo "--push Push to the origin repo when finished"
+}
+
+parse_args() {
+ RELEASE="$1"
+ if [ "$RELEASE" = "" ]; then
+ echo "Missing argument <release>"
+ usage
+ exit 1
+ fi
+ HOTFIX_BRANCH="hotfix-$RELEASE"
+}
+
+start() {
+ parse_args "$@"
+
+ # Checks
+ gitflow_check_clean_working_tree
+ gitflow_require_branches_equal 'master' 'origin/master'
+ gitflow_require_branch_absent "$HOTFIX_BRANCH"
+
+ # All checks passed, ready to roll
+ git checkout -b "$HOTFIX_BRANCH" master
+
+ echo ""
+ echo "Summary of actions:"
+ echo "- A new branch '$HOTFIX_BRANCH' was created, based on 'master'"
+ echo "- You are now on branch '$HOTFIX_BRANCH'"
+ echo ""
+ echo "Follow-up actions:"
+ echo "- Bump the version number now!"
+ echo "- Start committing your hot fixes"
+ echo "- When done, run:"
+ echo ""
+ echo " gitflow finish hotfix '$HOTFIX_BRANCH'"
+}
+
+finish() {
+ parse_args "$@"
+
+ # Checks
+ gitflow_check_clean_working_tree
+
+ git fetch origin develop # TODO: Make a flag to skip these fetches
+ git fetch origin master # TODO: Make a flag to skip these fetches
+ gitflow_require_branches_equal 'master' 'origin/master'
+ gitflow_require_branches_equal 'develop' 'origin/develop'
+
+ # All checks passed, ready to roll
+ git checkout master
+ git merge --no-ff "$HOTFIX_BRANCH"
+ git tag "$RELEASE"
+ git checkout develop
+ git merge --no-ff "$HOTFIX_BRANCH"
+ git branch -d "$HOTFIX_BRANCH"
+
+ # TODO: Implement an optional push to master
+ # git push origin develop; git push origin master; git push --tags origin
+
+ echo ""
+ echo "Summary of actions:"
+ echo "- Latest objects have been fetched from 'origin'"
+ echo "- Hotfix branch has been merged into 'master'"
+ echo "- The hotfix was tagged '$RELEASE'"
+ echo "- Hotfix branch has been back-merged into 'develop'"
+ echo "- Hotfix branch '$HOTFIX_BRANCH' has been deleted"
+ echo ""
+}
+
diff --git a/gitflow-release b/gitflow-release
new file mode 100755
index 0000000..b4f2424
--- /dev/null
+++ b/gitflow-release
@@ -0,0 +1,96 @@
+#!/bin/sh
+#
+# gitflow -- A collection of Git wrapper scripts to provide high-level
+# repository operations for Vincent Driessen's branching model:
+#
+# Original blog post presenting this model is found at:
+# http://nvie.com/archives/323
+#
+# Feel free to contribute to this project at:
+# http://github.com/nvie/gitflow
+#
+# Copyright (c) 2010 by Vincent Driessen
+#
+
+usage() {
+ echo "usage: gitflow start release <release>"
+ echo " gitflow finish release <release>"
+ # TODO
+ #echo ""
+ #echo "options:"
+ #echo "--option Explanation"
+ #echo ""
+ #echo "start-only options:"
+ #echo "--bump <script>"
+ #echo " Run the given script to auto-update the version number"
+ #echo ""
+ #echo "finish-only options:"
+ #echo "--push Push to the origin repo when finished"
+}
+
+parse_args() {
+ RELEASE="$1"
+ if [ "$RELEASE" = "" ]; then
+ echo "Missing argument <release>"
+ usage
+ exit 1
+ fi
+ RELEASE_BRANCH="release-$RELEASE"
+}
+
+start() {
+ parse_args "$@"
+
+ # Checks
+ gitflow_check_clean_working_tree
+ gitflow_require_branches_equal 'develop' 'origin/develop'
+ gitflow_require_branch_absent "$RELEASE_BRANCH"
+
+ # All checks passed, ready to roll
+ git checkout -b "$RELEASE_BRANCH" develop
+
+ echo ""
+ echo "Summary of actions:"
+ echo "- A new branch '$RELEASE_BRANCH' was created, based on 'develop'"
+ echo "- You are now on branch '$RELEASE_BRANCH'"
+ echo ""
+ echo "Follow-up actions:"
+ echo "- Bump the version number now!"
+ echo "- Start committing last-minute fixes in preparing your release"
+ echo "- When done, run:"
+ echo ""
+ echo " gitflow finish release '$RELEASE_BRANCH'"
+}
+
+finish() {
+ parse_args "$@"
+
+ # Checks
+ gitflow_check_clean_working_tree
+
+ git fetch origin develop # TODO: Make a flag to skip these fetches
+ git fetch origin master # TODO: Make a flag to skip these fetches
+ gitflow_require_branches_equal 'master' 'origin/master'
+ gitflow_require_branches_equal 'develop' 'origin/develop'
+
+ # All checks passed, ready to roll
+ git checkout master
+ git merge --no-ff "$RELEASE_BRANCH"
+ git tag "$RELEASE"
+ git checkout develop
+ git merge --no-ff "$RELEASE_BRANCH"
+ git branch -d "$RELEASE_BRANCH"
+
+ # TODO: Implement an optional push to master
+ # git push origin develop; git push origin master; git push --tags origin
+
+ echo ""
+ echo "Summary of actions:"
+ echo "- Latest objects have been fetched from 'origin'"
+ echo "- Release branch has been merged into 'master'"
+ echo "- The release was tagged '$RELEASE'"
+ echo "- Release branch has been back-merged into 'develop'"
+ echo "- Release branch '$RELEASE_BRANCH' has been deleted"
+ echo ""
+}
+
diff --git a/gitflow-sh-setup b/gitflow-sh-setup
new file mode 100755
index 0000000..0826758
--- /dev/null
+++ b/gitflow-sh-setup
@@ -0,0 +1,108 @@
+#!/bin/sh
+#
+# gitflow -- A collection of Git wrapper scripts to provide high-level
+# repository operations for Vincent Driessen's branching model:
+#
+# Original blog post presenting this model is found at:
+# http://nvie.com/archives/323
+#
+# Feel free to contribute to this project at:
+# http://github.com/nvie/gitflow
+#
+# Copyright (c) 2010 by Vincent Driessen
+#
+
+# Get the git dir
+GIT_DIR=$(git rev-parse --git-dir)
+
+# Get all available branches
+LOCAL_BRANCHES=$(git branch | sed 's/^[* ] //')
+REMOTE_BRANCHES=$(git branch -r | sed 's/^[* ] //')
+ALL_BRANCHES="$LOCAL_BRANCHES\n$REMOTE_BRANCHES"
+
+warn() { echo "$@" >&2; }
+die() { warn "$@"; exit 1; }
+
+gitflow_check_clean_working_tree() {
+ if [ "$(git status 2>/dev/null | tail -n1)" != "nothing to commit (working directory clean)" ]; then
+ die "Working directory is dirty. Only use gitflow in clean working directories for your own safety."
+ fi
+}
+
+gitflow_require_local_branch() {
+ echo "$LOCAL_BRANCHES" | grep "^$1\$" 2>&1 >/dev/null
+ if [ $? -ne 0 ]; then
+ die "Local branch '$1' does not exist and is required."
+ fi
+}
+
+gitflow_require_remote_branch() {
+ echo "$REMOTE_BRANCHES" | grep "^$1\$" 2>&1 >/dev/null
+ if [ $? -ne 0 ]; then
+ die "Remote branch '$1' does not exist and is required."
+ fi
+}
+
+gitflow_require_branch() {
+ echo "$ALL_BRANCHES" | grep "^$1\$" 2>&1 >/dev/null
+ if [ $? -ne 0 ]; then
+ die "Branch '$1' does not exist and is required."
+ fi
+}
+
+gitflow_require_branch_absent() {
+ echo "$ALL_BRANCHES" | grep "^$1\$" 2>&1 >/dev/null
+ if [ $? -eq 0 ]; then
+ die "Branch '$1' already exists. Pick another name."
+ fi
+}
+
+#
+# gitflow_test_branches_equal()
+#
+# Tests whether branches and their "origin" counterparts have diverged and need
+# merging first. It returns error codes to provide more detail, like so:
+#
+# 0 Branch heads point to the same commit
+# 1 First given branch needs fast-forwarding
+# 2 Second given branch needs fast-forwarding
+# 3 Branch needs a real merge
+#
+gitflow_test_branches_equal() {
+ commit1=$(git rev-parse "$1")
+ commit2=$(git rev-parse "$2")
+ if [ "$commit1" != "$commit2" ]; then
+ base=$(git merge-base "$commit1" "$commit2")
+ short_base=$(git rev-parse --short "$base")
+
+ if [ "$commit1" = "$base" ]; then
+ return 1
+ elif [ "$commit2" = "$base" ]; then
+ return 2
+ else
+ return 3
+ fi
+ else
+ return 0
+ fi
+}
+
+gitflow_require_branches_equal() {
+ gitflow_require_local_branch "$1"
+ gitflow_require_remote_branch "$2"
+ gitflow_test_branches_equal "$1" "$2"
+ status=$?
+ if [ $status -gt 0 ]; then
+ warn "Branches '$1' and '$2' have diverged."
+
+ if [ $status -eq 1 ]; then
+ die "And branch '$1' may be fast-forwarded."
+ elif [ $status -eq 2 ]; then
+ # Warn here, since there is no harm in being ahead
+ warn "And local branch '$1' is ahead of '$2'."
+ else
+ die "Branches need merging first."
+ fi
+ fi
+}
+
diff --git a/gitflow-version b/gitflow-version
new file mode 100644
index 0000000..c375924
--- /dev/null
+++ b/gitflow-version
@@ -0,0 +1 @@
+GITFLOW_VERSION=0.1