3 #include "parse-options.h"
6 #include "cache-tree.h"
7 #include "unpack-trees.h"
8 #include "merge-recursive.h"
9 #include "argv-array.h"
10 #include "run-command.h"
14 static const char * const git_stash_helper_usage[] = {
15 N_("git stash--helper apply [--index] [-q|--quiet] [<stash>]"),
19 static const char * const git_stash_helper_apply_usage[] = {
20 N_("git stash--helper apply [--index] [-q|--quiet] [<stash>]"),
24 static const char *ref_stash = "refs/stash";
25 static struct strbuf stash_index_path = STRBUF_INIT;
28 * w_commit is set to the commit containing the working tree
29 * b_commit is set to the base commit
30 * i_commit is set to the commit containing the index tree
31 * u_commit is set to the commit containing the untracked files tree
32 * w_tree is set to the working tree
33 * b_tree is set to the base tree
34 * i_tree is set to the index tree
35 * u_tree is set to the untracked files tree
38 struct object_id w_commit;
39 struct object_id b_commit;
40 struct object_id i_commit;
41 struct object_id u_commit;
42 struct object_id w_tree;
43 struct object_id b_tree;
44 struct object_id i_tree;
45 struct object_id u_tree;
46 struct strbuf revision;
51 static void free_stash_info(struct stash_info *info)
53 strbuf_release(&info->revision);
56 static void assert_stash_like(struct stash_info *info, const char *revision)
58 if (get_oidf(&info->b_commit, "%s^1", revision) ||
59 get_oidf(&info->w_tree, "%s:", revision) ||
60 get_oidf(&info->b_tree, "%s^1:", revision) ||
61 get_oidf(&info->i_tree, "%s^2:", revision))
62 die(_("'%s' is not a stash-like commit"), revision);
65 static int get_stash_info(struct stash_info *info, int argc, const char **argv)
71 const char *commit = NULL;
72 struct object_id dummy;
73 struct strbuf symbolic = STRBUF_INIT;
77 struct strbuf refs_msg = STRBUF_INIT;
79 for (i = 0; i < argc; i++)
80 strbuf_addf(&refs_msg, " '%s'", argv[i]);
82 fprintf_ln(stderr, _("Too many revisions specified:%s"),
84 strbuf_release(&refs_msg);
92 strbuf_init(&info->revision, 0);
94 if (!ref_exists(ref_stash)) {
95 free_stash_info(info);
96 fprintf_ln(stderr, _("No stash entries found."));
100 strbuf_addf(&info->revision, "%s@{0}", ref_stash);
101 } else if (strspn(commit, "0123456789") == strlen(commit)) {
102 strbuf_addf(&info->revision, "%s@{%s}", ref_stash, commit);
104 strbuf_addstr(&info->revision, commit);
107 revision = info->revision.buf;
109 if (get_oid(revision, &info->w_commit)) {
110 error(_("%s is not a valid reference"), revision);
111 free_stash_info(info);
115 assert_stash_like(info, revision);
117 info->has_u = !get_oidf(&info->u_tree, "%s^3:", revision);
119 end_of_rev = strchrnul(revision, '@');
120 strbuf_add(&symbolic, revision, end_of_rev - revision);
122 ret = dwim_ref(symbolic.buf, symbolic.len, &dummy, &expanded_ref);
123 strbuf_release(&symbolic);
125 case 0: /* Not found, but valid ref */
126 info->is_stash_ref = 0;
129 info->is_stash_ref = !strcmp(expanded_ref, ref_stash);
131 default: /* Invalid or ambiguous */
132 free_stash_info(info);
136 return !(ret == 0 || ret == 1);
139 static int reset_tree(struct object_id *i_tree, int update, int reset)
142 struct unpack_trees_options opts;
143 struct tree_desc t[MAX_UNPACK_TREES];
145 struct lock_file lock_file = LOCK_INIT;
147 read_cache_preload(NULL);
148 if (refresh_cache(REFRESH_QUIET))
151 hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);
153 memset(&opts, 0, sizeof(opts));
155 tree = parse_tree_indirect(i_tree);
156 if (parse_tree(tree))
159 init_tree_desc(t, tree->buffer, tree->size);
162 opts.src_index = &the_index;
163 opts.dst_index = &the_index;
166 opts.update = update;
167 opts.fn = oneway_merge;
169 if (unpack_trees(nr_trees, t, &opts))
172 if (write_locked_index(&the_index, &lock_file, COMMIT_LOCK))
173 return error(_("unable to write new index file"));
178 static int diff_tree_binary(struct strbuf *out, struct object_id *w_commit)
180 struct child_process cp = CHILD_PROCESS_INIT;
181 const char *w_commit_hex = oid_to_hex(w_commit);
184 * Diff-tree would not be very hard to replace with a native function,
185 * however it should be done together with apply_cached.
188 argv_array_pushl(&cp.args, "diff-tree", "--binary", NULL);
189 argv_array_pushf(&cp.args, "%s^2^..%s^2", w_commit_hex, w_commit_hex);
191 return pipe_command(&cp, NULL, 0, out, 0, NULL, 0);
194 static int apply_cached(struct strbuf *out)
196 struct child_process cp = CHILD_PROCESS_INIT;
199 * Apply currently only reads either from stdin or a file, thus
200 * apply_all_patches would have to be updated to optionally take a
204 argv_array_pushl(&cp.args, "apply", "--cached", NULL);
205 return pipe_command(&cp, out->buf, out->len, NULL, 0, NULL, 0);
208 static int reset_head(void)
210 struct child_process cp = CHILD_PROCESS_INIT;
213 * Reset is overall quite simple, however there is no current public
217 argv_array_push(&cp.args, "reset");
219 return run_command(&cp);
222 static int get_newly_staged(struct strbuf *out, struct object_id *c_tree)
224 struct child_process cp = CHILD_PROCESS_INIT;
225 const char *c_tree_hex = oid_to_hex(c_tree);
228 * diff-index is very similar to diff-tree above, and should be
229 * converted together with update_index.
232 argv_array_pushl(&cp.args, "diff-index", "--cached", "--name-only",
233 "--diff-filter=A", NULL);
234 argv_array_push(&cp.args, c_tree_hex);
235 return pipe_command(&cp, NULL, 0, out, 0, NULL, 0);
238 static int update_index(struct strbuf *out)
240 struct child_process cp = CHILD_PROCESS_INIT;
243 * Update-index is very complicated and may need to have a public
244 * function exposed in order to remove this forking.
247 argv_array_pushl(&cp.args, "update-index", "--add", "--stdin", NULL);
248 return pipe_command(&cp, out->buf, out->len, NULL, 0, NULL, 0);
251 static int restore_untracked(struct object_id *u_tree)
254 struct child_process cp = CHILD_PROCESS_INIT;
257 * We need to run restore files from a given index, but without
258 * affecting the current index, so we use GIT_INDEX_FILE with
259 * run_command to fork processes that will not interfere.
262 argv_array_push(&cp.args, "read-tree");
263 argv_array_push(&cp.args, oid_to_hex(u_tree));
264 argv_array_pushf(&cp.env_array, "GIT_INDEX_FILE=%s",
265 stash_index_path.buf);
266 if (run_command(&cp)) {
267 remove_path(stash_index_path.buf);
271 child_process_init(&cp);
273 argv_array_pushl(&cp.args, "checkout-index", "--all", NULL);
274 argv_array_pushf(&cp.env_array, "GIT_INDEX_FILE=%s",
275 stash_index_path.buf);
277 res = run_command(&cp);
278 remove_path(stash_index_path.buf);
282 static int do_apply_stash(const char *prefix, struct stash_info *info,
283 int index, int quiet)
286 int has_index = index;
287 struct merge_options o;
288 struct object_id c_tree;
289 struct object_id index_tree;
290 struct commit *result;
291 const struct object_id *bases[1];
293 read_cache_preload(NULL);
294 if (refresh_cache(REFRESH_QUIET))
297 if (write_cache_as_tree(&c_tree, 0, NULL))
298 return error(_("cannot apply a stash in the middle of a merge"));
301 if (oideq(&info->b_tree, &info->i_tree) ||
302 oideq(&c_tree, &info->i_tree)) {
305 struct strbuf out = STRBUF_INIT;
307 if (diff_tree_binary(&out, &info->w_commit)) {
308 strbuf_release(&out);
309 return error(_("could not generate diff %s^!."),
310 oid_to_hex(&info->w_commit));
313 ret = apply_cached(&out);
314 strbuf_release(&out);
316 return error(_("conflicts in index."
317 "Try without --index."));
321 if (write_cache_as_tree(&index_tree, 0, NULL))
322 return error(_("could not save index tree"));
328 if (info->has_u && restore_untracked(&info->u_tree))
329 return error(_("could not restore untracked files from stash"));
331 init_merge_options(&o);
333 o.branch1 = "Updated upstream";
334 o.branch2 = "Stashed changes";
336 if (oideq(&info->b_tree, &c_tree))
337 o.branch1 = "Version stash was based on";
342 if (o.verbosity >= 3)
343 printf_ln(_("Merging %s with %s"), o.branch1, o.branch2);
345 bases[0] = &info->b_tree;
347 ret = merge_recursive_generic(&o, &c_tree, &info->w_tree, 1, bases,
353 fprintf_ln(stderr, _("Index was not unstashed."));
359 if (reset_tree(&index_tree, 0, 0))
362 struct strbuf out = STRBUF_INIT;
364 if (get_newly_staged(&out, &c_tree)) {
365 strbuf_release(&out);
369 if (reset_tree(&c_tree, 0, 1)) {
370 strbuf_release(&out);
374 ret = update_index(&out);
375 strbuf_release(&out);
383 if (refresh_cache(REFRESH_QUIET))
384 warning("could not refresh index");
386 struct child_process cp = CHILD_PROCESS_INIT;
389 * Status is quite simple and could be replaced with calls to
390 * wt_status in the future, but it adds complexities which may
391 * require more tests.
395 argv_array_push(&cp.args, "status");
402 static int apply_stash(int argc, const char **argv, const char *prefix)
407 struct stash_info info;
408 struct option options[] = {
409 OPT__QUIET(&quiet, N_("be quiet, only report errors")),
410 OPT_BOOL(0, "index", &index,
411 N_("attempt to recreate the index")),
415 argc = parse_options(argc, argv, prefix, options,
416 git_stash_helper_apply_usage, 0);
418 if (get_stash_info(&info, argc, argv))
421 ret = do_apply_stash(prefix, &info, index, quiet);
422 free_stash_info(&info);
426 int cmd_stash__helper(int argc, const char **argv, const char *prefix)
428 pid_t pid = getpid();
429 const char *index_file;
431 struct option options[] = {
435 git_config(git_default_config, NULL);
437 argc = parse_options(argc, argv, prefix, options, git_stash_helper_usage,
438 PARSE_OPT_KEEP_UNKNOWN | PARSE_OPT_KEEP_DASHDASH);
440 index_file = get_index_file();
441 strbuf_addf(&stash_index_path, "%s.stash.%" PRIuMAX, index_file,
445 usage_with_options(git_stash_helper_usage, options);
446 if (!strcmp(argv[0], "apply"))
447 return !!apply_stash(argc, argv, prefix);
449 usage_msg_opt(xstrfmt(_("unknown subcommand: %s"), argv[0]),
450 git_stash_helper_usage, options);