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