Coverage Report

Created: 2024-09-08 06:23

/src/git/builtin/stash.c
Line
Count
Source (jump to first uncovered line)
1
#include "builtin.h"
2
#include "abspath.h"
3
#include "config.h"
4
#include "environment.h"
5
#include "gettext.h"
6
#include "hash.h"
7
#include "hex.h"
8
#include "object-name.h"
9
#include "parse-options.h"
10
#include "refs.h"
11
#include "lockfile.h"
12
#include "cache-tree.h"
13
#include "unpack-trees.h"
14
#include "merge-recursive.h"
15
#include "merge-ort-wrappers.h"
16
#include "strvec.h"
17
#include "run-command.h"
18
#include "dir.h"
19
#include "entry.h"
20
#include "preload-index.h"
21
#include "read-cache.h"
22
#include "rerere.h"
23
#include "revision.h"
24
#include "setup.h"
25
#include "sparse-index.h"
26
#include "log-tree.h"
27
#include "diffcore.h"
28
#include "reflog.h"
29
#include "add-interactive.h"
30
31
0
#define INCLUDE_ALL_FILES 2
32
33
#define BUILTIN_STASH_LIST_USAGE \
34
  N_("git stash list [<log-options>]")
35
#define BUILTIN_STASH_SHOW_USAGE \
36
  N_("git stash show [-u | --include-untracked | --only-untracked] [<diff-options>] [<stash>]")
37
#define BUILTIN_STASH_DROP_USAGE \
38
  N_("git stash drop [-q | --quiet] [<stash>]")
39
#define BUILTIN_STASH_POP_USAGE \
40
  N_("git stash pop [--index] [-q | --quiet] [<stash>]")
41
#define BUILTIN_STASH_APPLY_USAGE \
42
  N_("git stash apply [--index] [-q | --quiet] [<stash>]")
43
#define BUILTIN_STASH_BRANCH_USAGE \
44
  N_("git stash branch <branchname> [<stash>]")
45
#define BUILTIN_STASH_STORE_USAGE \
46
  N_("git stash store [(-m | --message) <message>] [-q | --quiet] <commit>")
47
#define BUILTIN_STASH_PUSH_USAGE \
48
  N_("git stash [push [-p | --patch] [-S | --staged] [-k | --[no-]keep-index] [-q | --quiet]\n" \
49
     "          [-u | --include-untracked] [-a | --all] [(-m | --message) <message>]\n" \
50
     "          [--pathspec-from-file=<file> [--pathspec-file-nul]]\n" \
51
     "          [--] [<pathspec>...]]")
52
#define BUILTIN_STASH_SAVE_USAGE \
53
  N_("git stash save [-p | --patch] [-S | --staged] [-k | --[no-]keep-index] [-q | --quiet]\n" \
54
     "          [-u | --include-untracked] [-a | --all] [<message>]")
55
#define BUILTIN_STASH_CREATE_USAGE \
56
  N_("git stash create [<message>]")
57
#define BUILTIN_STASH_CLEAR_USAGE \
58
  "git stash clear"
59
60
static const char * const git_stash_usage[] = {
61
  BUILTIN_STASH_LIST_USAGE,
62
  BUILTIN_STASH_SHOW_USAGE,
63
  BUILTIN_STASH_DROP_USAGE,
64
  BUILTIN_STASH_POP_USAGE,
65
  BUILTIN_STASH_APPLY_USAGE,
66
  BUILTIN_STASH_BRANCH_USAGE,
67
  BUILTIN_STASH_PUSH_USAGE,
68
  BUILTIN_STASH_SAVE_USAGE,
69
  BUILTIN_STASH_CLEAR_USAGE,
70
  BUILTIN_STASH_CREATE_USAGE,
71
  BUILTIN_STASH_STORE_USAGE,
72
  NULL
73
};
74
75
static const char * const git_stash_list_usage[] = {
76
  BUILTIN_STASH_LIST_USAGE,
77
  NULL
78
};
79
80
static const char * const git_stash_show_usage[] = {
81
  BUILTIN_STASH_SHOW_USAGE,
82
  NULL
83
};
84
85
static const char * const git_stash_drop_usage[] = {
86
  BUILTIN_STASH_DROP_USAGE,
87
  NULL
88
};
89
90
static const char * const git_stash_pop_usage[] = {
91
  BUILTIN_STASH_POP_USAGE,
92
  NULL
93
};
94
95
static const char * const git_stash_apply_usage[] = {
96
  BUILTIN_STASH_APPLY_USAGE,
97
  NULL
98
};
99
100
static const char * const git_stash_branch_usage[] = {
101
  BUILTIN_STASH_BRANCH_USAGE,
102
  NULL
103
};
104
105
static const char * const git_stash_clear_usage[] = {
106
  BUILTIN_STASH_CLEAR_USAGE,
107
  NULL
108
};
109
110
static const char * const git_stash_store_usage[] = {
111
  BUILTIN_STASH_STORE_USAGE,
112
  NULL
113
};
114
115
static const char * const git_stash_push_usage[] = {
116
  BUILTIN_STASH_PUSH_USAGE,
117
  NULL
118
};
119
120
static const char * const git_stash_save_usage[] = {
121
  BUILTIN_STASH_SAVE_USAGE,
122
  NULL
123
};
124
125
static const char ref_stash[] = "refs/stash";
126
static struct strbuf stash_index_path = STRBUF_INIT;
127
128
/*
129
 * w_commit is set to the commit containing the working tree
130
 * b_commit is set to the base commit
131
 * i_commit is set to the commit containing the index tree
132
 * u_commit is set to the commit containing the untracked files tree
133
 * w_tree is set to the working tree
134
 * b_tree is set to the base tree
135
 * i_tree is set to the index tree
136
 * u_tree is set to the untracked files tree
137
 */
138
struct stash_info {
139
  struct object_id w_commit;
140
  struct object_id b_commit;
141
  struct object_id i_commit;
142
  struct object_id u_commit;
143
  struct object_id w_tree;
144
  struct object_id b_tree;
145
  struct object_id i_tree;
146
  struct object_id u_tree;
147
  struct strbuf revision;
148
  int is_stash_ref;
149
  int has_u;
150
};
151
152
0
#define STASH_INFO_INIT { \
153
0
  .revision = STRBUF_INIT, \
