static int stash_working_tree(struct stash_info *info, struct pathspec ps) { int ret = 0; struct rev_info rev; struct child_process cp_upd_index = CHILD_PROCESS_INIT; struct strbuf diff_output = STRBUF_INIT; struct index_state istate = { NULL }; init_revisions(&rev, NULL); set_alternate_index_output(stash_index_path.buf); if (reset_tree(&info->i_tree, 0, 0)) { ret = -1; goto done; } set_alternate_index_output(NULL); rev.prune_data = ps; rev.diffopt.output_format = DIFF_FORMAT_CALLBACK; rev.diffopt.format_callback = add_diff_to_buf; rev.diffopt.format_callback_data = &diff_output; if (read_cache_preload(&rev.diffopt.pathspec) < 0) { ret = -1; goto done; } add_pending_object(&rev, parse_object(the_repository, &info->b_commit), ""); if (run_diff_index(&rev, 0)) { ret = -1; goto done; } cp_upd_index.git_cmd = 1; argv_array_pushl(&cp_upd_index.args, "update-index", "-z", "--add", "--remove", "--stdin", NULL); argv_array_pushf(&cp_upd_index.env_array, "GIT_INDEX_FILE=%s", stash_index_path.buf); if (pipe_command(&cp_upd_index, diff_output.buf, diff_output.len, NULL, 0, NULL, 0)) { ret = -1; goto done; } if (write_index_as_tree(&info->w_tree, &istate, stash_index_path.buf, 0, NULL)) { ret = -1; goto done; } done: discard_index(&istate); UNLEAK(rev); object_array_clear(&rev.pending); strbuf_release(&diff_output); remove_path(stash_index_path.buf); return ret; }
static int stash_patch(struct stash_info *info, struct pathspec ps, struct strbuf *out_patch, int quiet) { int ret = 0; struct child_process cp_read_tree = CHILD_PROCESS_INIT; struct child_process cp_add_i = CHILD_PROCESS_INIT; struct child_process cp_diff_tree = CHILD_PROCESS_INIT; struct index_state istate = { NULL }; remove_path(stash_index_path.buf); cp_read_tree.git_cmd = 1; argv_array_pushl(&cp_read_tree.args, "read-tree", "HEAD", NULL); argv_array_pushf(&cp_read_tree.env_array, "GIT_INDEX_FILE=%s", stash_index_path.buf); if (run_command(&cp_read_tree)) { ret = -1; goto done; } /* Find out what the user wants. */ cp_add_i.git_cmd = 1; argv_array_pushl(&cp_add_i.args, "add--interactive", "--patch=stash", "--", NULL); add_pathspecs(&cp_add_i.args, ps); argv_array_pushf(&cp_add_i.env_array, "GIT_INDEX_FILE=%s", stash_index_path.buf); if (run_command(&cp_add_i)) { ret = -1; goto done; } /* State of the working tree. */ if (write_index_as_tree(&info->w_tree, &istate, stash_index_path.buf, 0, NULL)) { ret = -1; goto done; } cp_diff_tree.git_cmd = 1; argv_array_pushl(&cp_diff_tree.args, "diff-tree", "-p", "HEAD", oid_to_hex(&info->w_tree), "--", NULL); if (pipe_command(&cp_diff_tree, NULL, 0, out_patch, 0, NULL, 0)) { ret = -1; goto done; } if (!out_patch->len) { if (!quiet) fprintf_ln(stderr, _("No changes selected")); ret = 1; } done: discard_index(&istate); remove_path(stash_index_path.buf); return ret; }
static int save_untracked_files(struct stash_info *info, struct strbuf *msg, struct strbuf files) { int ret = 0; struct strbuf untracked_msg = STRBUF_INIT; struct child_process cp_upd_index = CHILD_PROCESS_INIT; struct index_state istate = { NULL }; cp_upd_index.git_cmd = 1; argv_array_pushl(&cp_upd_index.args, "update-index", "-z", "--add", "--remove", "--stdin", NULL); argv_array_pushf(&cp_upd_index.env_array, "GIT_INDEX_FILE=%s", stash_index_path.buf); strbuf_addf(&untracked_msg, "untracked files on %s\n", msg->buf); if (pipe_command(&cp_upd_index, files.buf, files.len, NULL, 0, NULL, 0)) { ret = -1; goto done; } if (write_index_as_tree(&info->u_tree, &istate, stash_index_path.buf, 0, NULL)) { ret = -1; goto done; } if (commit_tree(untracked_msg.buf, untracked_msg.len, &info->u_tree, NULL, &info->u_commit, NULL, NULL)) { ret = -1; goto done; } done: discard_index(&istate); strbuf_release(&untracked_msg); remove_path(stash_index_path.buf); return ret; }
int write_cache_as_tree(unsigned char *sha1, int flags, const char *prefix) { return write_index_as_tree(sha1, &the_index, get_index_file(), flags, prefix); }