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" 11shift 12case"$arg"in 13"-b") 14 newbranch="$1" 15shift 16[-z"$newbranch"] && 17 die "git checkout: -b needs a branch name" 18[-e"$GIT_DIR/refs/heads/$newbranch"] && 19 die "git checkout: branch$newbranchalready 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--) 27break 28;; 29*) 30ifrev=$(git-rev-parse --verify "$arg^0" 2>/dev/null) 31then 32if[-z"$rev"];then 33echo"unknown flag$arg" 34exit1 35fi 36 new="$rev" 37if[-f"$GIT_DIR/refs/heads/$arg"];then 38 branch="$arg" 39fi 40elifrev=$(git-rev-parse --verify "$arg^{tree}" 2>/dev/null) 41then 42# checking out selected paths from a tree-ish. 43 new="$rev" 44 branch= 45else 46 new= 47 branch= 48set x "$arg""$@" 49shift 50fi 51break 52;; 53esac 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 66iftest"$#"-ge1 67then 68iftest''!="$newbranch$force" 69then 70 die "updating paths and switching branches or forcing are incompatible." 71fi 72iftest''!="$new" 73then 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""$@"| 78sed-ne's/^\([0-7]*\) blob \(.*\)$/\1 \2/p'| 79 git-update-index --index-info||exit $? 80fi 81 git-checkout-index -f -u --"$@" 82exit $? 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. 87iftest''!="$new" 88then 89 git-rev-parse --verify"$new^{commit}">/dev/null 2>&1|| 90 die "Cannot switch branch to a non-commit." 91fi 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["$?"-eq0];then 121if["$newbranch"];then 122echo$new>"$GIT_DIR/refs/heads/$newbranch" 123 branch="$newbranch" 124fi 125["$branch"] && 126 GIT_DIR="$GIT_DIR" git-symbolic-ref HEAD "refs/heads/$branch" 127rm-f"$GIT_DIR/MERGE_HEAD" 128else 129exit1 130fi