154
0
}
155
156
static void free_stash_info(struct stash_info *info)
157
0
{
158
0
  strbuf_release(&info->revision);
159
0
}
160
161
static void assert_stash_like(struct stash_info *info, const char *revision)
162
0
{
163
0
  if (get_oidf(&info->b_commit, "%s^1", revision) ||
164
0
      get_oidf(&info->w_tree, "%s:", revision) ||
165
0
      get_oidf(&info->b_tree, "%s^1:", revision) ||
166
0
      get_oidf(&info->i_tree, "%s^2:", revision))
167
0
    die(_("'%s' is not a stash-like commit"), revision);
168
0
}
169
170
static int get_stash_info(struct stash_info *info, int argc, const char **argv)
171
0
{
172
0
  int ret;
173
0
  char *end_of_rev;
174
0
  char *expanded_ref;
175
0
  const char *revision;
176
0
  const char *commit = NULL;
177
0
  struct object_id dummy;
178
0
  struct strbuf symbolic = STRBUF_INIT;
179
180
0
  if (argc > 1) {
181
0
    int i;
182
0
    struct strbuf refs_msg = STRBUF_INIT;
183
184
0
    for (i = 0; i < argc; i++)
185
0
      strbuf_addf(&refs_msg, " '%s'", argv[i]);
186
187
0
    fprintf_ln(stderr, _("Too many revisions specified:%s"),
188
0
         refs_msg.buf);
189
0
    strbuf_release(&refs_msg);
190
191
0
    return -1;
192
0
  }
193
194
0
  if (argc == 1)
195
0
    commit = argv[0];
196
197
0
  if (!commit) {
198
0
    if (!refs_ref_exists(get_main_ref_store(the_repository), ref_stash)) {
199
0
      fprintf_ln(stderr, _("No stash entries found."));
200
0
      return -1;
201
0
    }
202
203
0
    strbuf_addf(&info->revision, "%s@{0}", ref_stash);
204
0
  } else if (strspn(commit, "0123456789") == strlen(commit)) {
205
0
    strbuf_addf(&info->revision, "%s@{%s}", ref_stash, commit);
206
0
  } else {
207
0
    strbuf_addstr(&info->revision, commit);
208
0
  }
209
210
0
  revision = info->revision.buf;
211
212
0
  if (repo_get_oid(the_repository, revision, &info->w_commit))
213
0
    return error(_("%s is not a valid reference"), revision);
214
215
0
  assert_stash_like(info, revision);
216
217
0
  info->has_u = !get_oidf(&info->u_tree, "%s^3:", revision);
218
219
0
  end_of_rev = strchrnul(revision, '@');
220
0
  strbuf_add(&symbolic, revision, end_of_rev - revision);
221
222
0
  ret = repo_dwim_ref(the_repository, symbolic.buf, symbolic.len,
223
0
          &dummy, &expanded_ref, 0);
224
0
  strbuf_release(&symbolic);
225
0
  switch (ret) {
226
0
  case 0: /* Not found, but valid ref */
227
0
    info->is_stash_ref = 0;
228
0
    break;
229
0
  case 1:
230
0
    info->is_stash_ref = !strcmp(expanded_ref, ref_stash);
231
0
    break;
232
0
  default: /* Invalid or ambiguous */
233
0
    break;
234
0
  }
235
236
0
  free(expanded_ref);
237
0
  return !(ret == 0 || ret == 1);
238
0
}
239
240
static int do_clear_stash(void)
241
0
{
242
0
  struct object_id obj;
243
0
  if (repo_get_oid(the_repository, ref_stash, &obj))
244
0
    return 0;
245
246
0
  return refs_delete_ref(get_main_ref_store(the_repository), NULL,
247
0
             ref_stash, &obj, 0);
248
0
}
249
250
static int clear_stash(int argc, const char **argv, const char *prefix)
251
0
{
252
0
  struct option options[] = {
253
0
    OPT_END()
254
0
  };
255
256
0
  argc = parse_options(argc, argv, prefix, options,
257
0
           git_stash_clear_usage,
258
0
           PARSE_OPT_STOP_AT_NON_OPTION);
259
260
0
  if (argc)
261
0
    return error(_("git stash clear with arguments is "
262
0
             "unimplemented"));
263
264
0
  return do_clear_stash();
265
0
}
266
267
static int reset_tree(struct object_id *i_tree, int update, int reset)
268
0
{
269
0
  int nr_trees = 1;
270
0
  struct unpack_trees_options opts;
271
0
  struct tree_desc t[MAX_UNPACK_TREES];
272
0
  struct tree *tree;
273
0
  struct lock_file lock_file = LOCK_INIT;
274
275
0
  repo_read_index_preload(the_repository, NULL, 0);
276
0
  if (refresh_index(the_repository->index, REFRESH_QUIET, NULL, NULL, NULL))
277
0
    return -1;
278
279
0
  repo_hold_locked_index(the_repository, &lock_file, LOCK_DIE_ON_ERROR);
280
281
0
  memset(&opts, 0, sizeof(opts));
282
283
0
  tree = parse_tree_indirect(i_tree);
284
0
  if (parse_tree(tree))
285
0
    return -1;
286
287
0
  init_tree_desc(t, &tree->object.oid, tree->buffer, tree->size);
288
289
0
  opts.head_idx = 1;
290
0
  opts.src_index = the_repository->index;
291
0
  opts.dst_index = the_repository->index;
292
0
  opts.merge = 1;
293
0
  opts.reset = reset ? UNPACK_RESET_PROTECT_UNTRACKED : 0;
294
0
  opts.update = update;
295
0
  if (update)
296
0
    opts.preserve_ignored = 0; /* FIXME: !overwrite_ignore */
297
0
  opts.fn = oneway_merge;
298
299
0
  if (unpack_trees(nr_trees, t, &opts))
300
0
    return -1;
301
302
0
  if (write_locked_index(the_repository->index, &lock_file, COMMIT_LOCK))
303
0
    return error(_("unable to write new index file"));
304
305
0
  return 0;
306
0
}
307
308
static int diff_tree_binary(struct strbuf *out, struct object_id *w_commit)
309
0
{
310
0
  struct child_process cp = CHILD_PROCESS_INIT;
311
0
  const char *w_commit_hex = oid_to_hex(w_commit);
312
313
  /*
314
   * Diff-tree would not be very hard to replace with a native function,
315
   * however it should be done together with apply_cached.
316
   */
317
0
  cp.git_cmd = 1;
318
0
  strvec_pushl(&cp.args, "diff-tree", "--binary", NULL);
319
0
  strvec_pushf(&cp.args, "%s^2^..%s^2", w_commit_hex, w_commit_hex);
320
321
0
  return pipe_command(&cp, NULL, 0, out, 0, NULL, 0);
322
0
}
323
324
static int apply_cached(struct strbuf *out)
325
0
{
326
0
  struct child_process cp = CHILD_PROCESS_INIT;
327
328
  /*
329
   * Apply currently only reads either from stdin or a file, thus
330
   * apply_all_patches would have to be updated to optionally take a
331
   * buffer.
332
   */
333
0
  cp.git_cmd = 1;
334
0
  strvec_pushl(&cp.args, "apply", "--cached", NULL);
335
0
  return pipe_command(&cp, out->buf, out->len, NULL, 0, NULL, 0);
336
0
}
337
338
static int reset_head(void)
339
0
{
340
0
  struct child_process cp = CHILD_PROCESS_INIT;
341
342
  /*
343
   * Reset is overall quite simple, however there is no current public
344
   * API for resetting.
345
   */
346
0
  cp.git_cmd = 1;
347
0
  strvec_pushl(&cp.args, "reset", "--quiet", "--refresh", NULL);
348
349
0
  return run_command(&cp);
350
0
}
351
352
static int is_path_a_directory(const char *path)
353
0
{
354
  /*
355
   * This function differs from abspath.c:is_directory() in that
356
   * here we use lstat() instead of stat(); we do not want to
357
   * follow symbolic links here.
358
   */
359
0
  struct stat st;
360
0
  return (!lstat(path, &st) && S_ISDIR(st.st_mode));
361
0
}
362
363
static void add_diff_to_buf(struct diff_queue_struct *q,
364
          struct diff_options *options UNUSED,
365
          void *data)
366
0
{
367
0
  int i;
368
369
0
  for (i = 0; i < q->nr; i++) {
370
0
    if (is_path_a_directory(q->queue[i]->one->path))
371
0
      continue;
372
373
0
    strbuf_addstr(data, q->queue[i]->one->path);
374
375
    /* NUL-terminate: will be fed to update-index -z */
376
0
    strbuf_addch(data, '\0');
377
0
  }
378
0
}
379
380
static int restore_untracked(struct object_id *u_tree)
381
0
{
382
0
  int res;
383
0
  struct child_process cp = CHILD_PROCESS_INIT;
384
385
  /*
386
   * We need to run restore files from a given index, but without
387
   * affecting the current index, so we use GIT_INDEX_FILE with
388
   * run_command to fork processes that will not interfere.
389
   */
390
0
  cp.git_cmd = 1;
391
0
  strvec_push(&cp.args, "read-tree");
392
0
  strvec_push(&cp.args, oid_to_hex(u_tree));
393
0
  strvec_pushf(&cp.env, "GIT_INDEX_FILE=%s",
394
0
         stash_index_path.buf);
395
0
  if (run_command(&cp)) {
396
0
    remove_path(stash_index_path.buf);
397
0
    return -1;
398
0
  }
399
400
0
  child_process_init(&cp);
401
0
  cp.git_cmd = 1;
402
0
  strvec_pushl(&cp.args, "checkout-index", "--all", NULL);
403
0
  strvec_pushf(&cp.env, "GIT_INDEX_FILE=%s",
404
0
         stash_index_path.buf);
405
406
0
  res = run_command(&cp);
407
0
  remove_path(stash_index_path.buf);
408
0
  return res;
409
0
}
410
411
static void unstage_changes_unless_new(struct object_id *orig_tree)
412
0
{
413
  /*
414
   * When we enter this function, there has been a clean merge of
415
   * relevant trees, and the merge logic always stages whatever merges
416
   * cleanly.  We want to unstage those changes, unless it corresponds
417
   * to a file that didn't exist as of orig_tree.
418
   *
419
   * However, if any SKIP_WORKTREE path is modified relative to
420
   * orig_tree, then we want to clear the SKIP_WORKTREE bit and write
421
   * it to the worktree before unstaging.
422
   */
423
424
0
  struct checkout state = CHECKOUT_INIT;
425
0
  struct diff_options diff_opts;
426
0
  struct lock_file lock = LOCK_INIT;
427
0
  int i;
428
429
  /* If any entries have skip_worktree set, we'll have to check 'em out */
430
0
  state.force = 1;
431
0
  state.quiet = 1;
432
0
  state.refresh_cache = 1;
433
0
  state.istate = the_repository->index;
434
435
  /*
436
   * Step 1: get a difference between orig_tree (which corresponding
437
   * to the index before a merge was run) and the current index
438
   * (reflecting the changes brought in by the merge).
439
   */
440
0
  repo_diff_setup(the_repository, &diff_opts);
441
0
  diff_opts.flags.recursive = 1;
442
0
  diff_opts.detect_rename = 0;
443
0
  diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT;
444
0
  diff_setup_done(&diff_opts);
445
446
0
  do_diff_cache(orig_tree, &diff_opts);
447
0
  diffcore_std(&diff_opts);
448
449
  /* Iterate over the paths that changed due to the merge... */
450
0
  for (i = 0; i < diff_queued_diff.nr; i++) {
451
0
    struct diff_filepair *p;
452
0
    struct cache_entry *ce;
453
0
    int pos;
454
455
    /* Look up the path's position in the current index. */
456
0
    p = diff_queued_diff.queue[i];
457
0
    pos = index_name_pos(the_repository->index, p->two->path,
458
0
             strlen(p->two->path));
459
460
    /*
461
     * Step 2: Place changes in the working tree
462
     *
463
     * Stash is about restoring changes *to the working tree*.
464
     * So if the merge successfully got a new version of some
465
     * path, but left it out of the working tree, then clear the
466
     * SKIP_WORKTREE bit and write it to the working tree.
467
     */
468
0
    if (pos >= 0 && ce_skip_worktree(the_repository->index->cache[pos])) {
469
0
      struct stat st;
470
471
0
      ce = the_repository->index->cache[pos];
472
0
      if (!lstat(ce->name, &st)) {
473
        /* Conflicting path present; relocate it */
474
0
        struct strbuf new_path = STRBUF_INIT;
475
0
        int fd;
476
477
0
        strbuf_addf(&new_path,
478
0
              "%s.stash.XXXXXX", ce->name);
479
0
        fd = xmkstemp(new_path.buf);
480
0
        close(fd);
481
0
        printf(_("WARNING: Untracked file in way of "
482
0
           "tracked file!  Renaming\n "
483
0
           "           %s -> %s\n"
484
0
           "         to make room.\n"),
485
0
               ce->name, new_path.buf);
486
0
        if (rename(ce->name, new_path.buf))
487
0
          die("Failed to move %s to %s",
488
0
              ce->name, new_path.buf);
489
0
        strbuf_release(&new_path);
490
0
      }
491
0
      checkout_entry(ce, &state, NULL, NULL);
492
0
      ce->ce_flags &= ~CE_SKIP_WORKTREE;
493
0
    }
494
495
    /*
496
     * Step 3: "unstage" changes, as long as they are still tracked
497
     */
498
0
    if (p->one->oid_valid) {
499
      /*
500
       * Path existed in orig_tree; restore index entry
501
       * from that tree in order to "unstage" the changes.
502
       */
503
0
      int option = ADD_CACHE_OK_TO_REPLACE;
504
0
      if (pos < 0)
505
0
        option = ADD_CACHE_OK_TO_ADD;
506
507
0
      ce = make_cache_entry(the_repository->index,
508
0
                p->one->mode,
509
0
                &p->one->oid,
510
0
                p->one->path,
511
0
                0, 0);
512
0
      add_index_entry(the_repository->index, ce, option);
513
0
    }
514
0
  }
515
0
  diff_flush(&diff_opts);
516
517
  /*
518
   * Step 4: write the new index to disk
519
   */
520
0
  repo_hold_locked_index(the_repository, &lock, LOCK_DIE_ON_ERROR);
521
0
  if (write_locked_index(the_repository->index, &lock,
522
0
             COMMIT_LOCK | SKIP_IF_UNCHANGED))
523
0
    die(_("could not write index"));
524
0
}
525
526
static int do_apply_stash(const char *prefix, struct stash_info *info,
527
        int index, int quiet)
