git-legacy-stash.shon commit The sixth batch (14c0f8d)
   1#!/bin/sh
   2# Copyright (c) 2007, Nanako Shiraishi
   3
   4dashless=$(basename "$0" | sed -e 's/-/ /')
   5USAGE="list [<options>]
   6   or: $dashless show [<stash>]
   7   or: $dashless drop [-q|--quiet] [<stash>]
   8   or: $dashless ( pop | apply ) [--index] [-q|--quiet] [<stash>]
   9   or: $dashless branch <branchname> [<stash>]
  10   or: $dashless save [--patch] [-k|--[no-]keep-index] [-q|--quiet]
  11                      [-u|--include-untracked] [-a|--all] [<message>]
  12   or: $dashless [push [--patch] [-k|--[no-]keep-index] [-q|--quiet]
  13                       [-u|--include-untracked] [-a|--all] [-m <message>]
  14                       [-- <pathspec>...]]
  15   or: $dashless clear"
  16
  17SUBDIRECTORY_OK=Yes
  18OPTIONS_SPEC=
  19START_DIR=$(pwd)
  20. git-sh-setup
  21require_work_tree
  22prefix=$(git rev-parse --show-prefix) || exit 1
  23cd_to_toplevel
  24
  25TMP="$GIT_DIR/.git-stash.$$"
  26TMPindex=${GIT_INDEX_FILE-"$(git rev-parse --git-path index)"}.stash.$$
  27trap 'rm -f "$TMP-"* "$TMPindex"' 0
  28
  29ref_stash=refs/stash
  30
  31if git config --get-colorbool color.interactive; then
  32       help_color="$(git config --get-color color.interactive.help 'red bold')"
  33       reset_color="$(git config --get-color '' reset)"
  34else
  35       help_color=
  36       reset_color=
  37fi
  38
  39no_changes () {
  40        git diff-index --quiet --cached HEAD --ignore-submodules -- "$@" &&
  41        git diff-files --quiet --ignore-submodules -- "$@" &&
  42        (test -z "$untracked" || test -z "$(untracked_files "$@")")
  43}
  44
  45untracked_files () {
  46        if test "$1" = "-z"
  47        then
  48                shift
  49                z=-z
  50        else
  51                z=
  52        fi
  53        excl_opt=--exclude-standard
  54        test "$untracked" = "all" && excl_opt=
  55        git ls-files -o $z $excl_opt -- "$@"
  56}
  57
  58prepare_fallback_ident () {
  59        if ! git -c user.useconfigonly=yes var GIT_COMMITTER_IDENT >/dev/null 2>&1
  60        then
  61                GIT_AUTHOR_NAME="git stash"
  62                GIT_AUTHOR_EMAIL=git@stash
  63                GIT_COMMITTER_NAME="git stash"
  64                GIT_COMMITTER_EMAIL=git@stash
  65                export GIT_AUTHOR_NAME
  66                export GIT_AUTHOR_EMAIL
  67                export GIT_COMMITTER_NAME
  68                export GIT_COMMITTER_EMAIL
  69        fi
  70}
  71
  72clear_stash () {
  73        if test $# != 0
  74        then
  75                die "$(gettext "git stash clear with parameters is unimplemented")"
  76        fi
  77        if current=$(git rev-parse --verify --quiet $ref_stash)
  78        then
  79                git update-ref -d $ref_stash $current
  80        fi
  81}
  82
  83maybe_quiet () {
  84        case "$1" in
  85        --keep-stdout)
  86                shift
  87                if test -n "$GIT_QUIET"
  88                then
  89                        "$@" 2>/dev/null
  90                else
  91                        "$@"
  92                fi
  93                ;;
  94        *)
  95                if test -n "$GIT_QUIET"
  96                then
  97                        "$@" >/dev/null 2>&1
  98                else
  99                        "$@"
 100                fi
 101                ;;
 102        esac
 103}
 104
 105create_stash () {
 106
 107        prepare_fallback_ident
 108
 109        stash_msg=
 110        untracked=
 111        while test $# != 0
 112        do
 113                case "$1" in
 114                -m|--message)
 115                        shift
 116                        stash_msg=${1?"BUG: create_stash () -m requires an argument"}
 117                        ;;
 118                -m*)
 119                        stash_msg=${1#-m}
 120                        ;;
 121                --message=*)
 122                        stash_msg=${1#--message=}
 123                        ;;
 124                -u|--include-untracked)
 125                        shift
 126                        untracked=${1?"BUG: create_stash () -u requires an argument"}
 127                        ;;
 128                --)
 129                        shift
 130                        break
 131                        ;;
 132                esac
 133                shift
 134        done
 135
 136        git update-index -q --refresh
 137        if maybe_quiet no_changes "$@"
 138        then
 139                exit 0
 140        fi
 141
 142        # state of the base commit
 143        if b_commit=$(maybe_quiet --keep-stdout git rev-parse --verify HEAD)
 144        then
 145                head=$(git rev-list --oneline -n 1 HEAD --)
 146        elif test -n "$GIT_QUIET"
 147        then
 148                exit 1
 149        else
 150                die "$(gettext "You do not have the initial commit yet")"
 151        fi
 152
 153        if branch=$(git symbolic-ref -q HEAD)
 154        then
 155                branch=${branch#refs/heads/}
 156        else
 157                branch='(no branch)'
 158        fi
 159        msg=$(printf '%s: %s' "$branch" "$head")
 160
 161        # state of the index
 162        i_tree=$(git write-tree) &&
 163        i_commit=$(printf 'index on %s\n' "$msg" |
 164                git commit-tree $i_tree -p $b_commit) ||
 165                die "$(gettext "Cannot save the current index state")"
 166
 167        if test -n "$untracked"
 168        then
 169                # Untracked files are stored by themselves in a parentless commit, for
 170                # ease of unpacking later.
 171                u_commit=$(
 172                        untracked_files -z "$@" | (
 173                                GIT_INDEX_FILE="$TMPindex" &&
 174                                export GIT_INDEX_FILE &&
 175                                rm -f "$TMPindex" &&
 176                                git update-index -z --add --remove --stdin &&
 177                                u_tree=$(git write-tree) &&
 178                                printf 'untracked files on %s\n' "$msg" | git commit-tree $u_tree  &&
 179                                rm -f "$TMPindex"
 180                ) ) || die "$(gettext "Cannot save the untracked files")"
 181
 182                untracked_commit_option="-p $u_commit";
 183        else
 184                untracked_commit_option=
 185        fi
 186
 187        if test -z "$patch_mode"
 188        then
 189
 190                # state of the working tree
 191                w_tree=$( (
 192                        git read-tree --index-output="$TMPindex" -m $i_tree &&
 193                        GIT_INDEX_FILE="$TMPindex" &&
 194                        export GIT_INDEX_FILE &&
 195                        git diff-index --name-only -z HEAD -- "$@" >"$TMP-stagenames" &&
 196                        git update-index -z --add --remove --stdin <"$TMP-stagenames" &&
 197                        git write-tree &&
 198                        rm -f "$TMPindex"
 199                ) ) ||
 200                        die "$(gettext "Cannot save the current worktree state")"
 201
 202        else
 203
 204                rm -f "$TMP-index" &&
 205                GIT_INDEX_FILE="$TMP-index" git read-tree HEAD &&
 206
 207                # find out what the user wants
 208                GIT_INDEX_FILE="$TMP-index" \
 209                        git add--interactive --patch=stash -- "$@" &&
 210
 211                # state of the working tree
 212                w_tree=$(GIT_INDEX_FILE="$TMP-index" git write-tree) ||
 213                die "$(gettext "Cannot save the current worktree state")"
 214
 215                git diff-tree -p HEAD $w_tree -- >"$TMP-patch" &&
 216                test -s "$TMP-patch" ||
 217                die "$(gettext "No changes selected")"
 218
 219                rm -f "$TMP-index" ||
 220                die "$(gettext "Cannot remove temporary index (can't happen)")"
 221
 222        fi
 223
 224        # create the stash
 225        if test -z "$stash_msg"
 226        then
 227                stash_msg=$(printf 'WIP on %s' "$msg")
 228        else
 229                stash_msg=$(printf 'On %s: %s' "$branch" "$stash_msg")
 230        fi
 231        w_commit=$(printf '%s\n' "$stash_msg" |
 232        git commit-tree $w_tree -p $b_commit -p $i_commit $untracked_commit_option) ||
 233        die "$(gettext "Cannot record working tree state")"
 234}
 235
 236store_stash () {
 237        while test $# != 0
 238        do
 239                case "$1" in
 240                -m|--message)
 241                        shift
 242                        stash_msg="$1"
 243                        ;;
 244                -m*)
 245                        stash_msg=${1#-m}
 246                        ;;
 247                --message=*)
 248                        stash_msg=${1#--message=}
 249                        ;;
 250                -q|--quiet)
 251                        quiet=t
 252                        ;;
 253                *)
 254                        break
 255                        ;;
 256                esac
 257                shift
 258        done
 259        test $# = 1 ||
 260        die "$(eval_gettext "\"$dashless store\" requires one <commit> argument")"
 261
 262        w_commit="$1"
 263        if test -z "$stash_msg"
 264        then
 265                stash_msg="Created via \"git stash store\"."
 266        fi
 267
 268        git update-ref --create-reflog -m "$stash_msg" $ref_stash $w_commit
 269        ret=$?
 270        test $ret != 0 && test -z "$quiet" &&
 271        die "$(eval_gettext "Cannot update \$ref_stash with \$w_commit")"
 272        return $ret
 273}
 274
 275push_stash () {
 276        keep_index=
 277        patch_mode=
 278        untracked=
 279        stash_msg=
 280        while test $# != 0
 281        do
 282                case "$1" in
 283                -k|--keep-index)
 284                        keep_index=t
 285                        ;;
 286                --no-keep-index)
 287                        keep_index=n
 288                        ;;
 289                -p|--patch)
 290                        patch_mode=t
 291                        # only default to keep if we don't already have an override
 292                        test -z "$keep_index" && keep_index=t
 293                        ;;
 294                -q|--quiet)
 295                        GIT_QUIET=t
 296                        ;;
 297                -u|--include-untracked)
 298                        untracked=untracked
 299                        ;;
 300                -a|--all)
 301                        untracked=all
 302                        ;;
 303                -m|--message)
 304                        shift
 305                        test -z ${1+x} && usage
 306                        stash_msg=$1
 307                        ;;
 308                -m*)
 309                        stash_msg=${1#-m}
 310                        ;;
 311                --message=*)
 312                        stash_msg=${1#--message=}
 313                        ;;
 314                --help)
 315                        show_help
 316                        ;;
 317                --)
 318                        shift
 319                        break
 320                        ;;
 321                -*)
 322                        option="$1"
 323                        eval_gettextln "error: unknown option for 'stash push': \$option"
 324                        usage
 325                        ;;
 326                *)
 327                        break
 328                        ;;
 329                esac
 330                shift
 331        done
 332
 333        eval "set $(git rev-parse --sq --prefix "$prefix" -- "$@")"
 334
 335        if test -n "$patch_mode" && test -n "$untracked"
 336        then
 337                die "$(gettext "Can't use --patch and --include-untracked or --all at the same time")"
 338        fi
 339
 340        test -n "$untracked" || git ls-files --error-unmatch -- "$@" >/dev/null || exit 1
 341
 342        git update-index -q --refresh
 343        if maybe_quiet no_changes "$@"
 344        then
 345                say "$(gettext "No local changes to save")"
 346                exit 0
 347        fi
 348
 349        git reflog exists $ref_stash ||
 350                clear_stash || die "$(gettext "Cannot initialize stash")"
 351
 352        create_stash -m "$stash_msg" -u "$untracked" -- "$@"
 353        store_stash -m "$stash_msg" -q $w_commit ||
 354        die "$(gettext "Cannot save the current status")"
 355        say "$(eval_gettext "Saved working directory and index state \$stash_msg")"
 356
 357        if test -z "$patch_mode"
 358        then
 359                test "$untracked" = "all" && CLEAN_X_OPTION=-x || CLEAN_X_OPTION=
 360                if test -n "$untracked" && test $# = 0
 361                then
 362                        git clean --force --quiet -d $CLEAN_X_OPTION
 363                fi
 364
 365                if test $# != 0
 366                then
 367                        test -z "$untracked" && UPDATE_OPTION="-u" || UPDATE_OPTION=
 368                        test "$untracked" = "all" && FORCE_OPTION="--force" || FORCE_OPTION=
 369                        git add $UPDATE_OPTION $FORCE_OPTION -- "$@"
 370                        git diff-index -p --cached --binary HEAD -- "$@" |
 371                        git apply --index -R
 372                else
 373                        git reset --hard -q
 374                fi
 375
 376                if test "$keep_index" = "t" && test -n "$i_tree"
 377                then
 378                        git read-tree --reset $i_tree
 379                        git ls-files -z --modified -- "$@" |
 380                        git checkout-index -z --force --stdin
 381                fi
 382        else
 383                git apply -R < "$TMP-patch" ||
 384                die "$(gettext "Cannot remove worktree changes")"
 385
 386                if test "$keep_index" != "t"
 387                then
 388                        git reset -q -- "$@"
 389                fi
 390        fi
 391}
 392
 393save_stash () {
 394        push_options=
 395        while test $# != 0
 396        do
 397                case "$1" in
 398                -q|--quiet)
 399                        GIT_QUIET=t
 400                        ;;
 401                --)
 402                        shift
 403                        break
 404                        ;;
 405                -*)
 406                        # pass all options through to push_stash
 407                        push_options="$push_options $1"
 408                        ;;
 409                *)
 410                        break
 411                        ;;
 412                esac
 413                shift
 414        done
 415
 416        stash_msg="$*"
 417
 418        if test -z "$stash_msg"
 419        then
 420                push_stash $push_options
 421        else
 422                push_stash $push_options -m "$stash_msg"
 423        fi
 424}
 425
 426have_stash () {
 427        git rev-parse --verify --quiet $ref_stash >/dev/null
 428}
 429
 430list_stash () {
 431        have_stash || return 0
 432        git log --format="%gd: %gs" -g --first-parent -m "$@" $ref_stash --
 433}
 434
 435show_stash () {
 436        ALLOW_UNKNOWN_FLAGS=t
 437        assert_stash_like "$@"
 438
 439        if test -z "$FLAGS"
 440        then
 441                if test "$(git config --bool stash.showStat || echo true)" = "true"
 442                then
 443                        FLAGS=--stat
 444                fi
 445
 446                if test "$(git config --bool stash.showPatch || echo false)" = "true"
 447                then
 448                        FLAGS=${FLAGS}${FLAGS:+ }-p
 449                fi
 450
 451                if test -z "$FLAGS"
 452                then
 453                        return 0
 454                fi
 455        fi
 456
 457        git diff ${FLAGS} $b_commit $w_commit
 458}
 459
 460show_help () {
 461        exec git help stash
 462        exit 1
 463}
 464
 465#
 466# Parses the remaining options looking for flags and
 467# at most one revision defaulting to ${ref_stash}@{0}
 468# if none found.
 469#
 470# Derives related tree and commit objects from the
 471# revision, if one is found.
 472#
 473# stash records the work tree, and is a merge between the
 474# base commit (first parent) and the index tree (second parent).
 475#
 476#   REV is set to the symbolic version of the specified stash-like commit
 477#   IS_STASH_LIKE is non-blank if ${REV} looks like a stash
 478#   IS_STASH_REF is non-blank if the ${REV} looks like a stash ref
 479#   s is set to the SHA1 of the stash commit
 480#   w_commit is set to the commit containing the working tree
 481#   b_commit is set to the base commit
 482#   i_commit is set to the commit containing the index tree
 483#   u_commit is set to the commit containing the untracked files tree
 484#   w_tree is set to the working tree
 485#   b_tree is set to the base tree
 486#   i_tree is set to the index tree
 487#   u_tree is set to the untracked files tree
 488#
 489#   GIT_QUIET is set to t if -q is specified
 490#   INDEX_OPTION is set to --index if --index is specified.
 491#   FLAGS is set to the remaining flags (if allowed)
 492#
 493# dies if:
 494#   * too many revisions specified
 495#   * no revision is specified and there is no stash stack
 496#   * a revision is specified which cannot be resolve to a SHA1
 497#   * a non-existent stash reference is specified
 498#   * unknown flags were set and ALLOW_UNKNOWN_FLAGS is not "t"
 499#
 500
 501parse_flags_and_rev()
 502{
 503        test "$PARSE_CACHE" = "$*" && return 0 # optimisation
 504        PARSE_CACHE="$*"
 505
 506        IS_STASH_LIKE=
 507        IS_STASH_REF=
 508        INDEX_OPTION=
 509        s=
 510        w_commit=
 511        b_commit=
 512        i_commit=
 513        u_commit=
 514        w_tree=
 515        b_tree=
 516        i_tree=
 517        u_tree=
 518
 519        FLAGS=
 520        REV=
 521        for opt
 522        do
 523                case "$opt" in
 524                        -q|--quiet)
 525                                GIT_QUIET=-t
 526                        ;;
 527                        --index)
 528                                INDEX_OPTION=--index
 529                        ;;
 530                        --help)
 531                                show_help
 532                        ;;
 533                        -*)
 534                                test "$ALLOW_UNKNOWN_FLAGS" = t ||
 535                                        die "$(eval_gettext "unknown option: \$opt")"
 536                                FLAGS="${FLAGS}${FLAGS:+ }$opt"
 537                        ;;
 538                        *)
 539                                REV="${REV}${REV:+ }'$opt'"
 540                        ;;
 541                esac
 542        done
 543
 544        eval set -- $REV
 545
 546        case $# in
 547                0)
 548                        have_stash || die "$(gettext "No stash entries found.")"
 549                        set -- ${ref_stash}@{0}
 550                ;;
 551                1)
 552                        :
 553                ;;
 554                *)
 555                        die "$(eval_gettext "Too many revisions specified: \$REV")"
 556                ;;
 557        esac
 558
 559        case "$1" in
 560                *[!0-9]*)
 561                        :
 562                ;;
 563                *)
 564                        set -- "${ref_stash}@{$1}"
 565                ;;
 566        esac
 567
 568        REV=$(git rev-parse --symbolic --verify --quiet "$1") || {
 569                reference="$1"
 570                die "$(eval_gettext "\$reference is not a valid reference")"
 571        }
 572
 573        i_commit=$(git rev-parse --verify --quiet "$REV^2") &&
 574        set -- $(git rev-parse "$REV" "$REV^1" "$REV:" "$REV^1:" "$REV^2:" 2>/dev/null) &&
 575        s=$1 &&
 576        w_commit=$1 &&
 577        b_commit=$2 &&
 578        w_tree=$3 &&
 579        b_tree=$4 &&
 580        i_tree=$5 &&
 581        IS_STASH_LIKE=t &&
 582        test "$ref_stash" = "$(git rev-parse --symbolic-full-name "${REV%@*}")" &&
 583        IS_STASH_REF=t
 584
 585        u_commit=$(git rev-parse --verify --quiet "$REV^3") &&
 586        u_tree=$(git rev-parse "$REV^3:" 2>/dev/null)
 587}
 588
 589is_stash_like()
 590{
 591        parse_flags_and_rev "$@"
 592        test -n "$IS_STASH_LIKE"
 593}
 594
 595assert_stash_like() {
 596        is_stash_like "$@" || {
 597                args="$*"
 598                die "$(eval_gettext "'\$args' is not a stash-like commit")"
 599        }
 600}
 601
 602is_stash_ref() {
 603        is_stash_like "$@" && test -n "$IS_STASH_REF"
 604}
 605
 606assert_stash_ref() {
 607        is_stash_ref "$@" || {
 608                args="$*"
 609                die "$(eval_gettext "'\$args' is not a stash reference")"
 610        }
 611}
 612
 613apply_stash () {
 614
 615        assert_stash_like "$@"
 616
 617        git update-index -q --refresh || die "$(gettext "unable to refresh index")"
 618
 619        # current index state
 620        c_tree=$(git write-tree) ||
 621                die "$(gettext "Cannot apply a stash in the middle of a merge")"
 622
 623        unstashed_index_tree=
 624        if test -n "$INDEX_OPTION" && test "$b_tree" != "$i_tree" &&
 625                        test "$c_tree" != "$i_tree"
 626        then
 627                git diff-tree --binary $s^2^..$s^2 | git apply --cached
 628                test $? -ne 0 &&
 629                        die "$(gettext "Conflicts in index. Try without --index.")"
 630                unstashed_index_tree=$(git write-tree) ||
 631                        die "$(gettext "Could not save index tree")"
 632                git reset
 633        fi
 634
 635        if test -n "$u_tree"
 636        then
 637                GIT_INDEX_FILE="$TMPindex" git read-tree "$u_tree" &&
 638                GIT_INDEX_FILE="$TMPindex" git checkout-index --all &&
 639                rm -f "$TMPindex" ||
 640                die "$(gettext "Could not restore untracked files from stash entry")"
 641        fi
 642
 643        eval "
 644                GITHEAD_$w_tree='Stashed changes' &&
 645                GITHEAD_$c_tree='Updated upstream' &&
 646                GITHEAD_$b_tree='Version stash was based on' &&
 647                export GITHEAD_$w_tree GITHEAD_$c_tree GITHEAD_$b_tree
 648        "
 649
 650        if test -n "$GIT_QUIET"
 651        then
 652                GIT_MERGE_VERBOSITY=0 && export GIT_MERGE_VERBOSITY
 653        fi
 654        if git merge-recursive $b_tree -- $c_tree $w_tree
 655        then
 656                # No conflict
 657                if test -n "$unstashed_index_tree"
 658                then
 659                        git read-tree "$unstashed_index_tree"
 660                else
 661                        a="$TMP-added" &&
 662                        git diff-index --cached --name-only --diff-filter=A $c_tree >"$a" &&
 663                        git read-tree --reset $c_tree &&
 664                        git update-index --add --stdin <"$a" ||
 665                                die "$(gettext "Cannot unstage modified files")"
 666                        rm -f "$a"
 667                fi
 668                squelch=
 669                if test -n "$GIT_QUIET"
 670                then
 671                        squelch='>/dev/null 2>&1'
 672                fi
 673                (cd "$START_DIR" && eval "git status $squelch") || :
 674        else
 675                # Merge conflict; keep the exit status from merge-recursive
 676                status=$?
 677                git rerere
 678                if test -n "$INDEX_OPTION"
 679                then
 680                        gettextln "Index was not unstashed." >&2
 681                fi
 682                exit $status
 683        fi
 684}
 685
 686pop_stash() {
 687        assert_stash_ref "$@"
 688
 689        if apply_stash "$@"
 690        then
 691                drop_stash "$@"
 692        else
 693                status=$?
 694                say "$(gettext "The stash entry is kept in case you need it again.")"
 695                exit $status
 696        fi
 697}
 698
 699drop_stash () {
 700        assert_stash_ref "$@"
 701
 702        git reflog delete --updateref --rewrite "${REV}" &&
 703                say "$(eval_gettext "Dropped \${REV} (\$s)")" ||
 704                die "$(eval_gettext "\${REV}: Could not drop stash entry")"
 705
 706        # clear_stash if we just dropped the last stash entry
 707        git rev-parse --verify --quiet "$ref_stash@{0}" >/dev/null ||
 708        clear_stash
 709}
 710
 711apply_to_branch () {
 712        test -n "$1" || die "$(gettext "No branch name specified")"
 713        branch=$1
 714        shift 1
 715
 716        set -- --index "$@"
 717        assert_stash_like "$@"
 718
 719        git checkout -b $branch $REV^ &&
 720        apply_stash "$@" && {
 721                test -z "$IS_STASH_REF" || drop_stash "$@"
 722        }
 723}
 724
 725test "$1" = "-p" && set "push" "$@"
 726
 727PARSE_CACHE='--not-parsed'
 728# The default command is "push" if nothing but options are given
 729seen_non_option=
 730for opt
 731do
 732        case "$opt" in
 733        --) break ;;
 734        -*) ;;
 735        *) seen_non_option=t; break ;;
 736        esac
 737done
 738
 739test -n "$seen_non_option" || set "push" "$@"
 740
 741# Main command set
 742case "$1" in
 743list)
 744        shift
 745        list_stash "$@"
 746        ;;
 747show)
 748        shift
 749        show_stash "$@"
 750        ;;
 751save)
 752        shift
 753        save_stash "$@"
 754        ;;
 755push)
 756        shift
 757        push_stash "$@"
 758        ;;
 759apply)
 760        shift
 761        apply_stash "$@"
 762        ;;
 763clear)
 764        shift
 765        clear_stash "$@"
 766        ;;
 767create)
 768        shift
 769        create_stash -m "$*" && echo "$w_commit"
 770        ;;
 771store)
 772        shift
 773        store_stash "$@"
 774        ;;
 775drop)
 776        shift
 777        drop_stash "$@"
 778        ;;
 779pop)
 780        shift
 781        pop_stash "$@"
 782        ;;
 783branch)
 784        shift
 785        apply_to_branch "$@"
 786        ;;
 787*)
 788        case $# in
 789        0)
 790                push_stash &&
 791                say "$(gettext "(To restore them type \"git stash apply\")")"
 792                ;;
 793        *)
 794                usage
 795        esac
 796        ;;
 797esac