1#!/bin/sh 2. git-sh-setup|| die "Not a git archive" 3 4usage () { 5 die 'Usage: git reset [--mixed | --soft | --hard] [<commit-ish>]' 6} 7 8tmp=/var/tmp/reset.$$ 9trap'rm -f$tmp-*'0 1 2 3 15 10 11reset_type=--mixed 12case"$1"in 13--mixed|--soft|--hard) 14 reset_type="$1" 15shift 16;; 17-*) 18 usage ;; 19esac 20 21rev=$(git-rev-parse --verify --default HEAD "$@")||exit 22rev=$(git-rev-parse --verify $rev^0)||exit 23 24# We need to remember the set of paths that _could_ be left 25# behind before a hard reset, so that we can remove them. 26iftest"$reset_type"="--hard" 27then 28{ 29 git-ls-files --stage -z 30 git-rev-parse --verify HEAD 2>/dev/null && 31 git-ls-tree -r -z HEAD 32} | perl -e' 33 use strict; 34 my %seen; 35 $/ = "\0"; 36 while (<>) { 37 chomp; 38 my ($info,$path) = split(/\t/,$_); 39 next if ($info=~ / tree /); 40 if (!$seen{$path}) { 41$seen{$path} = 1; 42 print "$path\0"; 43 } 44 } 45 '>$tmp-exists 46fi 47 48# Soft reset does not touch the index file nor the working tree 49# at all, but requires them in a good order. Other resets reset 50# the index file to the tree object we are switching to. 51iftest"$reset_type"="--soft" 52then 53iftest -f"$GIT_DIR/MERGE_HEAD"|| 54test""!="$(git-ls-files --unmerged)" 55then 56 die "Cannot do a soft reset in the middle of a merge." 57fi 58else 59 git-read-tree --reset"$rev"||exit 60fi 61 62# Any resets update HEAD to the head being switched to. 63if orig=$(git-rev-parse --verify HEAD 2>/dev/null) 64then 65echo"$orig">"$GIT_DIR/ORIG_HEAD" 66else 67rm-f"$GIT_DIR/ORIG_HEAD" 68fi 69git-update-ref HEAD "$rev" 70 71case"$reset_type"in 72--hard) 73# Hard reset matches the working tree to that of the tree 74# being switched to. 75 git-checkout-index -f -u -q -a 76 git-ls-files --cached -z| 77 perl -e' 78 use strict; 79 my (%keep,$fh); 80 $/ = "\0"; 81 while (<STDIN>) { 82 chomp; 83$keep{$_} = 1; 84 } 85 open$fh, "<",$ARGV[0] 86 or die "cannot open$ARGV[0]"; 87 while (<$fh>) { 88 chomp; 89 if (! exists$keep{$_}) { 90 # it is ok if this fails -- it may already 91 # have been culled by checkout-index. 92 unlink$_; 93 } 94 } 95 '$tmp-exists 96;; 97--soft) 98;;# Nothing else to do 99--mixed) 100# Report what has not been updated. 101 git-update-index --refresh 102;; 103esac 104 105rm-f"$GIT_DIR/MERGE_HEAD"