528
0
{
529
0
  int clean, ret;
530
0
  int has_index = index;
531
0
  struct merge_options o;
532
0
  struct object_id c_tree;
533
0
  struct object_id index_tree;
534
0
  struct tree *head, *merge, *merge_base;
535
0
  struct lock_file lock = LOCK_INIT;
536
537
0
  repo_read_index_preload(the_repository, NULL, 0);
538
0
  if (repo_refresh_and_write_index(the_repository, REFRESH_QUIET, 0, 0,
539
0
           NULL, NULL, NULL))
540
0
    return error(_("could not write index"));
541
542
0
  if (write_index_as_tree(&c_tree, the_repository->index, get_index_file(), 0,
543
0
        NULL))
544
0
    return error(_("cannot apply a stash in the middle of a merge"));
545
546
0
  if (index) {
547
0
    if (oideq(&info->b_tree, &info->i_tree) ||
548
0
        oideq(&c_tree, &info->i_tree)) {
549
0
      has_index = 0;
550
0
    } else {
551
0
      struct strbuf out = STRBUF_INIT;
552
553
0
      if (diff_tree_binary(&out, &info->w_commit)) {
554
0
        strbuf_release(&out);
555
0
        return error(_("could not generate diff %s^!."),
556
0
               oid_to_hex(&info->w_commit));
557
0
      }
558
559
0
      ret = apply_cached(&out);
560
0
      strbuf_release(&out);
561
0
      if (ret)
562
0
        return error(_("conflicts in index. "
563
0
                 "Try without --index."));
564
565
0
      discard_index(the_repository->index);
566
0
      repo_read_index(the_repository);
567
0
      if (write_index_as_tree(&index_tree, the_repository->index,
568
0
            get_index_file(), 0, NULL))
569
0
        return error(_("could not save index tree"));
570
571
0
      reset_head();
572
0
      discard_index(the_repository->index);
573
0
      repo_read_index(the_repository);
574
0
    }
575
0
  }
576
577
0
  init_ui_merge_options(&o, the_repository);
578
579
0
  o.branch1 = "Updated upstream";
580
0
  o.branch2 = "Stashed changes";
581
0
  o.ancestor = "Stash base";
582
583
0
  if (oideq(&info->b_tree, &c_tree))
584
0
    o.branch1 = "Version stash was based on";
585
586
0
  if (quiet)
587
0
    o.verbosity = 0;
588
589
0
  if (o.verbosity >= 3)
590
0
    printf_ln(_("Merging %s with %s"), o.branch1, o.branch2);
591
592
0
  head = lookup_tree(o.repo, &c_tree);
593
0
  merge = lookup_tree(o.repo, &info->w_tree);
594
0
  merge_base = lookup_tree(o.repo, &info->b_tree);
595
596
0
  repo_hold_locked_index(o.repo, &lock, LOCK_DIE_ON_ERROR);
597
0
  clean = merge_ort_nonrecursive(&o, head, merge, merge_base);
598
599
  /*
600
   * If 'clean' >= 0, reverse the value for 'ret' so 'ret' is 0 when the
601
   * merge was clean, and nonzero if the merge was unclean or encountered
602
   * an error.
603
   */
604
0
  ret = clean >= 0 ? !clean : clean;
605
606
0
  if (ret < 0)
607
0
    rollback_lock_file(&lock);
608
0
  else if (write_locked_index(o.repo->index, &lock,
609
0
              COMMIT_LOCK | SKIP_IF_UNCHANGED))
610
0
    ret = error(_("could not write index"));
611
612
0
  if (ret) {
613
0
    repo_rerere(the_repository, 0);
614
615
0
    if (index)
616
0
      fprintf_ln(stderr, _("Index was not unstashed."));
617
618
0
    goto restore_untracked;
619
0
  }
620
621
0
  if (has_index) {
622
0
    if (reset_tree(&index_tree, 0, 0))
623
0
      ret = -1;
624
0
  } else {
625
0
    unstage_changes_unless_new(&c_tree);
626
0
  }
627
628
0
restore_untracked:
629
0
  if (info->has_u && restore_untracked(&info->u_tree))
630
0
    ret = error(_("could not restore untracked files from stash"));
631
632
0
  if (!quiet) {
633
0
    struct child_process cp = CHILD_PROCESS_INIT;
634
635
    /*
636
     * Status is quite simple and could be replaced with calls to
637
     * wt_status in the future, but it adds complexities which may
638
     * require more tests.
639
     */
640
0
    cp.git_cmd = 1;
641
0
    cp.dir = prefix;
642
0
    strvec_pushf(&cp.env, GIT_WORK_TREE_ENVIRONMENT"=%s",
643
0
           absolute_path(get_git_work_tree()));
644
0
    strvec_pushf(&cp.env, GIT_DIR_ENVIRONMENT"=%s",
645
0
           absolute_path(get_git_dir()));
646
0
    strvec_push(&cp.args, "status");
647
0
    run_command(&cp);
648
0
  }
649
650
0
  return ret;
651
0
}
652
653
static int apply_stash(int argc, const char **argv, const char *prefix)
654
0
{
655
0
  int ret = -1;
656
0
  int quiet = 0;
657
0
  int index = 0;
658
0
  struct stash_info info = STASH_INFO_INIT;
659
0
  struct option options[] = {
660
0
    OPT__QUIET(&quiet, N_("be quiet, only report errors")),
661
0
    OPT_BOOL(0, "index", &index,
662
0
       N_("attempt to recreate the index")),
663
0
    OPT_END()
664
0
  };
665
666
0
  argc = parse_options(argc, argv, prefix, options,
667
0
           git_stash_apply_usage, 0);
668
669
0
  if (get_stash_info(&info, argc, argv))
670
0
    goto cleanup;
671
672
0
  ret = do_apply_stash(prefix, &info, index, quiet);
673
0
cleanup:
674
0
  free_stash_info(&info);
675
0
  return ret;
676
0
}
677
678
static int reject_reflog_ent(struct object_id *ooid UNUSED,
679
           struct object_id *noid UNUSED,
680
           const char *email UNUSED,
681
           timestamp_t timestamp UNUSED,
682
           int tz UNUSED, const char *message UNUSED,
683
           void *cb_data UNUSED)
684
0
{
685
0
  return 1;
686
0
}
687
688
static int reflog_is_empty(const char *refname)
689
0
{
690
0
  return !refs_for_each_reflog_ent(get_main_ref_store(the_repository),
691
0
           refname, reject_reflog_ent, NULL);
692
0
}
693
694
static int do_drop_stash(struct stash_info *info, int quiet)
695
0
{
696
0
  if (!reflog_delete(info->revision.buf,
697
0
         EXPIRE_REFLOGS_REWRITE | EXPIRE_REFLOGS_UPDATE_REF,
698
0
         0)) {
699
0
    if (!quiet)
700
0
      printf_ln(_("Dropped %s (%s)"), info->revision.buf,
701
0
          oid_to_hex(&info->w_commit));
702
0
  } else {
703
0
    return error(_("%s: Could not drop stash entry"),
704
0
           info->revision.buf);
705
0
  }
706
707
0
  if (reflog_is_empty(ref_stash))
708
0
    do_clear_stash();
709
710
0
  return 0;
711
0
}
712
713
static int get_stash_info_assert(struct stash_info *info, int argc,
714
         const char **argv)
