| #!/bin/sh | |
| # | |
| # Copyright (c) 2005, 2006 Linus Torvalds and Junio C Hamano | |
| # | |
| USAGE='[--mixed | --soft | --hard] [<commit-ish>] [ [--] <paths>...]' | |
| SUBDIRECTORY_OK=Yes | |
| . git-sh-setup | |
| set_reflog_action "reset $*" | |
| require_work_tree | |
| update= reset_type=--mixed | |
| unset rev | |
| while test $# != 0 | |
| do | |
| case "$1" in | |
| --mixed | --soft | --hard) | |
| reset_type="$1" | |
| ;; | |
| --) | |
| break | |
| ;; | |
| -*) | |
| usage | |
| ;; | |
| *) | |
| rev=$(git rev-parse --verify "$1") || exit | |
| shift | |
| break | |
| ;; | |
| esac | |
| shift | |
| done | |
| : ${rev=HEAD} | |
| rev=$(git rev-parse --verify $rev^0) || exit | |
| # Skip -- in "git reset HEAD -- foo" and "git reset -- foo". | |
| case "$1" in --) shift ;; esac | |
| # git reset --mixed tree [--] paths... can be used to | |
| # load chosen paths from the tree into the index without | |
| # affecting the working tree or HEAD. | |
| if test $# != 0 | |
| then | |
| test "$reset_type" = "--mixed" || | |
| die "Cannot do partial $reset_type reset." | |
| git diff-index --cached $rev -- "$@" | | |
| sed -e 's/^:\([0-7][0-7]*\) [0-7][0-7]* \([0-9a-f][0-9a-f]*\) [0-9a-f][0-9a-f]* [A-Z] \(.*\)$/\1 \2 \3/' | | |
| git update-index --add --remove --index-info || exit | |
| git update-index --refresh | |
| exit | |
| fi | |
| cd_to_toplevel | |
| if test "$reset_type" = "--hard" | |
| then | |
| update=-u | |
| fi | |
| # Soft reset does not touch the index file or the working tree | |
| # at all, but requires them in a good order. Other resets reset | |
| # the index file to the tree object we are switching to. | |
| if test "$reset_type" = "--soft" | |
| then | |
| if test -f "$GIT_DIR/MERGE_HEAD" || | |
| test "" != "$(git ls-files --unmerged)" | |
| then | |
| die "Cannot do a soft reset in the middle of a merge." | |
| fi | |
| else | |
| git read-tree -v --reset $update "$rev" || exit | |
| fi | |
| # Any resets update HEAD to the head being switched to. | |
| if orig=$(git rev-parse --verify HEAD 2>/dev/null) | |
| then | |
| echo "$orig" >"$GIT_DIR/ORIG_HEAD" | |
| else | |
| rm -f "$GIT_DIR/ORIG_HEAD" | |
| fi | |
| git update-ref -m "$GIT_REFLOG_ACTION" HEAD "$rev" | |
| update_ref_status=$? | |
| case "$reset_type" in | |
| --hard ) | |
| test $update_ref_status = 0 && { | |
| printf "HEAD is now at " | |
| GIT_PAGER= git log --max-count=1 --pretty=oneline \ | |
| --abbrev-commit HEAD | |
| } | |
| ;; | |
| --soft ) | |
| ;; # Nothing else to do | |
| --mixed ) | |
| # Report what has not been updated. | |
| git update-index --refresh | |
| ;; | |
| esac | |
| rm -f "$GIT_DIR/MERGE_HEAD" "$GIT_DIR/rr-cache/MERGE_RR" \ | |
| "$GIT_DIR/SQUASH_MSG" "$GIT_DIR/MERGE_MSG" | |
| exit $update_ref_status |