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