715
0
{
716
0
  int ret = get_stash_info(info, argc, argv);
717
718
0
  if (ret < 0)
719
0
    return ret;
720
721
0
  if (!info->is_stash_ref)
722
0
    return error(_("'%s' is not a stash reference"), info->revision.buf);
723
724
0
  return 0;
725
0
}
726
727
static int drop_stash(int argc, const char **argv, const char *prefix)
728
0
{
729
0
  int ret = -1;
730
0
  int quiet = 0;
731
0
  struct stash_info info = STASH_INFO_INIT;
732
0
  struct option options[] = {
733
0
    OPT__QUIET(&quiet, N_("be quiet, only report errors")),
734
0
    OPT_END()
735
0
  };
736
737
0
  argc = parse_options(argc, argv, prefix, options,
738
0
           git_stash_drop_usage, 0);
739
740
0
  if (get_stash_info_assert(&info, argc, argv))
741
0
    goto cleanup;
742
743
0
  ret = do_drop_stash(&info, quiet);
744
0
cleanup:
745
0
  free_stash_info(&info);
746
0
  return ret;
747
0
}
748
749
static int pop_stash(int argc, const char **argv, const char *prefix)
750
0
{
751
0
  int ret = -1;
752
0
  int index = 0;
753
0
  int quiet = 0;
754
0
  struct stash_info info = STASH_INFO_INIT;
755
0
  struct option options[] = {
756
0
    OPT__QUIET(&quiet, N_("be quiet, only report errors")),
757
0
    OPT_BOOL(0, "index", &index,
758
0
       N_("attempt to recreate the index")),
759
0
    OPT_END()
760
0
  };
761
762
0
  argc = parse_options(argc, argv, prefix, options,
763
0
           git_stash_pop_usage, 0);
764
765
0
  if (get_stash_info_assert(&info, argc, argv))
766
0
    goto cleanup;
767
768
0
  if ((ret = do_apply_stash(prefix, &info, index, quiet)))
769
0
    printf_ln(_("The stash entry is kept in case "
770
0
          "you need it again."));
771
0
  else
772
0
    ret = do_drop_stash(&info, quiet);
773
774
0
cleanup:
775
0
  free_stash_info(&info);
776
0
  return ret;
777
0
}
778
779
static int branch_stash(int argc, const char **argv, const char *prefix)
780
0
{
781
0
  int ret = -1;
782
0
  const char *branch = NULL;
783
0
  struct stash_info info = STASH_INFO_INIT;
784
0
  struct child_process cp = CHILD_PROCESS_INIT;
785
0
  struct option options[] = {
786
0
    OPT_END()
787
0
  };
788
789
0
  argc = parse_options(argc, argv, prefix, options,
790
0
           git_stash_branch_usage, 0);
791
792
0
  if (!argc) {
793
0
    fprintf_ln(stderr, _("No branch name specified"));
794
0
    return -1;
795
0
  }
796
797
0
  branch = argv[0];
798
799
0
  if (get_stash_info(&info, argc - 1, argv + 1))
800
0
    goto cleanup;
801
802
0
  cp.git_cmd = 1;
803
0
  strvec_pushl(&cp.args, "checkout", "-b", NULL);
804
0
  strvec_push(&cp.args, branch);
805
0
  strvec_push(&cp.args, oid_to_hex(&info.b_commit));
806
0
  ret = run_command(&cp);
807
0
  if (!ret)
808
0
    ret = do_apply_stash(prefix, &info, 1, 0);
809
0
  if (!ret && info.is_stash_ref)
810
0
    ret = do_drop_stash(&info, 0);
811
812
0
cleanup:
813
0
  free_stash_info(&info);
814
0
  return ret;
815
0
}
816
817
static int list_stash(int argc, const char **argv, const char *prefix)
818
0
{
819
0
  struct child_process cp = CHILD_PROCESS_INIT;
820
0
  struct option options[] = {
821
0
    OPT_END()
822
0
  };
823
824
0
  argc = parse_options(argc, argv, prefix, options,
825
0
           git_stash_list_usage,
826
0
           PARSE_OPT_KEEP_UNKNOWN_OPT);
827
828
0
  if (!refs_ref_exists(get_main_ref_store(the_repository), ref_stash))
829
0
    return 0;
830
831
0
  cp.git_cmd = 1;
832
0
  strvec_pushl(&cp.args, "log", "--format=%gd: %gs", "-g",
833
0
         "--first-parent", NULL);
834
0
  strvec_pushv(&cp.args, argv);
835
0
  strvec_push(&cp.args, ref_stash);
836
0
  strvec_push(&cp.args, "--");
837
0
  return run_command(&cp);
838
0
}
839
840
static int show_stat = 1;
841
static int show_patch;
842
static int show_include_untracked;
843
844
static int git_stash_config(const char *var, const char *value,
845
          const struct config_context *ctx, void *cb)
846
0
{
847
0
  if (!strcmp(var, "stash.showstat")) {
848
0
    show_stat = git_config_bool(var, value);
849
0
    return 0;
850
0
  }
851
0
  if (!strcmp(var, "stash.showpatch")) {
852
0
    show_patch = git_config_bool(var, value);
853
0
    return 0;
854
0
  }
855
0
  if (!strcmp(var, "stash.showincludeuntracked")) {
856
0
    show_include_untracked = git_config_bool(var, value);
857
0
    return 0;
858
0
  }
859
0
  return git_diff_basic_config(var, value, ctx, cb);
860
0
}
861
862
static void diff_include_untracked(const struct stash_info *info, struct diff_options *diff_opt)
863
0
{
864
0
  const struct object_id *oid[] = { &info->w_commit, &info->u_tree };
865
0
  struct tree *tree[ARRAY_SIZE(oid)];
866
0
  struct tree_desc tree_desc[ARRAY_SIZE(oid)];
867
0
  struct unpack_trees_options unpack_tree_opt = { 0 };
868
0
  int i;
869
870
0
  for (i = 0; i < ARRAY_SIZE(oid); i++) {
871
0
    tree[i] = parse_tree_indirect(oid[i]);
872
0
    if (parse_tree(tree[i]) < 0)
873
0
      die(_("failed to parse tree"));
874
0
    init_tree_desc(&tree_desc[i], &tree[i]->object.oid,
875
0
             tree[i]->buffer, tree[i]->size);
876
0
  }
877
878
0
  unpack_tree_opt.head_idx = -1;
879
0
  unpack_tree_opt.src_index = the_repository->index;
880
0
  unpack_tree_opt.dst_index = the_repository->index;
881
0
  unpack_tree_opt.merge = 1;
882
0
  unpack_tree_opt.fn = stash_worktree_untracked_merge;
883
884
0
  if (unpack_trees(ARRAY_SIZE(tree_desc), tree_desc, &unpack_tree_opt))
885
0
    die(_("failed to unpack trees"));
886
887
0
  do_diff_cache(&info->b_commit, diff_opt);
888
0
}
889
890
static int show_stash(int argc, const char **argv, const char *prefix)
891
0
{
892
0
  int i;
893
0
  int ret = -1;
894
0
  struct stash_info info = STASH_INFO_INIT;
895
0
  struct rev_info rev;
896
0
  struct strvec stash_args = STRVEC_INIT;
897
0
  struct strvec revision_args = STRVEC_INIT;
898
0
  enum {
899
0
    UNTRACKED_NONE,
900
0
    UNTRACKED_INCLUDE,
901
0
    UNTRACKED_ONLY
902
0
  } show_untracked = show_include_untracked ? UNTRACKED_INCLUDE : UNTRACKED_NONE;
903
0
  struct option options[] = {
904
0
    OPT_SET_INT('u', "include-untracked", &show_untracked,
905
0
          N_("include untracked files in the stash"),
906
0
          UNTRACKED_INCLUDE),
907
0
    OPT_SET_INT_F(0, "only-untracked", &show_untracked,
908
0
            N_("only show untracked files in the stash"),
909
0
            UNTRACKED_ONLY, PARSE_OPT_NONEG),
910
0
    OPT_END()
911
0
  };
912
0
  int do_usage = 0;
913
914
0
  init_diff_ui_defaults();
915
0
  git_config(git_diff_ui_config, NULL);
916
0
  repo_init_revisions(the_repository, &rev, prefix);
917
918
0
  argc = parse_options(argc, argv, prefix, options, git_stash_show_usage,
919
0
           PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN_OPT |
920
0
           PARSE_OPT_KEEP_DASHDASH);
921
922
0
  strvec_push(&revision_args, argv[0]);
923
0
  for (i = 1; i < argc; i++) {
924
0
    if (argv[i][0] != '-')
925
0
      strvec_push(&stash_args, argv[i]);
926
0
    else
927
0
      strvec_push(&revision_args, argv[i]);
928
0
  }
929
930
0
  if (get_stash_info(&info, stash_args.nr, stash_args.v))
931
0
    goto cleanup;
932
933
  /*
934
   * The config settings are applied only if there are not passed
935
   * any options.
936
   */
937
0
  if (revision_args.nr == 1) {
938
0
    if (show_stat)
939
0
      rev.diffopt.output_format = DIFF_FORMAT_DIFFSTAT;
940
941
0
    if (show_patch)
942
0
      rev.diffopt.output_format |= DIFF_FORMAT_PATCH;
943
944
0
    if (!show_stat && !show_patch) {
945
0
      ret = 0;
946
0
      goto cleanup;
947
0
    }
948
0
  }
949
950
0
  argc = setup_revisions(revision_args.nr, revision_args.v, &rev, NULL);
951
0
  if (argc > 1)
952
0
    goto usage;
953
0
  if (!rev.diffopt.output_format) {
954
0
    rev.diffopt.output_format = DIFF_FORMAT_PATCH;
955
0
    diff_setup_done(&rev.diffopt);
956
0
  }
957
958
0
  rev.diffopt.flags.recursive = 1;
959
0
  setup_diff_pager(&rev.diffopt);
960
0
  switch (show_untracked) {
961
0
  case UNTRACKED_NONE:
962
0
    diff_tree_oid(&info.b_commit, &info.w_commit, "", &rev.diffopt);
963
0
    break;
964
0
  case UNTRACKED_ONLY:
965
0
    if (info.has_u)
966
0
      diff_root_tree_oid(&info.u_tree, "", &rev.diffopt);
967
0
    break;
968
0
  case UNTRACKED_INCLUDE:
969
0
    if (info.has_u)
970
0
      diff_include_untracked(&info, &rev.diffopt);
971
0
    else
972
0
      diff_tree_oid(&info.b_commit, &info.w_commit, "", &rev.diffopt);
973
0
    break;
974
0
  }
975
0
  log_tree_diff_flush(&rev);
976
977
0
  ret = diff_result_code(&rev.diffopt);
978
979
0
cleanup:
980
0
  strvec_clear(&revision_args);
981
0
  strvec_clear(&stash_args);
982
0
  free_stash_info(&info);
983
0
  release_revisions(&rev);
984
0
  if (do_usage)
985
0
    usage_with_options(git_stash_show_usage, options);
986
0
  return ret;
987
0
usage:
988
0
  do_usage = 1;
989
0
  goto cleanup;
990
0
}
991
992
static int do_store_stash(const struct object_id *w_commit, const char *stash_msg,
993
        int quiet)
