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