builtin / stash--helper.con commit stash: convert push to builtin (d553f53)
   1#include "builtin.h"
   2#include "config.h"
   3#include "parse-options.h"
   4#include "refs.h"
   5#include "lockfile.h"
   6#include "cache-tree.h"
   7#include "unpack-trees.h"
   8#include "merge-recursive.h"
   9#include "argv-array.h"
  10#include "run-command.h"
  11#include "dir.h"
  12#include "rerere.h"
  13#include "revision.h"
  14#include "log-tree.h"
  15#include "diffcore.h"
  16
  17#define INCLUDE_ALL_FILES 2
  18
  19static const char * const git_stash_helper_usage[] = {
  20        N_("git stash--helper list [<options>]"),
  21        N_("git stash--helper show [<options>] [<stash>]"),
  22        N_("git stash--helper drop [-q|--quiet] [<stash>]"),
  23        N_("git stash--helper ( pop | apply ) [--index] [-q|--quiet] [<stash>]"),
  24        N_("git stash--helper branch <branchname> [<stash>]"),
  25        N_("git stash--helper clear"),
  26        N_("git stash--helper [push [-p|--patch] [-k|--[no-]keep-index] [-q|--quiet]\n"
  27           "          [-u|--include-untracked] [-a|--all] [-m|--message <message>]\n"
  28           "          [--] [<pathspec>...]]"),
  29        NULL
  30};
  31
  32static const char * const git_stash_helper_list_usage[] = {
  33        N_("git stash--helper list [<options>]"),
  34        NULL
  35};
  36
  37static const char * const git_stash_helper_show_usage[] = {
  38        N_("git stash--helper show [<options>] [<stash>]"),
  39        NULL
  40};
  41
  42static const char * const git_stash_helper_drop_usage[] = {
  43        N_("git stash--helper drop [-q|--quiet] [<stash>]"),
  44        NULL
  45};
  46
  47static const char * const git_stash_helper_pop_usage[] = {
  48        N_("git stash--helper pop [--index] [-q|--quiet] [<stash>]"),
  49        NULL
  50};
  51
  52static const char * const git_stash_helper_apply_usage[] = {
  53        N_("git stash--helper apply [--index] [-q|--quiet] [<stash>]"),
  54        NULL
  55};
  56
  57static const char * const git_stash_helper_branch_usage[] = {
  58        N_("git stash--helper branch <branchname> [<stash>]"),
  59        NULL
  60};
  61
  62static const char * const git_stash_helper_clear_usage[] = {
  63        N_("git stash--helper clear"),
  64        NULL
  65};
  66
  67static const char * const git_stash_helper_store_usage[] = {
  68        N_("git stash--helper store [-m|--message <message>] [-q|--quiet] <commit>"),
  69        NULL
  70};
  71
  72static const char * const git_stash_helper_create_usage[] = {
  73        N_("git stash--helper create [<message>]"),
  74        NULL
  75};
  76
  77static const char * const git_stash_helper_push_usage[] = {
  78        N_("git stash--helper [push [-p|--patch] [-k|--[no-]keep-index] [-q|--quiet]\n"
  79           "          [-u|--include-untracked] [-a|--all] [-m|--message <message>]\n"
  80           "          [--] [<pathspec>...]]"),
  81        NULL
  82};
  83
  84static const char *ref_stash = "refs/stash";
  85static struct strbuf stash_index_path = STRBUF_INIT;
  86
  87/*
  88 * w_commit is set to the commit containing the working tree
  89 * b_commit is set to the base commit
  90 * i_commit is set to the commit containing the index tree
  91 * u_commit is set to the commit containing the untracked files tree
  92 * w_tree is set to the working tree
  93 * b_tree is set to the base tree
  94 * i_tree is set to the index tree
  95 * u_tree is set to the untracked files tree
  96 */
  97struct stash_info {
  98        struct object_id w_commit;
  99        struct object_id b_commit;
 100        struct object_id i_commit;
 101        struct object_id u_commit;
 102        struct object_id w_tree;
 103        struct object_id b_tree;
 104        struct object_id i_tree;
 105        struct object_id u_tree;
 106        struct strbuf revision;
 107        int is_stash_ref;
 108        int has_u;
 109};
 110
 111static void free_stash_info(struct stash_info *info)
 112{
 113        strbuf_release(&info->revision);
 114}
 115
 116static void assert_stash_like(struct stash_info *info, const char *revision)
 117{
 118        if (get_oidf(&info->b_commit, "%s^1", revision) ||
 119            get_oidf(&info->w_tree, "%s:", revision) ||
 120            get_oidf(&info->b_tree, "%s^1:", revision) ||
 121            get_oidf(&info->i_tree, "%s^2:", revision))
 122                die(_("'%s' is not a stash-like commit"), revision);
 123}
 124
 125static int get_stash_info(struct stash_info *info, int argc, const char **argv)
 126{
 127        int ret;
 128        char *end_of_rev;
 129        char *expanded_ref;
 130        const char *revision;
 131        const char *commit = NULL;
 132        struct object_id dummy;
 133        struct strbuf symbolic = STRBUF_INIT;
 134
 135        if (argc > 1) {
 136                int i;
 137                struct strbuf refs_msg = STRBUF_INIT;
 138
 139                for (i = 0; i < argc; i++)
 140                        strbuf_addf(&refs_msg, " '%s'", argv[i]);
 141
 142                fprintf_ln(stderr, _("Too many revisions specified:%s"),
 143                           refs_msg.buf);
 144                strbuf_release(&refs_msg);
 145
 146                return -1;
 147        }
 148
 149        if (argc == 1)
 150                commit = argv[0];
 151
 152        strbuf_init(&info->revision, 0);
 153        if (!commit) {
 154                if (!ref_exists(ref_stash)) {
 155                        free_stash_info(info);
 156                        fprintf_ln(stderr, _("No stash entries found."));
 157                        return -1;
 158                }
 159
 160                strbuf_addf(&info->revision, "%s@{0}", ref_stash);
 161        } else if (strspn(commit, "0123456789") == strlen(commit)) {
 162                strbuf_addf(&info->revision, "%s@{%s}", ref_stash, commit);
 163        } else {
 164                strbuf_addstr(&info->revision, commit);
 165        }
 166
 167        revision = info->revision.buf;
 168
 169        if (get_oid(revision, &info->w_commit)) {
 170                error(_("%s is not a valid reference"), revision);
 171                free_stash_info(info);
 172                return -1;
 173        }
 174
 175        assert_stash_like(info, revision);
 176
 177        info->has_u = !get_oidf(&info->u_tree, "%s^3:", revision);
 178
 179        end_of_rev = strchrnul(revision, '@');
 180        strbuf_add(&symbolic, revision, end_of_rev - revision);
 181
 182        ret = dwim_ref(symbolic.buf, symbolic.len, &dummy, &expanded_ref);
 183        strbuf_release(&symbolic);
 184        switch (ret) {
 185        case 0: /* Not found, but valid ref */
 186                info->is_stash_ref = 0;
 187                break;
 188        case 1:
 189                info->is_stash_ref = !strcmp(expanded_ref, ref_stash);
 190                break;
 191        default: /* Invalid or ambiguous */
 192                free_stash_info(info);
 193        }
 194
 195        free(expanded_ref);
 196        return !(ret == 0 || ret == 1);
 197}
 198
 199static int do_clear_stash(void)
 200{
 201        struct object_id obj;
 202        if (get_oid(ref_stash, &obj))
 203                return 0;
 204
 205        return delete_ref(NULL, ref_stash, &obj, 0);
 206}
 207
 208static int clear_stash(int argc, const char **argv, const char *prefix)
 209{
 210        struct option options[] = {
 211                OPT_END()
 212        };
 213
 214        argc = parse_options(argc, argv, prefix, options,
 215                             git_stash_helper_clear_usage,
 216                             PARSE_OPT_STOP_AT_NON_OPTION);
 217
 218        if (argc)
 219                return error(_("git stash clear with parameters is "
 220                               "unimplemented"));
 221
 222        return do_clear_stash();
 223}
 224
 225static int reset_tree(struct object_id *i_tree, int update, int reset)
 226{
 227        int nr_trees = 1;
 228        struct unpack_trees_options opts;
 229        struct tree_desc t[MAX_UNPACK_TREES];
 230        struct tree *tree;
 231        struct lock_file lock_file = LOCK_INIT;
 232
 233        read_cache_preload(NULL);
 234        if (refresh_cache(REFRESH_QUIET))
 235                return -1;
 236
 237        hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);
 238
 239        memset(&opts, 0, sizeof(opts));
 240
 241        tree = parse_tree_indirect(i_tree);
 242        if (parse_tree(tree))
 243                return -1;
 244
 245        init_tree_desc(t, tree->buffer, tree->size);
 246
 247        opts.head_idx = 1;
 248        opts.src_index = &the_index;
 249        opts.dst_index = &the_index;
 250        opts.merge = 1;
 251        opts.reset = reset;
 252        opts.update = update;
 253        opts.fn = oneway_merge;
 254
 255        if (unpack_trees(nr_trees, t, &opts))
 256                return -1;
 257
 258        if (write_locked_index(&the_index, &lock_file, COMMIT_LOCK))
 259                return error(_("unable to write new index file"));
 260
 261        return 0;
 262}
 263
 264static int diff_tree_binary(struct strbuf *out, struct object_id *w_commit)
 265{
 266        struct child_process cp = CHILD_PROCESS_INIT;
 267        const char *w_commit_hex = oid_to_hex(w_commit);
 268
 269        /*
 270         * Diff-tree would not be very hard to replace with a native function,
 271         * however it should be done together with apply_cached.
 272         */
 273        cp.git_cmd = 1;
 274        argv_array_pushl(&cp.args, "diff-tree", "--binary", NULL);
 275        argv_array_pushf(&cp.args, "%s^2^..%s^2", w_commit_hex, w_commit_hex);
 276
 277        return pipe_command(&cp, NULL, 0, out, 0, NULL, 0);
 278}
 279
 280static int apply_cached(struct strbuf *out)
 281{
 282        struct child_process cp = CHILD_PROCESS_INIT;
 283
 284        /*
 285         * Apply currently only reads either from stdin or a file, thus
 286         * apply_all_patches would have to be updated to optionally take a
 287         * buffer.
 288         */
 289        cp.git_cmd = 1;
 290        argv_array_pushl(&cp.args, "apply", "--cached", NULL);
 291        return pipe_command(&cp, out->buf, out->len, NULL, 0, NULL, 0);
 292}
 293
 294static int reset_head(void)
 295{
 296        struct child_process cp = CHILD_PROCESS_INIT;
 297
 298        /*
 299         * Reset is overall quite simple, however there is no current public
 300         * API for resetting.
 301         */
 302        cp.git_cmd = 1;
 303        argv_array_push(&cp.args, "reset");
 304
 305        return run_command(&cp);
 306}
 307
 308static void add_diff_to_buf(struct diff_queue_struct *q,
 309                            struct diff_options *options,
 310                            void *data)
 311{
 312        int i;
 313
 314        for (i = 0; i < q->nr; i++) {
 315                strbuf_addstr(data, q->queue[i]->one->path);
 316
 317                /* NUL-terminate: will be fed to update-index -z */
 318                strbuf_addch(data, '\0');
 319        }
 320}
 321
 322static int get_newly_staged(struct strbuf *out, struct object_id *c_tree)
 323{
 324        struct child_process cp = CHILD_PROCESS_INIT;
 325        const char *c_tree_hex = oid_to_hex(c_tree);
 326
 327        /*
 328         * diff-index is very similar to diff-tree above, and should be
 329         * converted together with update_index.
 330         */
 331        cp.git_cmd = 1;
 332        argv_array_pushl(&cp.args, "diff-index", "--cached", "--name-only",
 333                         "--diff-filter=A", NULL);
 334        argv_array_push(&cp.args, c_tree_hex);
 335        return pipe_command(&cp, NULL, 0, out, 0, NULL, 0);
 336}
 337
 338static int update_index(struct strbuf *out)
 339{
 340        struct child_process cp = CHILD_PROCESS_INIT;
 341
 342        /*
 343         * Update-index is very complicated and may need to have a public
 344         * function exposed in order to remove this forking.
 345         */
 346        cp.git_cmd = 1;
 347        argv_array_pushl(&cp.args, "update-index", "--add", "--stdin", NULL);
 348        return pipe_command(&cp, out->buf, out->len, NULL, 0, NULL, 0);
 349}
 350
 351static int restore_untracked(struct object_id *u_tree)
 352{
 353        int res;
 354        struct child_process cp = CHILD_PROCESS_INIT;
 355
 356        /*
 357         * We need to run restore files from a given index, but without
 358         * affecting the current index, so we use GIT_INDEX_FILE with
 359         * run_command to fork processes that will not interfere.
 360         */
 361        cp.git_cmd = 1;
 362        argv_array_push(&cp.args, "read-tree");
 363        argv_array_push(&cp.args, oid_to_hex(u_tree));
 364        argv_array_pushf(&cp.env_array, "GIT_INDEX_FILE=%s",
 365                         stash_index_path.buf);
 366        if (run_command(&cp)) {
 367                remove_path(stash_index_path.buf);
 368                return -1;
 369        }
 370
 371        child_process_init(&cp);
 372        cp.git_cmd = 1;
 373        argv_array_pushl(&cp.args, "checkout-index", "--all", NULL);
 374        argv_array_pushf(&cp.env_array, "GIT_INDEX_FILE=%s",
 375                         stash_index_path.buf);
 376
 377        res = run_command(&cp);
 378        remove_path(stash_index_path.buf);
 379        return res;
 380}
 381
 382static int do_apply_stash(const char *prefix, struct stash_info *info,
 383                          int index, int quiet)
 384{
 385        int ret;
 386        int has_index = index;
 387        struct merge_options o;
 388        struct object_id c_tree;
 389        struct object_id index_tree;
 390        struct commit *result;
 391        const struct object_id *bases[1];
 392
 393        read_cache_preload(NULL);
 394        if (refresh_cache(REFRESH_QUIET))
 395                return -1;
 396
 397        if (write_cache_as_tree(&c_tree, 0, NULL))
 398                return error(_("cannot apply a stash in the middle of a merge"));
 399
 400        if (index) {
 401                if (oideq(&info->b_tree, &info->i_tree) ||
 402                    oideq(&c_tree, &info->i_tree)) {
 403                        has_index = 0;
 404                } else {
 405                        struct strbuf out = STRBUF_INIT;
 406
 407                        if (diff_tree_binary(&out, &info->w_commit)) {
 408                                strbuf_release(&out);
 409                                return error(_("could not generate diff %s^!."),
 410                                             oid_to_hex(&info->w_commit));
 411                        }
 412
 413                        ret = apply_cached(&out);
 414                        strbuf_release(&out);
 415                        if (ret)
 416                                return error(_("conflicts in index."
 417                                               "Try without --index."));
 418
 419                        discard_cache();
 420                        read_cache();
 421                        if (write_cache_as_tree(&index_tree, 0, NULL))
 422                                return error(_("could not save index tree"));
 423
 424                        reset_head();
 425                }
 426        }
 427
 428        if (info->has_u && restore_untracked(&info->u_tree))
 429                return error(_("could not restore untracked files from stash"));
 430
 431        init_merge_options(&o);
 432
 433        o.branch1 = "Updated upstream";
 434        o.branch2 = "Stashed changes";
 435
 436        if (oideq(&info->b_tree, &c_tree))
 437                o.branch1 = "Version stash was based on";
 438
 439        if (quiet)
 440                o.verbosity = 0;
 441
 442        if (o.verbosity >= 3)
 443                printf_ln(_("Merging %s with %s"), o.branch1, o.branch2);
 444
 445        bases[0] = &info->b_tree;
 446
 447        ret = merge_recursive_generic(&o, &c_tree, &info->w_tree, 1, bases,
 448                                      &result);
 449        if (ret) {
 450                rerere(0);
 451
 452                if (index)
 453                        fprintf_ln(stderr, _("Index was not unstashed."));
 454
 455                return ret;
 456        }
 457
 458        if (has_index) {
 459                if (reset_tree(&index_tree, 0, 0))
 460                        return -1;
 461        } else {
 462                struct strbuf out = STRBUF_INIT;
 463
 464                if (get_newly_staged(&out, &c_tree)) {
 465                        strbuf_release(&out);
 466                        return -1;
 467                }
 468
 469                if (reset_tree(&c_tree, 0, 1)) {
 470                        strbuf_release(&out);
 471                        return -1;
 472                }
 473
 474                ret = update_index(&out);
 475                strbuf_release(&out);
 476                if (ret)
 477                        return -1;
 478
 479                discard_cache();
 480        }
 481
 482        if (quiet) {
 483                if (refresh_cache(REFRESH_QUIET))
 484                        warning("could not refresh index");
 485        } else {
 486                struct child_process cp = CHILD_PROCESS_INIT;
 487
 488                /*
 489                 * Status is quite simple and could be replaced with calls to
 490                 * wt_status in the future, but it adds complexities which may
 491                 * require more tests.
 492                 */
 493                cp.git_cmd = 1;
 494                cp.dir = prefix;
 495                argv_array_push(&cp.args, "status");
 496                run_command(&cp);
 497        }
 498
 499        return 0;
 500}
 501
 502static int apply_stash(int argc, const char **argv, const char *prefix)
 503{
 504        int ret;
 505        int quiet = 0;
 506        int index = 0;
 507        struct stash_info info;
 508        struct option options[] = {
 509                OPT__QUIET(&quiet, N_("be quiet, only report errors")),
 510                OPT_BOOL(0, "index", &index,
 511                         N_("attempt to recreate the index")),
 512                OPT_END()
 513        };
 514
 515        argc = parse_options(argc, argv, prefix, options,
 516                             git_stash_helper_apply_usage, 0);
 517
 518        if (get_stash_info(&info, argc, argv))
 519                return -1;
 520
 521        ret = do_apply_stash(prefix, &info, index, quiet);
 522        free_stash_info(&info);
 523        return ret;
 524}
 525
 526static int do_drop_stash(const char *prefix, struct stash_info *info, int quiet)
 527{
 528        int ret;
 529        struct child_process cp_reflog = CHILD_PROCESS_INIT;
 530        struct child_process cp = CHILD_PROCESS_INIT;
 531
 532        /*
 533         * reflog does not provide a simple function for deleting refs. One will
 534         * need to be added to avoid implementing too much reflog code here
 535         */
 536
 537        cp_reflog.git_cmd = 1;
 538        argv_array_pushl(&cp_reflog.args, "reflog", "delete", "--updateref",
 539                         "--rewrite", NULL);
 540        argv_array_push(&cp_reflog.args, info->revision.buf);
 541        ret = run_command(&cp_reflog);
 542        if (!ret) {
 543                if (!quiet)
 544                        printf_ln(_("Dropped %s (%s)"), info->revision.buf,
 545                                  oid_to_hex(&info->w_commit));
 546        } else {
 547                return error(_("%s: Could not drop stash entry"),
 548                             info->revision.buf);
 549        }
 550
 551        /*
 552         * This could easily be replaced by get_oid, but currently it will throw
 553         * a fatal error when a reflog is empty, which we can not recover from.
 554         */
 555        cp.git_cmd = 1;
 556        /* Even though --quiet is specified, rev-parse still outputs the hash */
 557        cp.no_stdout = 1;
 558        argv_array_pushl(&cp.args, "rev-parse", "--verify", "--quiet", NULL);
 559        argv_array_pushf(&cp.args, "%s@{0}", ref_stash);
 560        ret = run_command(&cp);
 561
 562        /* do_clear_stash if we just dropped the last stash entry */
 563        if (ret)
 564                do_clear_stash();
 565
 566        return 0;
 567}
 568
 569static void assert_stash_ref(struct stash_info *info)
 570{
 571        if (!info->is_stash_ref) {
 572                error(_("'%s' is not a stash reference"), info->revision.buf);
 573                free_stash_info(info);
 574                exit(1);
 575        }
 576}
 577
 578static int drop_stash(int argc, const char **argv, const char *prefix)
 579{
 580        int ret;
 581        int quiet = 0;
 582        struct stash_info info;
 583        struct option options[] = {
 584                OPT__QUIET(&quiet, N_("be quiet, only report errors")),
 585                OPT_END()
 586        };
 587
 588        argc = parse_options(argc, argv, prefix, options,
 589                             git_stash_helper_drop_usage, 0);
 590
 591        if (get_stash_info(&info, argc, argv))
 592                return -1;
 593
 594        assert_stash_ref(&info);
 595
 596        ret = do_drop_stash(prefix, &info, quiet);
 597        free_stash_info(&info);
 598        return ret;
 599}
 600
 601static int pop_stash(int argc, const char **argv, const char *prefix)
 602{
 603        int ret;
 604        int index = 0;
 605        int quiet = 0;
 606        struct stash_info info;
 607        struct option options[] = {
 608                OPT__QUIET(&quiet, N_("be quiet, only report errors")),
 609                OPT_BOOL(0, "index", &index,
 610                         N_("attempt to recreate the index")),
 611                OPT_END()
 612        };
 613
 614        argc = parse_options(argc, argv, prefix, options,
 615                             git_stash_helper_pop_usage, 0);
 616
 617        if (get_stash_info(&info, argc, argv))
 618                return -1;
 619
 620        assert_stash_ref(&info);
 621        if ((ret = do_apply_stash(prefix, &info, index, quiet)))
 622                printf_ln(_("The stash entry is kept in case "
 623                            "you need it again."));
 624        else
 625                ret = do_drop_stash(prefix, &info, quiet);
 626
 627        free_stash_info(&info);
 628        return ret;
 629}
 630
 631static int branch_stash(int argc, const char **argv, const char *prefix)
 632{
 633        int ret;
 634        const char *branch = NULL;
 635        struct stash_info info;
 636        struct child_process cp = CHILD_PROCESS_INIT;
 637        struct option options[] = {
 638                OPT_END()
 639        };
 640
 641        argc = parse_options(argc, argv, prefix, options,
 642                             git_stash_helper_branch_usage, 0);
 643
 644        if (!argc) {
 645                fprintf_ln(stderr, _("No branch name specified"));
 646                return -1;
 647        }
 648
 649        branch = argv[0];
 650
 651        if (get_stash_info(&info, argc - 1, argv + 1))
 652                return -1;
 653
 654        cp.git_cmd = 1;
 655        argv_array_pushl(&cp.args, "checkout", "-b", NULL);
 656        argv_array_push(&cp.args, branch);
 657        argv_array_push(&cp.args, oid_to_hex(&info.b_commit));
 658        ret = run_command(&cp);
 659        if (!ret)
 660                ret = do_apply_stash(prefix, &info, 1, 0);
 661        if (!ret && info.is_stash_ref)
 662                ret = do_drop_stash(prefix, &info, 0);
 663
 664        free_stash_info(&info);
 665
 666        return ret;
 667}
 668
 669static int list_stash(int argc, const char **argv, const char *prefix)
 670{
 671        struct child_process cp = CHILD_PROCESS_INIT;
 672        struct option options[] = {
 673                OPT_END()
 674        };
 675
 676        argc = parse_options(argc, argv, prefix, options,
 677                             git_stash_helper_list_usage,
 678                             PARSE_OPT_KEEP_UNKNOWN);
 679
 680        if (!ref_exists(ref_stash))
 681                return 0;
 682
 683        cp.git_cmd = 1;
 684        argv_array_pushl(&cp.args, "log", "--format=%gd: %gs", "-g",
 685                         "--first-parent", "-m", NULL);
 686        argv_array_pushv(&cp.args, argv);
 687        argv_array_push(&cp.args, ref_stash);
 688        argv_array_push(&cp.args, "--");
 689        return run_command(&cp);
 690}
 691
 692static int show_stat = 1;
 693static int show_patch;
 694
 695static int git_stash_config(const char *var, const char *value, void *cb)
 696{
 697        if (!strcmp(var, "stash.showstat")) {
 698                show_stat = git_config_bool(var, value);
 699                return 0;
 700        }
 701        if (!strcmp(var, "stash.showpatch")) {
 702                show_patch = git_config_bool(var, value);
 703                return 0;
 704        }
 705        return git_default_config(var, value, cb);
 706}
 707
 708static int show_stash(int argc, const char **argv, const char *prefix)
 709{
 710        int i;
 711        int opts = 0;
 712        int ret = 0;
 713        struct stash_info info;
 714        struct rev_info rev;
 715        struct argv_array stash_args = ARGV_ARRAY_INIT;
 716        struct option options[] = {
 717                OPT_END()
 718        };
 719
 720        init_diff_ui_defaults();
 721        git_config(git_diff_ui_config, NULL);
 722        init_revisions(&rev, prefix);
 723
 724        for (i = 1; i < argc; i++) {
 725                if (argv[i][0] != '-')
 726                        argv_array_push(&stash_args, argv[i]);
 727                else
 728                        opts++;
 729        }
 730
 731        ret = get_stash_info(&info, stash_args.argc, stash_args.argv);
 732        argv_array_clear(&stash_args);
 733        if (ret)
 734                return -1;
 735
 736        /*
 737         * The config settings are applied only if there are not passed
 738         * any options.
 739         */
 740        if (!opts) {
 741                git_config(git_stash_config, NULL);
 742                if (show_stat)
 743                        rev.diffopt.output_format = DIFF_FORMAT_DIFFSTAT;
 744
 745                if (show_patch)
 746                        rev.diffopt.output_format |= DIFF_FORMAT_PATCH;
 747
 748                if (!show_stat && !show_patch) {
 749                        free_stash_info(&info);
 750                        return 0;
 751                }
 752        }
 753
 754        argc = setup_revisions(argc, argv, &rev, NULL);
 755        if (argc > 1) {
 756                free_stash_info(&info);
 757                usage_with_options(git_stash_helper_show_usage, options);
 758        }
 759
 760        rev.diffopt.flags.recursive = 1;
 761        setup_diff_pager(&rev.diffopt);
 762        diff_tree_oid(&info.b_commit, &info.w_commit, "", &rev.diffopt);
 763        log_tree_diff_flush(&rev);
 764
 765        free_stash_info(&info);
 766        return diff_result_code(&rev.diffopt, 0);
 767}
 768
 769static int do_store_stash(const struct object_id *w_commit, const char *stash_msg,
 770                          int quiet)
 771{
 772        if (!stash_msg)
 773                stash_msg = "Created via \"git stash store\".";
 774
 775        if (update_ref(stash_msg, ref_stash, w_commit, NULL,
 776                       REF_FORCE_CREATE_REFLOG,
 777                       quiet ? UPDATE_REFS_QUIET_ON_ERR :
 778                       UPDATE_REFS_MSG_ON_ERR)) {
 779                if (!quiet) {
 780                        fprintf_ln(stderr, _("Cannot update %s with %s"),
 781                                   ref_stash, oid_to_hex(w_commit));
 782                }
 783                return -1;
 784        }
 785
 786        return 0;
 787}
 788
 789static int store_stash(int argc, const char **argv, const char *prefix)
 790{
 791        int quiet = 0;
 792        const char *stash_msg = NULL;
 793        struct object_id obj;
 794        struct object_context dummy;
 795        struct option options[] = {
 796                OPT__QUIET(&quiet, N_("be quiet")),
 797                OPT_STRING('m', "message", &stash_msg, "message",
 798                           N_("stash message")),
 799                OPT_END()
 800        };
 801
 802        argc = parse_options(argc, argv, prefix, options,
 803                             git_stash_helper_store_usage,
 804                             PARSE_OPT_KEEP_UNKNOWN);
 805
 806        if (argc != 1) {
 807                if (!quiet)
 808                        fprintf_ln(stderr, _("\"git stash store\" requires one "
 809                                             "<commit> argument"));
 810                return -1;
 811        }
 812
 813        if (get_oid_with_context(argv[0], quiet ? GET_OID_QUIETLY : 0, &obj,
 814                                 &dummy)) {
 815                if (!quiet)
 816                        fprintf_ln(stderr, _("Cannot update %s with %s"),
 817                                             ref_stash, argv[0]);
 818                return -1;
 819        }
 820
 821        return do_store_stash(&obj, stash_msg, quiet);
 822}
 823
 824static void add_pathspecs(struct argv_array *args,
 825                          struct pathspec ps) {
 826        int i;
 827
 828        for (i = 0; i < ps.nr; i++)
 829                argv_array_push(args, ps.items[i].match);
 830}
 831
 832/*
 833 * `untracked_files` will be filled with the names of untracked files.
 834 * The return value is:
 835 *
 836 * = 0 if there are not any untracked files
 837 * > 0 if there are untracked files
 838 */
 839static int get_untracked_files(struct pathspec ps, int include_untracked,
 840                               struct strbuf *untracked_files)
 841{
 842        int i;
 843        int max_len;
 844        int found = 0;
 845        char *seen;
 846        struct dir_struct dir;
 847
 848        memset(&dir, 0, sizeof(dir));
 849        if (include_untracked != INCLUDE_ALL_FILES)
 850                setup_standard_excludes(&dir);
 851
 852        seen = xcalloc(ps.nr, 1);
 853
 854        max_len = fill_directory(&dir, the_repository->index, &ps);
 855        for (i = 0; i < dir.nr; i++) {
 856                struct dir_entry *ent = dir.entries[i];
 857                if (dir_path_match(&the_index, ent, &ps, max_len, seen)) {
 858                        found++;
 859                        strbuf_addstr(untracked_files, ent->name);
 860                        /* NUL-terminate: will be fed to update-index -z */
 861                        strbuf_addch(untracked_files, '\0');
 862                }
 863                free(ent);
 864        }
 865
 866        free(seen);
 867        free(dir.entries);
 868        free(dir.ignored);
 869        clear_directory(&dir);
 870        return found;
 871}
 872
 873/*
 874 * The return value of `check_changes()` can be:
 875 *
 876 * < 0 if there was an error
 877 * = 0 if there are no changes.
 878 * > 0 if there are changes.
 879 */
 880static int check_changes(struct pathspec ps, int include_untracked)
 881{
 882        int result;
 883        struct rev_info rev;
 884        struct object_id dummy;
 885        struct strbuf out = STRBUF_INIT;
 886
 887        /* No initial commit. */
 888        if (get_oid("HEAD", &dummy))
 889                return -1;
 890
 891        if (read_cache() < 0)
 892                return -1;
 893
 894        init_revisions(&rev, NULL);
 895        rev.prune_data = ps;
 896
 897        rev.diffopt.flags.quick = 1;
 898        rev.diffopt.flags.ignore_submodules = 1;
 899        rev.abbrev = 0;
 900
 901        add_head_to_pending(&rev);
 902        diff_setup_done(&rev.diffopt);
 903
 904        result = run_diff_index(&rev, 1);
 905        if (diff_result_code(&rev.diffopt, result))
 906                return 1;
 907
 908        object_array_clear(&rev.pending);
 909        result = run_diff_files(&rev, 0);
 910        if (diff_result_code(&rev.diffopt, result))
 911                return 1;
 912
 913        if (include_untracked && get_untracked_files(ps, include_untracked,
 914                                                     &out)) {
 915                strbuf_release(&out);
 916                return 1;
 917        }
 918
 919        strbuf_release(&out);
 920        return 0;
 921}
 922
 923static int save_untracked_files(struct stash_info *info, struct strbuf *msg,
 924                                struct strbuf files)
 925{
 926        int ret = 0;
 927        struct strbuf untracked_msg = STRBUF_INIT;
 928        struct strbuf out = STRBUF_INIT;
 929        struct child_process cp_upd_index = CHILD_PROCESS_INIT;
 930        struct child_process cp_write_tree = CHILD_PROCESS_INIT;
 931
 932        cp_upd_index.git_cmd = 1;
 933        argv_array_pushl(&cp_upd_index.args, "update-index", "-z", "--add",
 934                         "--remove", "--stdin", NULL);
 935        argv_array_pushf(&cp_upd_index.env_array, "GIT_INDEX_FILE=%s",
 936                         stash_index_path.buf);
 937
 938        strbuf_addf(&untracked_msg, "untracked files on %s\n", msg->buf);
 939        if (pipe_command(&cp_upd_index, files.buf, files.len, NULL, 0,
 940                         NULL, 0)) {
 941                ret = -1;
 942                goto done;
 943        }
 944
 945        cp_write_tree.git_cmd = 1;
 946        argv_array_push(&cp_write_tree.args, "write-tree");
 947        argv_array_pushf(&cp_write_tree.env_array, "GIT_INDEX_FILE=%s",
 948                         stash_index_path.buf);
 949        if (pipe_command(&cp_write_tree, NULL, 0, &out, 0,NULL, 0)) {
 950                ret = -1;
 951                goto done;
 952        }
 953        get_oid_hex(out.buf, &info->u_tree);
 954
 955        if (commit_tree(untracked_msg.buf, untracked_msg.len,
 956                        &info->u_tree, NULL, &info->u_commit, NULL, NULL)) {
 957                ret = -1;
 958                goto done;
 959        }
 960
 961done:
 962        strbuf_release(&untracked_msg);
 963        strbuf_release(&out);
 964        remove_path(stash_index_path.buf);
 965        return ret;
 966}
 967
 968static int stash_patch(struct stash_info *info, struct pathspec ps,
 969                       struct strbuf *out_patch)
 970{
 971        int ret = 0;
 972        struct strbuf out = STRBUF_INIT;
 973        struct child_process cp_read_tree = CHILD_PROCESS_INIT;
 974        struct child_process cp_add_i = CHILD_PROCESS_INIT;
 975        struct child_process cp_write_tree = CHILD_PROCESS_INIT;
 976        struct child_process cp_diff_tree = CHILD_PROCESS_INIT;
 977
 978        remove_path(stash_index_path.buf);
 979
 980        cp_read_tree.git_cmd = 1;
 981        argv_array_pushl(&cp_read_tree.args, "read-tree", "HEAD", NULL);
 982        argv_array_pushf(&cp_read_tree.env_array, "GIT_INDEX_FILE=%s",
 983                         stash_index_path.buf);
 984        if (run_command(&cp_read_tree)) {
 985                ret = -1;
 986                goto done;
 987        }
 988
 989        /* Find out what the user wants. */
 990        cp_add_i.git_cmd = 1;
 991        argv_array_pushl(&cp_add_i.args, "add--interactive", "--patch=stash",
 992                         "--", NULL);
 993        add_pathspecs(&cp_add_i.args, ps);
 994        argv_array_pushf(&cp_add_i.env_array, "GIT_INDEX_FILE=%s",
 995                         stash_index_path.buf);
 996        if (run_command(&cp_add_i)) {
 997                ret = -1;
 998                goto done;
 999        }
1000
1001        /* State of the working tree. */
1002        cp_write_tree.git_cmd = 1;
1003        argv_array_push(&cp_write_tree.args, "write-tree");
1004        argv_array_pushf(&cp_write_tree.env_array, "GIT_INDEX_FILE=%s",
1005                         stash_index_path.buf);
1006        if (pipe_command(&cp_write_tree, NULL, 0, &out, 0,NULL, 0)) {
1007                ret = -1;
1008                goto done;
1009        }
1010
1011        get_oid_hex(out.buf, &info->w_tree);
1012
1013        cp_diff_tree.git_cmd = 1;
1014        argv_array_pushl(&cp_diff_tree.args, "diff-tree", "-p", "HEAD",
1015                         oid_to_hex(&info->w_tree), "--", NULL);
1016        if (pipe_command(&cp_diff_tree, NULL, 0, out_patch, 0, NULL, 0)) {
1017                ret = -1;
1018                goto done;
1019        }
1020
1021        if (!out_patch->len) {
1022                fprintf_ln(stderr, _("No changes selected"));
1023                ret = 1;
1024        }
1025
1026done:
1027        strbuf_release(&out);
1028        remove_path(stash_index_path.buf);
1029        return ret;
1030}
1031
1032static int stash_working_tree(struct stash_info *info, struct pathspec ps)
1033{
1034        int ret = 0;
1035        struct rev_info rev;
1036        struct child_process cp_upd_index = CHILD_PROCESS_INIT;
1037        struct child_process cp_write_tree = CHILD_PROCESS_INIT;
1038        struct strbuf out = STRBUF_INIT;
1039        struct strbuf diff_output = STRBUF_INIT;
1040
1041        init_revisions(&rev, NULL);
1042
1043        set_alternate_index_output(stash_index_path.buf);
1044        if (reset_tree(&info->i_tree, 0, 0)) {
1045                ret = -1;
1046                goto done;
1047        }
1048        set_alternate_index_output(NULL);
1049
1050        rev.prune_data = ps;
1051        rev.diffopt.output_format = DIFF_FORMAT_CALLBACK;
1052        rev.diffopt.format_callback = add_diff_to_buf;
1053        rev.diffopt.format_callback_data = &diff_output;
1054
1055        if (read_cache_preload(&rev.diffopt.pathspec) < 0) {
1056                ret = -1;
1057                goto done;
1058        }
1059
1060        add_pending_object(&rev, parse_object(the_repository, &info->b_commit),
1061                           "");
1062        if (run_diff_index(&rev, 0)) {
1063                ret = -1;
1064                goto done;
1065        }
1066
1067        cp_upd_index.git_cmd = 1;
1068        argv_array_pushl(&cp_upd_index.args, "update-index", "-z", "--add",
1069                         "--remove", "--stdin", NULL);
1070        argv_array_pushf(&cp_upd_index.env_array, "GIT_INDEX_FILE=%s",
1071                         stash_index_path.buf);
1072
1073        if (pipe_command(&cp_upd_index, diff_output.buf, diff_output.len,
1074                         NULL, 0, NULL, 0)) {
1075                ret = -1;
1076                goto done;
1077        }
1078
1079        cp_write_tree.git_cmd = 1;
1080        argv_array_push(&cp_write_tree.args, "write-tree");
1081        argv_array_pushf(&cp_write_tree.env_array, "GIT_INDEX_FILE=%s",
1082                         stash_index_path.buf);
1083        if (pipe_command(&cp_write_tree, NULL, 0, &out, 0,NULL, 0)) {
1084                ret = -1;
1085                goto done;
1086        }
1087
1088        get_oid_hex(out.buf, &info->w_tree);
1089
1090done:
1091        UNLEAK(rev);
1092        strbuf_release(&out);
1093        object_array_clear(&rev.pending);
1094        strbuf_release(&diff_output);
1095        remove_path(stash_index_path.buf);
1096        return ret;
1097}
1098
1099static int do_create_stash(struct pathspec ps, struct strbuf *stash_msg_buf,
1100                           int include_untracked, int patch_mode,
1101                           struct stash_info *info, struct strbuf *patch)
1102{
1103        int ret = 0;
1104        int flags = 0;
1105        int untracked_commit_option = 0;
1106        const char *head_short_sha1 = NULL;
1107        const char *branch_ref = NULL;
1108        const char *branch_name = "(no branch)";
1109        struct commit *head_commit = NULL;
1110        struct commit_list *parents = NULL;
1111        struct strbuf msg = STRBUF_INIT;
1112        struct strbuf commit_tree_label = STRBUF_INIT;
1113        struct strbuf untracked_files = STRBUF_INIT;
1114
1115        prepare_fallback_ident("git stash", "git@stash");
1116
1117        read_cache_preload(NULL);
1118        refresh_cache(REFRESH_QUIET);
1119
1120        if (get_oid("HEAD", &info->b_commit)) {
1121                fprintf_ln(stderr, _("You do not have the initial commit yet"));
1122                ret = -1;
1123                goto done;
1124        } else {
1125                head_commit = lookup_commit(the_repository, &info->b_commit);
1126        }
1127
1128        if (!check_changes(ps, include_untracked)) {
1129                ret = 1;
1130                goto done;
1131        }
1132
1133        branch_ref = resolve_ref_unsafe("HEAD", 0, NULL, &flags);
1134        if (flags & REF_ISSYMREF)
1135                branch_name = strrchr(branch_ref, '/') + 1;
1136        head_short_sha1 = find_unique_abbrev(&head_commit->object.oid,
1137                                             DEFAULT_ABBREV);
1138        strbuf_addf(&msg, "%s: %s ", branch_name, head_short_sha1);
1139        pp_commit_easy(CMIT_FMT_ONELINE, head_commit, &msg);
1140
1141        strbuf_addf(&commit_tree_label, "index on %s\n", msg.buf);
1142        commit_list_insert(head_commit, &parents);
1143        if (write_cache_as_tree(&info->i_tree, 0, NULL) ||
1144            commit_tree(commit_tree_label.buf, commit_tree_label.len,
1145                        &info->i_tree, parents, &info->i_commit, NULL, NULL)) {
1146                fprintf_ln(stderr, _("Cannot save the current index state"));
1147                ret = -1;
1148                goto done;
1149        }
1150
1151        if (include_untracked && get_untracked_files(ps, include_untracked,
1152                                                     &untracked_files)) {
1153                if (save_untracked_files(info, &msg, untracked_files)) {
1154                        fprintf_ln(stderr, _("Cannot save "
1155                                             "the untracked files"));
1156                        ret = -1;
1157                        goto done;
1158                }
1159                untracked_commit_option = 1;
1160        }
1161        if (patch_mode) {
1162                ret = stash_patch(info, ps, patch);
1163                if (ret < 0) {
1164                        fprintf_ln(stderr, _("Cannot save the current "
1165                                             "worktree state"));
1166                        goto done;
1167                } else if (ret > 0) {
1168                        goto done;
1169                }
1170        } else {
1171                if (stash_working_tree(info, ps)) {
1172                        fprintf_ln(stderr, _("Cannot save the current "
1173                                             "worktree state"));
1174                        ret = -1;
1175                        goto done;
1176                }
1177        }
1178
1179        if (!stash_msg_buf->len)
1180                strbuf_addf(stash_msg_buf, "WIP on %s", msg.buf);
1181        else
1182                strbuf_insertf(stash_msg_buf, 0, "On %s: ", branch_name);
1183
1184        /*
1185         * `parents` will be empty after calling `commit_tree()`, so there is
1186         * no need to call `free_commit_list()`
1187         */
1188        parents = NULL;
1189        if (untracked_commit_option)
1190                commit_list_insert(lookup_commit(the_repository,
1191                                                 &info->u_commit),
1192                                   &parents);
1193        commit_list_insert(lookup_commit(the_repository, &info->i_commit),
1194                           &parents);
1195        commit_list_insert(head_commit, &parents);
1196
1197        if (commit_tree(stash_msg_buf->buf, stash_msg_buf->len, &info->w_tree,
1198                        parents, &info->w_commit, NULL, NULL)) {
1199                fprintf_ln(stderr, _("Cannot record working tree state"));
1200                ret = -1;
1201                goto done;
1202        }
1203
1204done:
1205        strbuf_release(&commit_tree_label);
1206        strbuf_release(&msg);
1207        strbuf_release(&untracked_files);
1208        return ret;
1209}
1210
1211static int create_stash(int argc, const char **argv, const char *prefix)
1212{
1213        int include_untracked = 0;
1214        int ret = 0;
1215        const char *stash_msg = NULL;
1216        struct strbuf stash_msg_buf = STRBUF_INIT;
1217        struct stash_info info;
1218        struct pathspec ps;
1219        struct option options[] = {
1220                OPT_BOOL('u', "include-untracked", &include_untracked,
1221                         N_("include untracked files in stash")),
1222                OPT_STRING('m', "message", &stash_msg, N_("message"),
1223                         N_("stash message")),
1224                OPT_END()
1225        };
1226
1227        argc = parse_options(argc, argv, prefix, options,
1228                             git_stash_helper_create_usage,
1229                             0);
1230
1231        memset(&ps, 0, sizeof(ps));
1232        strbuf_addstr(&stash_msg_buf, stash_msg);
1233        ret = do_create_stash(ps, &stash_msg_buf, include_untracked, 0, &info,
1234                              NULL);
1235        if (!ret)
1236                printf_ln("%s", oid_to_hex(&info.w_commit));
1237
1238        strbuf_release(&stash_msg_buf);
1239
1240        /*
1241         * ret can be 1 if there were no changes. In this case, we should
1242         * not error out.
1243         */
1244        return ret < 0;
1245}
1246
1247static int do_push_stash(struct pathspec ps, const char *stash_msg, int quiet,
1248                         int keep_index, int patch_mode, int include_untracked)
1249{
1250        int ret = 0;
1251        struct stash_info info;
1252        struct strbuf patch = STRBUF_INIT;
1253        struct strbuf stash_msg_buf = STRBUF_INIT;
1254
1255        if (patch_mode && keep_index == -1)
1256                keep_index = 1;
1257
1258        if (patch_mode && include_untracked) {
1259                fprintf_ln(stderr, _("Can't use --patch and --include-untracked"
1260                                     " or --all at the same time"));
1261                ret = -1;
1262                goto done;
1263        }
1264
1265        read_cache_preload(NULL);
1266        if (!include_untracked && ps.nr) {
1267                int i;
1268                char *ps_matched = xcalloc(ps.nr, 1);
1269
1270                for (i = 0; i < active_nr; i++)
1271                        ce_path_match(&the_index, active_cache[i], &ps,
1272                                      ps_matched);
1273
1274                if (report_path_error(ps_matched, &ps, NULL)) {
1275                        fprintf_ln(stderr, _("Did you forget to 'git add'?"));
1276                        ret = -1;
1277                        free(ps_matched);
1278                        goto done;
1279                }
1280                free(ps_matched);
1281        }
1282
1283        if (refresh_cache(REFRESH_QUIET)) {
1284                ret = -1;
1285                goto done;
1286        }
1287
1288        if (!check_changes(ps, include_untracked)) {
1289                if (!quiet)
1290                        printf_ln(_("No local changes to save"));
1291                goto done;
1292        }
1293
1294        if (!reflog_exists(ref_stash) && do_clear_stash()) {
1295                ret = -1;
1296                fprintf_ln(stderr, _("Cannot initialize stash"));
1297                goto done;
1298        }
1299
1300        if (stash_msg)
1301                strbuf_addstr(&stash_msg_buf, stash_msg);
1302        if (do_create_stash(ps, &stash_msg_buf, include_untracked, patch_mode,
1303                            &info, &patch)) {
1304                ret = -1;
1305                goto done;
1306        }
1307
1308        if (do_store_stash(&info.w_commit, stash_msg_buf.buf, 1)) {
1309                ret = -1;
1310                fprintf_ln(stderr, _("Cannot save the current status"));
1311                goto done;
1312        }
1313
1314        printf_ln(_("Saved working directory and index state %s"),
1315                  stash_msg_buf.buf);
1316
1317        if (!patch_mode) {
1318                if (include_untracked && !ps.nr) {
1319                        struct child_process cp = CHILD_PROCESS_INIT;
1320
1321                        cp.git_cmd = 1;
1322                        argv_array_pushl(&cp.args, "clean", "--force",
1323                                         "--quiet", "-d", NULL);
1324                        if (include_untracked == INCLUDE_ALL_FILES)
1325                                argv_array_push(&cp.args, "-x");
1326                        if (run_command(&cp)) {
1327                                ret = -1;
1328                                goto done;
1329                        }
1330                }
1331                discard_cache();
1332                if (ps.nr) {
1333                        struct child_process cp_add = CHILD_PROCESS_INIT;
1334                        struct child_process cp_diff = CHILD_PROCESS_INIT;
1335                        struct child_process cp_apply = CHILD_PROCESS_INIT;
1336                        struct strbuf out = STRBUF_INIT;
1337
1338                        cp_add.git_cmd = 1;
1339                        argv_array_push(&cp_add.args, "add");
1340                        if (!include_untracked)
1341                                argv_array_push(&cp_add.args, "-u");
1342                        if (include_untracked == INCLUDE_ALL_FILES)
1343                                argv_array_push(&cp_add.args, "--force");
1344                        argv_array_push(&cp_add.args, "--");
1345                        add_pathspecs(&cp_add.args, ps);
1346                        if (run_command(&cp_add)) {
1347                                ret = -1;
1348                                goto done;
1349                        }
1350
1351                        cp_diff.git_cmd = 1;
1352                        argv_array_pushl(&cp_diff.args, "diff-index", "-p",
1353                                         "--cached", "--binary", "HEAD", "--",
1354                                         NULL);
1355                        add_pathspecs(&cp_diff.args, ps);
1356                        if (pipe_command(&cp_diff, NULL, 0, &out, 0, NULL, 0)) {
1357                                ret = -1;
1358                                goto done;
1359                        }
1360
1361                        cp_apply.git_cmd = 1;
1362                        argv_array_pushl(&cp_apply.args, "apply", "--index",
1363                                         "-R", NULL);
1364                        if (pipe_command(&cp_apply, out.buf, out.len, NULL, 0,
1365                                         NULL, 0)) {
1366                                ret = -1;
1367                                goto done;
1368                        }
1369                } else {
1370                        struct child_process cp = CHILD_PROCESS_INIT;
1371                        cp.git_cmd = 1;
1372                        argv_array_pushl(&cp.args, "reset", "--hard", "-q",
1373                                         NULL);
1374                        if (run_command(&cp)) {
1375                                ret = -1;
1376                                goto done;
1377                        }
1378                }
1379
1380                if (keep_index == 1 && !is_null_oid(&info.i_tree)) {
1381                        struct child_process cp_ls = CHILD_PROCESS_INIT;
1382                        struct child_process cp_checkout = CHILD_PROCESS_INIT;
1383                        struct strbuf out = STRBUF_INIT;
1384
1385                        if (reset_tree(&info.i_tree, 0, 1)) {
1386                                ret = -1;
1387                                goto done;
1388                        }
1389
1390                        cp_ls.git_cmd = 1;
1391                        argv_array_pushl(&cp_ls.args, "ls-files", "-z",
1392                                         "--modified", "--", NULL);
1393
1394                        add_pathspecs(&cp_ls.args, ps);
1395                        if (pipe_command(&cp_ls, NULL, 0, &out, 0, NULL, 0)) {
1396                                ret = -1;
1397                                goto done;
1398                        }
1399
1400                        cp_checkout.git_cmd = 1;
1401                        argv_array_pushl(&cp_checkout.args, "checkout-index",
1402                                         "-z", "--force", "--stdin", NULL);
1403                        if (pipe_command(&cp_checkout, out.buf, out.len, NULL,
1404                                         0, NULL, 0)) {
1405                                ret = -1;
1406                                goto done;
1407                        }
1408                }
1409                goto done;
1410        } else {
1411                struct child_process cp = CHILD_PROCESS_INIT;
1412
1413                cp.git_cmd = 1;
1414                argv_array_pushl(&cp.args, "apply", "-R", NULL);
1415
1416                if (pipe_command(&cp, patch.buf, patch.len, NULL, 0, NULL, 0)) {
1417                        fprintf_ln(stderr, _("Cannot remove worktree changes"));
1418                        ret = -1;
1419                        goto done;
1420                }
1421
1422                if (keep_index < 1) {
1423                        struct child_process cp = CHILD_PROCESS_INIT;
1424
1425                        cp.git_cmd = 1;
1426                        argv_array_pushl(&cp.args, "reset", "-q", "--", NULL);
1427                        add_pathspecs(&cp.args, ps);
1428                        if (run_command(&cp)) {
1429                                ret = -1;
1430                                goto done;
1431                        }
1432                }
1433                goto done;
1434        }
1435
1436done:
1437        strbuf_release(&stash_msg_buf);
1438        return ret;
1439}
1440
1441static int push_stash(int argc, const char **argv, const char *prefix)
1442{
1443        int keep_index = -1;
1444        int patch_mode = 0;
1445        int include_untracked = 0;
1446        int quiet = 0;
1447        const char *stash_msg = NULL;
1448        struct pathspec ps;
1449        struct option options[] = {
1450                OPT_BOOL('k', "keep-index", &keep_index,
1451                         N_("keep index")),
1452                OPT_BOOL('p', "patch", &patch_mode,
1453                         N_("stash in patch mode")),
1454                OPT__QUIET(&quiet, N_("quiet mode")),
1455                OPT_BOOL('u', "include-untracked", &include_untracked,
1456                         N_("include untracked files in stash")),
1457                OPT_SET_INT('a', "all", &include_untracked,
1458                            N_("include ignore files"), 2),
1459                OPT_STRING('m', "message", &stash_msg, N_("message"),
1460                           N_("stash message")),
1461                OPT_END()
1462        };
1463
1464        argc = parse_options(argc, argv, prefix, options,
1465                             git_stash_helper_push_usage,
1466                             0);
1467
1468        parse_pathspec(&ps, 0, PATHSPEC_PREFER_FULL, prefix, argv);
1469        return do_push_stash(ps, stash_msg, quiet, keep_index, patch_mode,
1470                             include_untracked);
1471}
1472
1473int cmd_stash__helper(int argc, const char **argv, const char *prefix)
1474{
1475        pid_t pid = getpid();
1476        const char *index_file;
1477
1478        struct option options[] = {
1479                OPT_END()
1480        };
1481
1482        git_config(git_diff_basic_config, NULL);
1483
1484        argc = parse_options(argc, argv, prefix, options, git_stash_helper_usage,
1485                             PARSE_OPT_KEEP_UNKNOWN | PARSE_OPT_KEEP_DASHDASH);
1486
1487        index_file = get_index_file();
1488        strbuf_addf(&stash_index_path, "%s.stash.%" PRIuMAX, index_file,
1489                    (uintmax_t)pid);
1490
1491        if (argc < 1)
1492                usage_with_options(git_stash_helper_usage, options);
1493        if (!strcmp(argv[0], "apply"))
1494                return !!apply_stash(argc, argv, prefix);
1495        else if (!strcmp(argv[0], "clear"))
1496                return !!clear_stash(argc, argv, prefix);
1497        else if (!strcmp(argv[0], "drop"))
1498                return !!drop_stash(argc, argv, prefix);
1499        else if (!strcmp(argv[0], "pop"))
1500                return !!pop_stash(argc, argv, prefix);
1501        else if (!strcmp(argv[0], "branch"))
1502                return !!branch_stash(argc, argv, prefix);
1503        else if (!strcmp(argv[0], "list"))
1504                return !!list_stash(argc, argv, prefix);
1505        else if (!strcmp(argv[0], "show"))
1506                return !!show_stash(argc, argv, prefix);
1507        else if (!strcmp(argv[0], "store"))
1508                return !!store_stash(argc, argv, prefix);
1509        else if (!strcmp(argv[0], "create"))
1510                return !!create_stash(argc, argv, prefix);
1511        else if (!strcmp(argv[0], "push"))
1512                return !!push_stash(argc, argv, prefix);
1513
1514        usage_msg_opt(xstrfmt(_("unknown subcommand: %s"), argv[0]),
1515                      git_stash_helper_usage, options);
1516}