994
0
{
995
0
  struct stash_info info;
996
0
  char revision[GIT_MAX_HEXSZ];
997
998
0
  oid_to_hex_r(revision, w_commit);
999
0
  assert_stash_like(&info, revision);
1000
1001
0
  if (!stash_msg)
1002
0
    stash_msg = "Created via \"git stash store\".";
1003
1004
0
  if (refs_update_ref(get_main_ref_store(the_repository), stash_msg, ref_stash, w_commit, NULL,
1005
0
          REF_FORCE_CREATE_REFLOG,
1006
0
          quiet ? UPDATE_REFS_QUIET_ON_ERR :
1007
0
          UPDATE_REFS_MSG_ON_ERR)) {
1008
0
    if (!quiet) {
1009
0
      fprintf_ln(stderr, _("Cannot update %s with %s"),
1010
0
           ref_stash, oid_to_hex(w_commit));
1011
0
    }
1012
0
    return -1;
1013
0
  }
1014
1015
0
  return 0;
1016
0
}
1017
1018
static int store_stash(int argc, const char **argv, const char *prefix)
1019
0
{
1020
0
  int quiet = 0;
1021
0
  const char *stash_msg = NULL;
1022
0
  struct object_id obj;
1023
0
  struct object_context dummy = {0};
1024
0
  struct option options[] = {
1025
0
    OPT__QUIET(&quiet, N_("be quiet")),
1026
0
    OPT_STRING('m', "message", &stash_msg, "message",
1027
0
         N_("stash message")),
1028
0
    OPT_END()
1029
0
  };
1030
0
  int ret;
1031
1032
0
  argc = parse_options(argc, argv, prefix, options,
1033
0
           git_stash_store_usage,
1034
0
           PARSE_OPT_KEEP_UNKNOWN_OPT);
1035
1036
0
  if (argc != 1) {
1037
0
    if (!quiet)
1038
0
      fprintf_ln(stderr, _("\"git stash store\" requires one "
1039
0
               "<commit> argument"));
1040
0
    return -1;
1041
0
  }
1042
1043
0
  if (get_oid_with_context(the_repository,
1044
0
         argv[0], quiet ? GET_OID_QUIETLY : 0, &obj,
1045
0
         &dummy)) {
1046
0
    if (!quiet)
1047
0
      fprintf_ln(stderr, _("Cannot update %s with %s"),
1048
0
               ref_stash, argv[0]);
1049
0
    ret = -1;
1050
0
    goto out;
1051
0
  }
1052
1053
0
  ret = do_store_stash(&obj, stash_msg, quiet);
1054
1055
0
out:
1056
0
  object_context_release(&dummy);
1057
0
  return ret;
1058
0
}
1059
1060
static void add_pathspecs(struct strvec *args,
1061
0
        const struct pathspec *ps) {
1062
0
  int i;
1063
1064
0
  for (i = 0; i < ps->nr; i++)
1065
0
    strvec_push(args, ps->items[i].original);
1066
0
}
1067
1068
/*
1069
 * `untracked_files` will be filled with the names of untracked files.
1070
 * The return value is:
1071
 *
1072
 * = 0 if there are not any untracked files
1073
 * > 0 if there are untracked files
1074
 */
1075
static int get_untracked_files(const struct pathspec *ps, int include_untracked,
1076
             struct strbuf *untracked_files)
1077
0
{
1078
0
  int i;
1079
0
  int found = 0;
1080
0
  struct dir_struct dir = DIR_INIT;
1081
1082
0
  if (include_untracked != INCLUDE_ALL_FILES)
1083
0
    setup_standard_excludes(&dir);
1084
1085
0
  fill_directory(&dir, the_repository->index, ps);
1086
0
  for (i = 0; i < dir.nr; i++) {
1087
0
    struct dir_entry *ent = dir.entries[i];
1088
0
    found++;
1089
0
    strbuf_addstr(untracked_files, ent->name);
1090
    /* NUL-terminate: will be fed to update-index -z */
1091
0
    strbuf_addch(untracked_files, '\0');
1092
0
  }
1093
1094
0
  dir_clear(&dir);
1095
0
  return found;
1096
0
}
1097
1098
/*
1099
 * The return value of `check_changes_tracked_files()` can be:
1100
 *
1101
 * < 0 if there was an error
1102
 * = 0 if there are no changes.
1103
 * > 0 if there are changes.
1104
 */
1105
static int check_changes_tracked_files(const struct pathspec *ps)
1106
0
{
1107
0
  struct rev_info rev;
1108
0
  struct object_id dummy;
1109
0
  int ret = 0;
1110
1111
  /* No initial commit. */
1112
0
  if (repo_get_oid(the_repository, "HEAD", &dummy))
1113
0
    return -1;
1114
1115
0
  if (repo_read_index(the_repository) < 0)
1116
0
    return -1;
1117
1118
0
  repo_init_revisions(the_repository, &rev, NULL);
1119
0
  copy_pathspec(&rev.prune_data, ps);
1120
1121
0
  rev.diffopt.flags.quick = 1;
1122
0
  rev.diffopt.flags.ignore_submodules = 1;
1123
0
  rev.abbrev = 0;
1124
1125
0
  add_head_to_pending(&rev);
1126
0
  diff_setup_done(&rev.diffopt);
1127
1128
0
  run_diff_index(&rev, DIFF_INDEX_CACHED);
1129
0
  if (diff_result_code(&rev.diffopt)) {
1130
0
    ret = 1;
1131
0
    goto done;
1132
0
  }
1133
1134
0
  run_diff_files(&rev, 0);
1135
0
  if (diff_result_code(&rev.diffopt)) {
1136
0
    ret = 1;
1137
0
    goto done;
1138
0
  }
1139
1140
0
done:
1141
0
  release_revisions(&rev);
1142
0
  return ret;
1143
0
}
1144
1145
/*
1146
 * The function will fill `untracked_files` with the names of untracked files
1147
 * It will return 1 if there were any changes and 0 if there were not.
1148
 */
1149
static int check_changes(const struct pathspec *ps, int include_untracked,
1150
       struct strbuf *untracked_files)
1151
0
{
1152
0
  int ret = 0;
1153
0
  if (check_changes_tracked_files(ps))
1154
0
    ret = 1;
1155
1156
0
  if (include_untracked && get_untracked_files(ps, include_untracked,
1157
0
                 untracked_files))
1158
0
    ret = 1;
1159
1160
0
  return ret;
1161
0
}
1162
1163
static int save_untracked_files(struct stash_info *info, struct strbuf *msg,
1164
        struct strbuf files)
1165
0
{
1166
0
  int ret = 0;
1167
0
  struct strbuf untracked_msg = STRBUF_INIT;
1168
0
  struct child_process cp_upd_index = CHILD_PROCESS_INIT;
1169
0
  struct index_state istate = INDEX_STATE_INIT(the_repository);
1170
1171
0
  cp_upd_index.git_cmd = 1;
1172
0
  strvec_pushl(&cp_upd_index.args, "update-index", "-z", "--add",
1173
0
         "--remove", "--stdin", NULL);
1174
0
  strvec_pushf(&cp_upd_index.env, "GIT_INDEX_FILE=%s",
1175
0
       stash_index_path.buf);
1176
1177
0
  strbuf_addf(&untracked_msg, "untracked files on %s\n", msg->buf);
1178
0
  if (pipe_command(&cp_upd_index, files.buf, files.len, NULL, 0,
1179
0
       NULL, 0)) {
1180
0
    ret = -1;
1181
0
    goto done;
1182
0
  }
1183
1184
0
  if (write_index_as_tree(&info->u_tree, &istate, stash_index_path.buf, 0,
1185
0
        NULL)) {
1186
0
    ret = -1;
1187
0
    goto done;
1188
0
  }
1189
1190
0
  if (commit_tree(untracked_msg.buf, untracked_msg.len,
1191
0
      &info->u_tree, NULL, &info->u_commit, NULL, NULL)) {
1192
0
    ret = -1;
1193
0
    goto done;
1194
0
  }
1195
1196
0
done:
1197
0
  release_index(&istate);
1198
0
  strbuf_release(&untracked_msg);
1199
0
  remove_path(stash_index_path.buf);
1200
0
  return ret;
1201
0
}
1202
1203
static int stash_staged(struct stash_info *info, struct strbuf *out_patch,
1204
      int quiet)
1205
0
{
1206
0
  int ret = 0;
1207
0
  struct child_process cp_diff_tree = CHILD_PROCESS_INIT;
1208
0
  struct index_state istate = INDEX_STATE_INIT(the_repository);
1209
1210
0
  if (write_index_as_tree(&info->w_tree, &istate, the_repository->index_file,
1211
0
        0, NULL)) {
1212
0
    ret = -1;
1213
0
    goto done;
1214
0
  }
1215
1216
0
  cp_diff_tree.git_cmd = 1;
1217
0
  strvec_pushl(&cp_diff_tree.args, "diff-tree", "-p", "--binary",
1218
0
         "-U1", "HEAD", oid_to_hex(&info->w_tree), "--", NULL);
1219
0
  if (pipe_command(&cp_diff_tree, NULL, 0, out_patch, 0, NULL, 0)) {
1220
0
    ret = -1;
1221
0
    goto done;
1222
0
  }
1223
1224
0
  if (!out_patch->len) {
1225
0
    if (!quiet)
1226
0
      fprintf_ln(stderr, _("No staged changes"));
1227
0
    ret = 1;
1228
0
  }
1229
1230
0
done:
1231
0
  release_index(&istate);
1232
0
  return ret;
1233
0
}
1234
1235
static int stash_patch(struct stash_info *info, const struct pathspec *ps,
1236
           struct strbuf *out_patch, int quiet)
