git-checkout.shon commit Merge branch 'fixes' (8ac3a61)
   1#!/bin/sh
   2. git-sh-setup || die "Not a git archive"
   3
   4old=$(git-rev-parse HEAD)
   5new=
   6force=
   7branch=
   8newbranch=
   9while [ "$#" != "0" ]; do
  10    arg="$1"
  11    shift
  12    case "$arg" in
  13        "-b")
  14                newbranch="$1"
  15                shift
  16                [ -z "$newbranch" ] &&
  17                        die "git checkout: -b needs a branch name"
  18                [ -e "$GIT_DIR/refs/heads/$newbranch" ] &&
  19                        die "git checkout: branch $newbranch already exists"
  20                git-check-ref-format "heads/$newbranch" ||
  21                        die "we do not like '$newbranch' as a branch name."
  22                ;;
  23        "-f")
  24                force=1
  25                ;;
  26        --)
  27                break
  28                ;;
  29        *)
  30                if rev=$(git-rev-parse --verify "$arg^0" 2>/dev/null)
  31                then
  32                        if [ -z "$rev" ]; then
  33                                echo "unknown flag $arg"
  34                                exit 1
  35                        fi
  36                        new="$rev"
  37                        if [ -f "$GIT_DIR/refs/heads/$arg" ]; then
  38                                branch="$arg"
  39                        fi
  40                elif rev=$(git-rev-parse --verify "$arg^{tree}" 2>/dev/null)
  41                then
  42                        # checking out selected paths from a tree-ish.
  43                        new="$rev"
  44                        branch=
  45                else
  46                        new=
  47                        branch=
  48                        set x "$arg" "$@"
  49                        shift
  50                fi
  51                break
  52                ;;
  53    esac
  54done
  55
  56# The behaviour of the command with and without explicit path
  57# parameters is quite different.
  58#
  59# Without paths, we are checking out everything in the work tree,
  60# possibly switching branches.  This is the traditional behaviour.
  61#
  62# With paths, we are _never_ switching branch, but checking out
  63# the named paths from either index (when no rev is given),
  64# or the named tree-ish (when rev is given).
  65
  66if test "$#" -ge 1
  67then
  68        if test '' != "$newbranch$force"
  69        then
  70                die "updating paths and switching branches or forcing are incompatible."
  71        fi
  72        if test '' != "$new"
  73        then
  74                # from a specific tree-ish; note that this is for
  75                # rescuing paths and is never meant to remove what
  76                # is not in the named tree-ish.
  77                git-ls-tree -r "$new" "$@" |
  78                sed -ne 's/^\([0-7]*\) blob \(.*\)$/\1 \2/p' |
  79                git-update-index --index-info || exit $?
  80        fi
  81        git-checkout-index -f -u -- "$@"
  82        exit $?
  83else
  84        # Make sure we did not fall back on $arg^{tree} codepath
  85        # since we are not checking out from an arbitrary tree-ish,
  86        # but switching branches.
  87        if test '' != "$new"
  88        then
  89                git-rev-parse --verify "$new^{commit}" >/dev/null 2>&1 ||
  90                die "Cannot switch branch to a non-commit."
  91        fi
  92fi
  93
  94[ -z "$new" ] && new=$old
  95
  96# If we don't have an old branch that we're switching to,
  97# and we don't have a new branch name for the target we
  98# are switching to, then we'd better just be checking out
  99# what we already had
 100
 101[ -z "$branch$newbranch" ] &&
 102        [ "$new" != "$old" ] &&
 103        die "git checkout: you need to specify a new branch name"
 104
 105if [ "$force" ]
 106then
 107    git-read-tree --reset $new &&
 108        git-checkout-index -q -f -u -a
 109else
 110    git-update-index --refresh >/dev/null
 111    git-read-tree -m -u $old $new
 112fi
 113
 114# 
 115# Switch the HEAD pointer to the new branch if it we
 116# checked out a branch head, and remove any potential
 117# old MERGE_HEAD's (subsequent commits will clearly not
 118# be based on them, since we re-set the index)
 119#
 120if [ "$?" -eq 0 ]; then
 121        if [ "$newbranch" ]; then
 122                echo $new > "$GIT_DIR/refs/heads/$newbranch"
 123                branch="$newbranch"
 124        fi
 125        [ "$branch" ] &&
 126        GIT_DIR="$GIT_DIR" git-symbolic-ref HEAD "refs/heads/$branch"
 127        rm -f "$GIT_DIR/MERGE_HEAD"
 128else
 129        exit 1
 130fi