Vincent Driessen | 61ade55 | 2010-01-21 01:28:08 +0100 | [diff] [blame] | 1 | #!/bin/sh |
Vincent Driessen | 093a147 | 2010-01-21 01:36:44 +0100 | [diff] [blame] | 2 | # |
| 3 | # gitflow -- A collection of Git wrapper scripts to provide high-level |
| 4 | # repository operations for Vincent Driessen's branching model: |
| 5 | # |
| 6 | # Original blog post presenting this model is found at: |
| 7 | # http://nvie.com/archives/323 |
| 8 | # |
| 9 | # Feel free to contribute to this project at: |
| 10 | # http://github.com/nvie/gitflow |
| 11 | # |
| 12 | # Copyright (c) 2010 by Vincent Driessen |
| 13 | # |
Vincent Driessen | 61ade55 | 2010-01-21 01:28:08 +0100 | [diff] [blame] | 14 | |
Vincent Driessen | 4f1cc33 | 2010-01-25 16:44:57 +0100 | [diff] [blame] | 15 | # Get the git dir |
| 16 | GIT_DIR=$(git rev-parse --git-dir) |
| 17 | |
| 18 | # Get all available branches |
| 19 | LOCAL_BRANCHES=$(cd "$GIT_DIR/refs/heads"; find * -type f) |
| 20 | REMOTE_BRANCHES=$(cd "$GIT_DIR/refs/remotes"; find * -type f) |
| 21 | ALL_BRANCHES="$LOCAL_BRANCHES\n$REMOTE_BRANCHES" |
| 22 | |
Vincent Driessen | a0434ca | 2010-01-25 17:28:22 +0100 | [diff] [blame] | 23 | warn() { echo "$@" >&2; } |
| 24 | die() { warn "$@"; exit 1; } |
Vincent Driessen | 4f1cc33 | 2010-01-25 16:44:57 +0100 | [diff] [blame] | 25 | |
Vincent Driessen | 61ade55 | 2010-01-21 01:28:08 +0100 | [diff] [blame] | 26 | gitflow_check_clean_working_tree() { |
Vincent Driessen | a1bc871 | 2010-01-25 21:50:08 +0100 | [diff] [blame] | 27 | if [ "$(git status 2> /dev/null | tail -n1)" != "nothing to commit (working directory clean)" ]; then |
| 28 | die "Working directory is dirty. Only use gitflow in clean working directories for your own safety." |
| 29 | fi |
Vincent Driessen | 4f1cc33 | 2010-01-25 16:44:57 +0100 | [diff] [blame] | 30 | } |
| 31 | |
| 32 | gitflow_require_local_branch() { |
| 33 | echo "$LOCAL_BRANCHES" | grep "^$1\$" 2>/dev/null >/dev/null |
| 34 | if [ $? -ne 0 ]; then |
| 35 | die "Local branch '$1' does not exist and is required." |
| 36 | fi |
| 37 | } |
| 38 | |
| 39 | gitflow_require_remote_branch() { |
| 40 | echo "$REMOTE_BRANCHES" | grep "^$1\$" 2>/dev/null >/dev/null |
| 41 | if [ $? -ne 0 ]; then |
| 42 | die "Remote branch '$1' does not exist and is required." |
| 43 | fi |
| 44 | } |
| 45 | |
| 46 | gitflow_require_branch() { |
| 47 | echo "$ALL_BRANCHES" | grep "^$1\$" 2>/dev/null >/dev/null |
| 48 | if [ $? -ne 0 ]; then |
| 49 | die "Branch '$1' does not exist and is required." |
| 50 | fi |
Vincent Driessen | 61ade55 | 2010-01-21 01:28:08 +0100 | [diff] [blame] | 51 | } |
| 52 | |
Vincent Driessen | 6c9e804 | 2010-01-25 21:59:10 +0100 | [diff] [blame] | 53 | gitflow_require_branch_absent() { |
| 54 | echo "$ALL_BRANCHES" | grep "^$1\$" 2>/dev/null >/dev/null |
| 55 | if [ $? -eq 0 ]; then |
Vincent Driessen | ec2c895 | 2010-01-25 22:40:13 +0100 | [diff] [blame^] | 56 | die "Branch '$1' already exists. Pick another name." |
Vincent Driessen | 6c9e804 | 2010-01-25 21:59:10 +0100 | [diff] [blame] | 57 | fi |
| 58 | } |
| 59 | |
Vincent Driessen | afee9fd | 2010-01-25 17:29:29 +0100 | [diff] [blame] | 60 | # |
| 61 | # gitflow_test_branches_equal() |
| 62 | # |
| 63 | # Tests whether branches and their "origin" counterparts have diverged and need |
| 64 | # merging first. It returns error codes to provide more detail, like so: |
| 65 | # |
| 66 | # 0 Branch heads point to the same commit |
| 67 | # 1 First given branch needs fast-forwarding |
| 68 | # 2 Second given branch needs fast-forwarding |
| 69 | # 3 Branch needs a real merge |
| 70 | # |
| 71 | gitflow_test_branches_equal() { |
| 72 | commit1=$(git rev-parse "$1") |
| 73 | commit2=$(git rev-parse "$2") |
| 74 | if [ "$commit1" != "$commit2" ]; then |
| 75 | base=$(git merge-base "$commit1" "$commit2") |
| 76 | short_base=$(git rev-parse --short "$base") |
| 77 | |
| 78 | if [ "$commit1" = "$base" ]; then |
| 79 | return 1 |
| 80 | elif [ "$commit2" = "$base" ]; then |
| 81 | return 2 |
| 82 | else |
| 83 | return 3 |
| 84 | fi |
| 85 | else |
| 86 | return 0 |
| 87 | fi |
| 88 | } |
| 89 | |
| 90 | gitflow_require_branches_equal() { |
| 91 | gitflow_require_local_branch "$1" |
| 92 | gitflow_require_remote_branch "$2" |
| 93 | gitflow_test_branches_equal "$1" "$2" |
| 94 | status=$? |
| 95 | if [ $status -gt 0 ]; then |
| 96 | warn "Branches '$1' and '$2' have diverged." |
| 97 | |
| 98 | if [ $status -eq 1 ]; then |
| 99 | die "And branch '$1' may be fast-forwarded." |
| 100 | elif [ $status -eq 2 ]; then |
| 101 | die "And local branch '$1' is ahead of '$2'." |
| 102 | else |
| 103 | die "Branches need merging first." |
| 104 | fi |
| 105 | fi |
| 106 | } |
| 107 | |