1237
0
{
1238
0
  int ret = 0;
1239
0
  struct child_process cp_read_tree = CHILD_PROCESS_INIT;
1240
0
  struct child_process cp_diff_tree = CHILD_PROCESS_INIT;
1241
0
  struct index_state istate = INDEX_STATE_INIT(the_repository);
1242
0
  char *old_index_env = NULL, *old_repo_index_file;
1243
1244
0
  remove_path(stash_index_path.buf);
1245
1246
0
  cp_read_tree.git_cmd = 1;
1247
0
  strvec_pushl(&cp_read_tree.args, "read-tree", "HEAD", NULL);
1248
0
  strvec_pushf(&cp_read_tree.env, "GIT_INDEX_FILE=%s",
1249
0
         stash_index_path.buf);
1250
0
  if (run_command(&cp_read_tree)) {
1251
0
    ret = -1;
1252
0
    goto done;
1253
0
  }
1254
1255
  /* Find out what the user wants. */
1256
0
  old_repo_index_file = the_repository->index_file;
1257
0
  the_repository->index_file = stash_index_path.buf;
1258
0
  old_index_env = xstrdup_or_null(getenv(INDEX_ENVIRONMENT));
1259
0
  setenv(INDEX_ENVIRONMENT, the_repository->index_file, 1);
1260
1261
0
  ret = !!run_add_p(the_repository, ADD_P_STASH, NULL, ps);
1262
1263
0
  the_repository->index_file = old_repo_index_file;
1264
0
  if (old_index_env && *old_index_env)
1265
0
    setenv(INDEX_ENVIRONMENT, old_index_env, 1);
1266
0
  else
1267
0
    unsetenv(INDEX_ENVIRONMENT);
1268
0
  FREE_AND_NULL(old_index_env);
1269
1270
  /* State of the working tree. */
1271
0
  if (write_index_as_tree(&info->w_tree, &istate, stash_index_path.buf, 0,
1272
0
        NULL)) {
1273
0
    ret = -1;
1274
0
    goto done;
1275
0
  }
1276
1277
0
  cp_diff_tree.git_cmd = 1;
1278
0
  strvec_pushl(&cp_diff_tree.args, "diff-tree", "-p", "-U1", "HEAD",
1279
0
         oid_to_hex(&info->w_tree), "--", NULL);
1280
0
  if (pipe_command(&cp_diff_tree, NULL, 0, out_patch, 0, NULL, 0)) {
1281
0
    ret = -1;
1282
0
    goto done;
1283
0
  }
1284
1285
0
  if (!out_patch->len) {
1286
0
    if (!quiet)
1287
0
      fprintf_ln(stderr, _("No changes selected"));
1288
0
    ret = 1;
1289
0
  }
1290
1291
0
done:
1292
0
  release_index(&istate);
1293
0
  remove_path(stash_index_path.buf);
1294
0
  return ret;
1295
0
}
1296
1297
static int stash_working_tree(struct stash_info *info, const struct pathspec *ps)
1298
0
{
1299
0
  int ret = 0;
1300
0
  struct rev_info rev;
1301
0
  struct child_process cp_upd_index = CHILD_PROCESS_INIT;
1302
0
  struct strbuf diff_output = STRBUF_INIT;
1303
0
  struct index_state istate = INDEX_STATE_INIT(the_repository);
1304
1305
0
  repo_init_revisions(the_repository, &rev, NULL);
1306
0
  copy_pathspec(&rev.prune_data, ps);
1307
1308
0
  set_alternate_index_output(stash_index_path.buf);
1309
0
  if (reset_tree(&info->i_tree, 0, 0)) {
1310
0
    ret = -1;
1311
0
    goto done;
1312
0
  }
1313
0
  set_alternate_index_output(NULL);
1314
1315
0
  rev.diffopt.output_format = DIFF_FORMAT_CALLBACK;
1316
0
  rev.diffopt.format_callback = add_diff_to_buf;
1317
0
  rev.diffopt.format_callback_data = &diff_output;
1318
1319
0
  if (repo_read_index_preload(the_repository, &rev.diffopt.pathspec, 0) < 0) {
1320
0
    ret = -1;
1321
0
    goto done;
1322
0
  }
1323
1324
0
  add_pending_object(&rev, parse_object(the_repository, &info->b_commit),
1325
0
         "");
1326
0
  run_diff_index(&rev, 0);
1327
1328
0
  cp_upd_index.git_cmd = 1;
1329
0
  strvec_pushl(&cp_upd_index.args, "update-index",
1330
0
         "--ignore-skip-worktree-entries",
1331
0
         "-z", "--add", "--remove", "--stdin", NULL);
1332
0
  strvec_pushf(&cp_upd_index.env, "GIT_INDEX_FILE=%s",
1333
0
         stash_index_path.buf);
1334
1335
0
  if (pipe_command(&cp_upd_index, diff_output.buf, diff_output.len,
1336
0
       NULL, 0, NULL, 0)) {
1337
0
    ret = -1;
1338
0
    goto done;
1339
0
  }
1340
1341
0
  if (write_index_as_tree(&info->w_tree, &istate, stash_index_path.buf, 0,
1342
0
        NULL)) {
1343
0
    ret = -1;
1344
0
    goto done;
1345
0
  }
1346
1347
0
done:
1348
0
  release_index(&istate);
1349
0
  release_revisions(&rev);
1350
0
  strbuf_release(&diff_output);
1351
0
  remove_path(stash_index_path.buf);
1352
0
  return ret;
1353
0
}
1354
1355
static int do_create_stash(const struct pathspec *ps, struct strbuf *stash_msg_buf,
1356
         int include_untracked, int patch_mode, int only_staged,
1357
         struct stash_info *info, struct strbuf *patch,
1358
         int quiet)
1359
0
{
1360
0
  int ret = 0;
1361
0
  int flags = 0;
1362
0
  int untracked_commit_option = 0;
1363
0
  const char *head_short_sha1 = NULL;
1364
0
  const char *branch_ref = NULL;
1365
0
  const char *branch_name = "(no branch)";
1366
0
  struct commit *head_commit = NULL;
1367
0
  struct commit_list *parents = NULL;
1368
0
  struct strbuf msg = STRBUF_INIT;
1369
0
  struct strbuf commit_tree_label = STRBUF_INIT;
1370
0
  struct strbuf untracked_files = STRBUF_INIT;
1371
1372
0
  prepare_fallback_ident("git stash", "git@stash");
1373
1374
0
  repo_read_index_preload(the_repository, NULL, 0);
1375
0
  if (repo_refresh_and_write_index(the_repository, REFRESH_QUIET, 0, 0,
1376
0
           NULL, NULL, NULL) < 0) {
1377
0
    ret = error(_("could not write index"));
1378
0
    goto done;
1379
0
  }
1380
1381
0
  if (repo_get_oid(the_repository, "HEAD", &info->b_commit)) {
1382
0
    if (!quiet)
1383
0
      fprintf_ln(stderr, _("You do not have "
1384
0
               "the initial commit yet"));
1385
0
    ret = -1;
1386
0
    goto done;
1387
0
  } else {
1388
0
    head_commit = lookup_commit(the_repository, &info->b_commit);
1389
0
  }
1390
1391
0
  if (!check_changes(ps, include_untracked, &untracked_files)) {
1392
0
    ret = 1;
1393
0
    goto done;
1394
0
  }
1395
1396
0
  branch_ref = refs_resolve_ref_unsafe(get_main_ref_store(the_repository),
1397
0
               "HEAD", 0, NULL, &flags);
1398
0
  if (flags & REF_ISSYMREF)
1399
0
    skip_prefix(branch_ref, "refs/heads/", &branch_name);
1400
0
  head_short_sha1 = repo_find_unique_abbrev(the_repository,
1401
0
              &head_commit->object.oid,
1402
0
              DEFAULT_ABBREV);
1403
0
  strbuf_addf(&msg, "%s: %s ", branch_name, head_short_sha1);
1404
0
  pp_commit_easy(CMIT_FMT_ONELINE, head_commit, &msg);
1405
1406
0
  strbuf_addf(&commit_tree_label, "index on %s\n", msg.buf);
1407
0
  commit_list_insert(head_commit, &parents);
1408
0
  if (write_index_as_tree(&info->i_tree, the_repository->index, get_index_file(), 0,
1409
0
        NULL) ||
1410
0
      commit_tree(commit_tree_label.buf, commit_tree_label.len,
1411
0
      &info->i_tree, parents, &info->i_commit, NULL, NULL)) {
1412
0
    if (!quiet)
1413
0
      fprintf_ln(stderr, _("Cannot save the current "
1414
0
               "index state"));
1415
0
    ret = -1;
1416
0
    goto done;
1417
0
  }
1418
1419
0
  free_commit_list(parents);
1420
0
  parents = NULL;
1421
1422
0
  if (include_untracked) {
1423
0
    if (save_untracked_files(info, &msg, untracked_files)) {
1424
0
      if (!quiet)
1425
0
        fprintf_ln(stderr, _("Cannot save "
1426
0
                 "the untracked files"));
1427
0
      ret = -1;
1428
0
      goto done;
1429
0
    }
1430
0
    untracked_commit_option = 1;
1431
0
  }
1432
0
  if (patch_mode) {
1433
0
    ret = stash_patch(info, ps, patch, quiet);
1434
0
    if (ret < 0) {
1435
0
      if (!quiet)
1436
0
        fprintf_ln(stderr, _("Cannot save the current "
1437
0
                 "worktree state"));
1438
0
      goto done;
1439
0
    } else if (ret > 0) {
1440
0
      goto done;
1441
0
    }
1442
0
  } else if (only_staged) {
1443
0
    ret = stash_staged(info, patch, quiet);
1444
0
    if (ret < 0) {
1445
0
      if (!quiet)
1446
0
        fprintf_ln(stderr, _("Cannot save the current "
1447
0
                 "staged state"));
1448
0
      goto done;
1449
0
    } else if (ret > 0) {
1450
0
      goto done;
1451
0
    }
1452
0
  } else {
1453
0
    if (stash_working_tree(info, ps)) {
1454
0
      if (!quiet)
1455
0
        fprintf_ln(stderr, _("Cannot save the current "
1456
0
                 "worktree state"));
1457
0
      ret = -1;
1458
0
      goto done;
1459
0
    }
1460
0
  }
1461
1462
0
  if (!stash_msg_buf->len)
1463
0
    strbuf_addf(stash_msg_buf, "WIP on %s", msg.buf);
1464
0
  else
1465
0
    strbuf_insertf(stash_msg_buf, 0, "On %s: ", branch_name);
1466
1467
0
  if (untracked_commit_option)
1468
0
    commit_list_insert(lookup_commit(the_repository,
1469
0
             &info->u_commit),
1470
0
           &parents);
1471
0
  commit_list_insert(lookup_commit(the_repository, &info->i_commit),
1472
0
         &parents);
1473
0
  commit_list_insert(head_commit, &parents);
1474
1475
0
  if (commit_tree(stash_msg_buf->buf, stash_msg_buf->len, &info->w_tree,
1476
0
      parents, &info->w_commit, NULL, NULL)) {
1477
0
    if (!quiet)
1478
0
      fprintf_ln(stderr, _("Cannot record "
1479
0
               "working tree state"));
1480
0
    ret = -1;
1481
0
    goto done;
1482
0
  }
1483
1484
0
done:
1485
0
  strbuf_release(&commit_tree_label);
1486
0
  strbuf_release(&msg);
1487
0
  strbuf_release(&untracked_files);
1488
0
  free_commit_list(parents);
1489
0
  return ret;
1490
0
}
1491
1492
static int create_stash(int argc, const char **argv, const char *prefix UNUSED)
1493
0
{
1494
0
  int ret;
1495
0
  struct strbuf stash_msg_buf = STRBUF_INIT;
1496
0
  struct stash_info info = STASH_INFO_INIT;
1497
0
  struct pathspec ps;
1498
1499
  /* Starting with argv[1], since argv[0] is "create" */
1500
0
  strbuf_join_argv(&stash_msg_buf, argc - 1, ++argv, ' ');
1501
1502
0
  memset(&ps, 0, sizeof(ps));
1503
0
  if (!check_changes_tracked_files(&ps))
1504
0
    return 0;
1505
1506
0
  ret = do_create_stash(&ps, &stash_msg_buf, 0, 0, 0, &info,
1507
0
            NULL, 0);
1508
0
  if (!ret)
1509
0
    printf_ln("%s", oid_to_hex(&info.w_commit));
1510
1511
0
  free_stash_info(&info);
1512
0
  strbuf_release(&stash_msg_buf);
1513
0
  return ret;
1514
0
}
1515
1516
static int do_push_stash(const struct pathspec *ps, const char *stash_msg, int quiet,
1517
       int keep_index, int patch_mode, int include_untracked, int only_staged)
