diff --git a/git-checkout.sh b/git-checkout.sh index 679057dcbf..855cf46a2d 100755 --- a/git-checkout.sh +++ b/git-checkout.sh @@ -150,35 +150,32 @@ fi # correct, it feels somewhat funny. More importantly, we do not # want "git checkout" nor "git checkout -f" to detach HEAD. +detached= +detach_warn= + if test -z "$branch$newbranch" && test "$new" != "$old" then - # NEEDSWORK: we would want to have a command here - # that allows us to detach the HEAD atomically. Perhaps - # something like "git update-ref --detach HEAD $new" - echo "$new" >"$GIT_DIR/HEAD.new" && - mv "$GIT_DIR/HEAD.new" "$GIT_DIR/HEAD" || die "Cannot detach HEAD" - + detached="$new" if test -n "$oldbranch" then - echo >&2 "warning: you are not on ANY branch anymore. + detach_warn="warning: you are not on ANY branch anymore. If you meant to create a new branch from the commit, you need -b to associate a new branch with the wanted checkout. Example: - git checkout -b $arg -" + git checkout -b $arg" fi elif test -z "$oldbranch" && test -n "$branch" then # Coming back... if test -z "$force" then - mb=$(git merge-base --all $old $new) && - case "$LF$mb$LF" in - *"$LF$old$LF"*) : ;; - *) false ;; - esac || { + git show-ref -d -s | grep "$old" >/dev/null || { echo >&2 \ -"You are not on a branch and switching to $new_name branch may lose -your changes. Use 'git checkout -f $new_name' if you want to." +"You are not on any branch and switching to branch '$new_name' +may lose your changes. At this point, you can do one of two things: + (1) Decide it is Ok and say 'git checkout -f $new_name'; + (2) Start a new branch from the current commit, by saying + 'git checkout -b '. +Leaving your HEAD detached; not switching to branch '$new_name'." exit 1; } fi @@ -265,8 +262,25 @@ if [ "$?" -eq 0 ]; then git-update-ref -m "checkout: Created from $new_name" "refs/heads/$newbranch" $new || exit branch="$newbranch" fi - [ "$branch" ] && - GIT_DIR="$GIT_DIR" git-symbolic-ref HEAD "refs/heads/$branch" + if test -n "$branch" + then + GIT_DIR="$GIT_DIR" git-symbolic-ref HEAD "refs/heads/$branch" + elif test -n "$detached" + then + # NEEDSWORK: we would want a command to detach the HEAD + # atomically, instead of this handcrafted command sequence. + # Perhaps: + # git update-ref --detach HEAD $new + # or something like that... + # + echo "$detached" >"$GIT_DIR/HEAD.new" && + mv "$GIT_DIR/HEAD.new" "$GIT_DIR/HEAD" || + die "Cannot detach HEAD" + if test -n "$detach_warn" + then + echo >&2 "$detach_warn" + fi + fi rm -f "$GIT_DIR/MERGE_HEAD" else exit 1