1518
0
{
1519
0
  int ret = 0;
1520
0
  struct stash_info info = STASH_INFO_INIT;
1521
0
  struct strbuf patch = STRBUF_INIT;
1522
0
  struct strbuf stash_msg_buf = STRBUF_INIT;
1523
0
  struct strbuf untracked_files = STRBUF_INIT;
1524
0
  struct strbuf out = STRBUF_INIT;
1525
1526
0
  if (patch_mode && keep_index == -1)
1527
0
    keep_index = 1;
1528
1529
0
  if (patch_mode && include_untracked) {
1530
0
    fprintf_ln(stderr, _("Can't use --patch and --include-untracked"
1531
0
             " or --all at the same time"));
1532
0
    ret = -1;
1533
0
    goto done;
1534
0
  }
1535
1536
  /* --patch overrides --staged */
1537
0
  if (patch_mode)
1538
0
    only_staged = 0;
1539
1540
0
  if (only_staged && include_untracked) {
1541
0
    fprintf_ln(stderr, _("Can't use --staged and --include-untracked"
1542
0
             " or --all at the same time"));
1543
0
    ret = -1;
1544
0
    goto done;
1545
0
  }
1546
1547
0
  repo_read_index_preload(the_repository, NULL, 0);
1548
0
  if (!include_untracked && ps->nr) {
1549
0
    int i;
1550
0
    char *ps_matched = xcalloc(ps->nr, 1);
1551
1552
    /* TODO: audit for interaction with sparse-index. */
1553
0
    ensure_full_index(the_repository->index);
1554
0
    for (i = 0; i < the_repository->index->cache_nr; i++)
1555
0
      ce_path_match(the_repository->index, the_repository->index->cache[i], ps,
1556
0
              ps_matched);
1557
1558
0
    if (report_path_error(ps_matched, ps)) {
1559
0
      fprintf_ln(stderr, _("Did you forget to 'git add'?"));
1560
0
      ret = -1;
1561
0
      free(ps_matched);
1562
0
      goto done;
1563
0
    }
1564
0
    free(ps_matched);
1565
0
  }
1566
1567
0
  if (repo_refresh_and_write_index(the_repository, REFRESH_QUIET, 0, 0,
1568
0
           NULL, NULL, NULL)) {
1569
0
    ret = error(_("could not write index"));
1570
0
    goto done;
1571
0
  }
1572
1573
0
  if (!check_changes(ps, include_untracked, &untracked_files)) {
1574
0
    if (!quiet)
1575
0
      printf_ln(_("No local changes to save"));
1576
0
    goto done;
1577
0
  }
1578
1579
0
  if (!refs_reflog_exists(get_main_ref_store(the_repository), ref_stash) && do_clear_stash()) {
1580
0
    ret = -1;
1581
0
    if (!quiet)
1582
0
      fprintf_ln(stderr, _("Cannot initialize stash"));
1583
0
    goto done;
1584
0
  }
1585
1586
0
  if (stash_msg)
1587
0
    strbuf_addstr(&stash_msg_buf, stash_msg);
1588
0
  if (do_create_stash(ps, &stash_msg_buf, include_untracked, patch_mode, only_staged,
1589
0
          &info, &patch, quiet)) {
1590
0
    ret = -1;
1591
0
    goto done;
1592
0
  }
1593
1594
0
  if (do_store_stash(&info.w_commit, stash_msg_buf.buf, 1)) {
1595
0
    ret = -1;
1596
0
    if (!quiet)
1597
0
      fprintf_ln(stderr, _("Cannot save the current status"));
1598
0
    goto done;
1599
0
  }
1600
1601
0
  if (!quiet)
1602
0
    printf_ln(_("Saved working directory and index state %s"),
1603
0
        stash_msg_buf.buf);
1604
1605
0
  if (!(patch_mode || only_staged)) {
1606
0
    if (include_untracked && !ps->nr) {
1607
0
      struct child_process cp = CHILD_PROCESS_INIT;
1608
1609
0
      cp.git_cmd = 1;
1610
0
      if (startup_info->original_cwd) {
1611
0
        cp.dir = startup_info->original_cwd;
1612
0
        strvec_pushf(&cp.env, "%s=%s",
1613
0
               GIT_WORK_TREE_ENVIRONMENT,
1614
0
               the_repository->worktree);
1615
0
      }
1616
0
      strvec_pushl(&cp.args, "clean", "--force",
1617
0
             "--quiet", "-d", ":/", NULL);
1618
0
      if (include_untracked == INCLUDE_ALL_FILES)
1619
0
        strvec_push(&cp.args, "-x");
1620
0
      if (run_command(&cp)) {
1621
0
        ret = -1;
1622
0
        goto done;
1623
0
      }
1624
0
    }
1625
0
    discard_index(the_repository->index);
1626
0
    if (ps->nr) {
1627
0
      struct child_process cp_add = CHILD_PROCESS_INIT;
1628
0
      struct child_process cp_diff = CHILD_PROCESS_INIT;
1629
0
      struct child_process cp_apply = CHILD_PROCESS_INIT;
1630
1631
0
      cp_add.git_cmd = 1;
1632
0
      strvec_push(&cp_add.args, "add");
1633
0
      if (!include_untracked)
1634
0
        strvec_push(&cp_add.args, "-u");
1635
0
      if (include_untracked == INCLUDE_ALL_FILES)
1636
0
        strvec_push(&cp_add.args, "--force");
1637
0
      strvec_push(&cp_add.args, "--");
1638
0
      add_pathspecs(&cp_add.args, ps);
1639
0
      if (run_command(&cp_add)) {
1640
0
        ret = -1;
1641
0
        goto done;
1642
0
      }
1643
1644
0
      cp_diff.git_cmd = 1;
1645
0
      strvec_pushl(&cp_diff.args, "diff-index", "-p",
1646
0
             "--cached", "--binary", "HEAD", "--",
1647
0
             NULL);
1648
0
      add_pathspecs(&cp_diff.args, ps);
1649
0
      if (pipe_command(&cp_diff, NULL, 0, &out, 0, NULL, 0)) {
1650
0
        ret = -1;
1651
0
        goto done;
1652
0
      }
1653
1654
0
      cp_apply.git_cmd = 1;
1655
0
      strvec_pushl(&cp_apply.args, "apply", "--index",
1656
0
             "-R", NULL);
1657
0
      if (pipe_command(&cp_apply, out.buf, out.len, NULL, 0,
1658
0
           NULL, 0)) {
1659
0
        ret = -1;
1660
0
        goto done;
1661
0
      }
1662
0
    } else {
1663
0
      struct child_process cp = CHILD_PROCESS_INIT;
1664
0
      cp.git_cmd = 1;
1665
      /* BUG: this nukes untracked files in the way */
1666
0
      strvec_pushl(&cp.args, "reset", "--hard", "-q",
1667
0
             "--no-recurse-submodules", NULL);
1668
0
      if (run_command(&cp)) {
1669
0
        ret = -1;
1670
0
        goto done;
1671
0
      }
1672
0
    }
1673
1674
    /*
1675
     * When keeping staged entries, we need to reset the working
1676
     * directory to match the state of our index. This can be
1677
     * skipped when the index is the empty tree, because there is
1678
     * nothing to reset in that case:
1679
     *
1680
     *   - When the index has any file, regardless of whether
1681
     *     staged or not, the tree cannot be empty by definition
1682
     *     and thus we enter the condition.
1683
     *
1684
     *   - When the index has no files, the only thing we need to
1685
     *     care about is untracked files when `--include-untracked`
1686
     *     is given. But as we already execute git-clean(1) further
1687
     *     up to delete such untracked files we don't have to do
1688
     *     anything here, either.
1689
     *
1690
     * We thus skip calling git-checkout(1) in this case, also
1691
     * because running it on an empty tree will cause it to fail
1692
     * due to the pathspec not matching anything.
1693
     */
1694
0
    if (keep_index == 1 && !is_null_oid(&info.i_tree) &&
1695
0
        !is_empty_tree_oid(&info.i_tree, the_repository->hash_algo)) {
1696
0
      struct child_process cp = CHILD_PROCESS_INIT;
1697
1698
0
      cp.git_cmd = 1;
1699
0
      strvec_pushl(&cp.args, "checkout", "--no-overlay",
1700
0
             oid_to_hex(&info.i_tree), "--", NULL);
1701
0
      if (!ps->nr)
1702
0
        strvec_push(&cp.args, ":/");
1703
0
      else
1704
0
        add_pathspecs(&cp.args, ps);
1705
0
      if (run_command(&cp)) {
1706
0
        ret = -1;
1707
0
        goto done;
1708
0
      }
1709
0
    }
1710
0
    goto done;
1711
0
  } else {
1712
0
    struct child_process cp = CHILD_PROCESS_INIT;
1713
1714
0
    cp.git_cmd = 1;
1715
0
    strvec_pushl(&cp.args, "apply", "-R", NULL);
1716
1717
0
    if (pipe_command(&cp, patch.buf, patch.len, NULL, 0, NULL, 0)) {
1718
0
      if (!quiet)
1719
0
        fprintf_ln(stderr, _("Cannot remove "
1720
0
                 "worktree changes"));
1721
0
      ret = -1;
1722
0
      goto done;
1723
0
    }
1724
1725
0
    if (keep_index < 1) {
1726
0
      struct child_process cp = CHILD_PROCESS_INIT;
1727
1728
0
      cp.git_cmd = 1;
1729
0
      strvec_pushl(&cp.args, "reset", "-q", "--refresh", "--",
1730
0
             NULL);
1731
0
      add_pathspecs(&cp.args, ps);
1732
0
      if (run_command(&cp)) {
1733
0
        ret = -1;
1734
0
        goto done;
1735
0
      }
1736
0
    }
1737
0
    goto done;
1738
0
  }
1739
1740
0
done:
1741
0
  strbuf_release(&patch);
1742
0
  strbuf_release(&out);
1743
0
  free_stash_info(&info);
1744
0
  strbuf_release(&stash_msg_buf);
1745
0
  strbuf_release(&untracked_files);
1746
0
  return ret;
1747
0
}
1748
1749
static int push_stash(int argc, const char **argv, const char *prefix,
1750
          int push_assumed)
1751
0
{
1752
0
  int force_assume = 0;
1753
0
  int keep_index = -1;
1754
0
  int only_staged = 0;
1755
0
  int patch_mode = 0;
1756
0
  int include_untracked = 0;
1757
0
  int quiet = 0;
1758
0
  int pathspec_file_nul = 0;
1759
0
  const char *stash_msg = NULL;
1760
0
  const char *pathspec_from_file = NULL;
1761
0
  struct pathspec ps;
1762
0
  struct option options[] = {
1763
0
    OPT_BOOL('k', "keep-index", &keep_index,
1764
0
       N_("keep index")),
1765
0
    OPT_BOOL('S', "staged", &only_staged,
1766
0
       N_("stash staged changes only")),
1767
0
    OPT_BOOL('p', "patch", &patch_mode,
1768
0
       N_("stash in patch mode")),
1769
0
    OPT__QUIET(&quiet, N_("quiet mode")),
1770
0
    OPT_BOOL('u', "include-untracked", &include_untracked,
1771
0
       N_("include untracked files in stash")),
1772
0
    OPT_SET_INT('a', "all", &include_untracked,
1773
0
          N_("include ignore files"), 2),
1774
0
    OPT_STRING('m', "message", &stash_msg, N_("message"),
1775
0
         N_("stash message")),
1776
0
    OPT_PATHSPEC_FROM_FILE(&pathspec_from_file),
1777
0
    OPT_PATHSPEC_FILE_NUL(&pathspec_file_nul),
1778
0
    OPT_END()
1779
0
  };
1780
0
  int ret;
1781
1782
0
  if (argc) {
1783
0
    force_assume = !strcmp(argv[0], "-p");
1784
0
    argc = parse_options(argc, argv, prefix, options,
1785
0
             push_assumed ? git_stash_usage :
1786
0
             git_stash_push_usage,
1787
0
             PARSE_OPT_KEEP_DASHDASH);
1788
0
  }
1789
1790
0
  if (argc) {
1791
0
    if (!strcmp(argv[0], "--")) {
1792
0
      argc--;
1793
0
      argv++;
1794
0
    } else if (push_assumed && !force_assume) {
1795
0
      die("subcommand wasn't specified; 'push' can't be assumed due to unexpected token '%s'",
1796
0
          argv[0]);
1797
0
    }
1798
0
  }
1799
1800
0
  parse_pathspec(&ps, 0, PATHSPEC_PREFER_FULL | PATHSPEC_PREFIX_ORIGIN,
1801
0
           prefix, argv);
1802
1803
0
  if (pathspec_from_file) {
1804
0
    if (patch_mode)
1805
0
      die(_("options '%s' and '%s' cannot be used together"), "--pathspec-from-file", "--patch");
1806
1807
0
    if (only_staged)
1808
0
      die(_("options '%s' and '%s' cannot be used together"), "--pathspec-from-file", "--staged");
1809
1810
0
    if (ps.nr)
1811
0
      die(_("'%s' and pathspec arguments cannot be used together"), "--pathspec-from-file");
1812
1813
0
    parse_pathspec_file(&ps, 0,
1814
0
            PATHSPEC_PREFER_FULL | PATHSPEC_PREFIX_ORIGIN,
1815
0
            prefix, pathspec_from_file, pathspec_file_nul);
1816
0
  } else if (pathspec_file_nul) {
1817
0
    die(_("the option '%s' requires '%s'"), "--pathspec-file-nul", "--pathspec-from-file");
1818
0
  }
1819
1820
0
  ret = do_push_stash(&ps, stash_msg, quiet, keep_index, patch_mode,
1821
0
          include_untracked, only_staged);
1822
0
  clear_pathspec(&ps);
1823
0
  return ret;
1824
0
}
1825
1826
static int push_stash_unassumed(int argc, const char **argv, const char *prefix)
1827
0
{
1828
0
  return push_stash(argc, argv, prefix, 0);
1829
0
}
1830
1831
static int save_stash(int argc, const char **argv, const char *prefix)
1832
0
{
1833
0
  int keep_index = -1;
1834
0
  int only_staged = 0;
1835
0
  int patch_mode = 0;
1836
0
  int include_untracked = 0;
1837
0
  int quiet = 0;
1838
0
  int ret = 0;
1839
0
  const char *stash_msg = NULL;
1840
0
  struct pathspec ps;
1841
0
  struct strbuf stash_msg_buf = STRBUF_INIT;
1842
0
  struct option options[] = {
1843
0
    OPT_BOOL('k', "keep-index", &keep_index,
1844
0
       N_("keep index")),
1845
0
    OPT_BOOL('S', "staged", &only_staged,
1846
0
       N_("stash staged changes only")),
1847
0
    OPT_BOOL('p', "patch", &patch_mode,
1848
0
       N_("stash in patch mode")),
1849
0
    OPT__QUIET(&quiet, N_("quiet mode")),
1850
0
    OPT_BOOL('u', "include-untracked", &include_untracked,
1851
0
       N_("include untracked files in stash")),
1852
0
    OPT_SET_INT('a', "all", &include_untracked,
1853
0
          N_("include ignore files"), 2),
1854
0
    OPT_STRING('m', "message", &stash_msg, "message",
1855
0
         N_("stash message")),
1856
0
    OPT_END()
1857
0
  };
1858
1859
0
  argc = parse_options(argc, argv, prefix, options,
1860
0
           git_stash_save_usage,
1861
0
           PARSE_OPT_KEEP_DASHDASH);
1862
1863
0
  if (argc)
1864
0
    stash_msg = strbuf_join_argv(&stash_msg_buf, argc, argv, ' ');
1865
1866
0
  memset(&ps, 0, sizeof(ps));
1867
0
  ret = do_push_stash(&ps, stash_msg, quiet, keep_index,
1868
0
          patch_mode, include_untracked, only_staged);
1869
1870
0
  strbuf_release(&stash_msg_buf);
1871
0
  return ret;
1872
0
}
1873
1874
int cmd_stash(int argc, const char **argv, const char *prefix)
1875
0
{
1876
0
  pid_t pid = getpid();
1877
0
  const char *index_file;
1878
0
  struct strvec args = STRVEC_INIT;
1879
0
  parse_opt_subcommand_fn *fn = NULL;
1880
0
  struct option options[] = {
1881
0
    OPT_SUBCOMMAND("apply", &fn, apply_stash),
1882
0
    OPT_SUBCOMMAND("clear", &fn, clear_stash),
1883
0
    OPT_SUBCOMMAND("drop", &fn, drop_stash),
1884
0
    OPT_SUBCOMMAND("pop", &fn, pop_stash),
1885
0
    OPT_SUBCOMMAND("branch", &fn, branch_stash),
1886
0
    OPT_SUBCOMMAND("list", &fn, list_stash),
1887
0
    OPT_SUBCOMMAND("show", &fn, show_stash),
1888
0
    OPT_SUBCOMMAND("store", &fn, store_stash),
1889
0
    OPT_SUBCOMMAND("create", &fn, create_stash),
1890
0
    OPT_SUBCOMMAND("push", &fn, push_stash_unassumed),
1891
0
    OPT_SUBCOMMAND_F("save", &fn, save_stash, PARSE_OPT_NOCOMPLETE),
1892
0
    OPT_END()
1893
0
  };
1894
0
  const char **args_copy;
1895
0
  int ret;
1896
1897
0
  git_config(git_stash_config, NULL);
1898
1899
0
  argc = parse_options(argc, argv, prefix, options, git_stash_usage,
1900
0
           PARSE_OPT_SUBCOMMAND_OPTIONAL |
1901
0
           PARSE_OPT_KEEP_UNKNOWN_OPT |
1902
0
           PARSE_OPT_KEEP_DASHDASH);
1903
1904
0
  prepare_repo_settings(the_repository);
1905
0
  the_repository->settings.command_requires_full_index = 0;
1906
1907
0
  index_file = get_index_file();
1908
0
  strbuf_addf(&stash_index_path, "%s.stash.%" PRIuMAX, index_file,
1909
0
        (uintmax_t)pid);
1910
1911
0
  if (fn)
1912
0
    return !!fn(argc, argv, prefix);
1913
0
  else if (!argc)
1914
0
    return !!push_stash_unassumed(0, NULL, prefix);
1915
1916
  /* Assume 'stash push' */
1917
0
  strvec_push(&args, "push");
1918
0
  strvec_pushv(&args, argv);
1919
1920
  /*
1921
   * `push_stash()` ends up modifying the array, which causes memory
1922
   * leaks if we didn't copy the array here.
1923
   */
1924
0
  DUP_ARRAY(args_copy, args.v, args.nr);
1925
1926
0
  ret = !!push_stash(args.nr, args_copy, prefix, 1);
1927
1928
0
  strvec_clear(&args);
1929
0
  free(args_copy);
1930
0
  return ret;
1931
0
}