int cmd_write_tree(int argc, const char **argv, const char *unused_prefix) { int flags = 0, ret; const char *prefix = NULL; unsigned char sha1[20]; const char *me = "git-write-tree"; struct option write_tree_options[] = { OPT_BIT(0, "missing-ok", &flags, "allow missing objects", WRITE_TREE_MISSING_OK), { OPTION_STRING, 0, "prefix", &prefix, "<prefix>/", "write tree object for a subdirectory <prefix>" , PARSE_OPT_LITERAL_ARGHELP }, { OPTION_BIT, 0, "ignore-cache-tree", &flags, NULL, "only useful for debugging", PARSE_OPT_HIDDEN | PARSE_OPT_NOARG, NULL, WRITE_TREE_IGNORE_CACHE_TREE }, OPT_END() }; git_config(git_default_config, NULL); argc = parse_options(argc, argv, unused_prefix, write_tree_options, write_tree_usage, 0); ret = write_cache_as_tree(sha1, flags, prefix); switch (ret) { case 0: printf("%s\n", sha1_to_hex(sha1)); break; case WRITE_TREE_UNREADABLE_INDEX: die("%s: error reading the index", me); break; case WRITE_TREE_UNMERGED_INDEX: die("%s: error building trees", me); break; case WRITE_TREE_PREFIX_ERROR: die("%s: prefix %s not found", me, prefix); break; } return ret; }
int cmd_write_tree(int argc, const char **argv, const char *unused_prefix) { int missing_ok = 0, ret; const char *prefix = NULL; unsigned char sha1[20]; const char *me = "git-write-tree"; git_config(git_default_config, NULL); while (1 < argc) { const char *arg = argv[1]; if (!strcmp(arg, "--missing-ok")) missing_ok = 1; else if (!prefixcmp(arg, "--prefix=")) prefix = arg + 9; else usage(write_tree_usage); argc--; argv++; } if (argc > 2) die("too many options"); ret = write_cache_as_tree(sha1, missing_ok, prefix); switch (ret) { case 0: printf("%s\n", sha1_to_hex(sha1)); break; case WRITE_TREE_UNREADABLE_INDEX: die("%s: error reading the index", me); break; case WRITE_TREE_UNMERGED_INDEX: die("%s: error building trees; the index is unmerged?", me); break; case WRITE_TREE_PREFIX_ERROR: die("%s: prefix %s not found", me, prefix); break; } return ret; }
static int do_pick_commit(struct commit *commit, struct replay_opts *opts) { unsigned char head[20]; struct commit *base, *next, *parent; const char *base_label, *next_label; struct commit_message msg = { NULL, NULL, NULL, NULL }; struct strbuf msgbuf = STRBUF_INIT; int res, unborn = 0, allow; if (opts->no_commit) { /* * We do not intend to commit immediately. We just want to * merge the differences in, so let's compute the tree * that represents the "current" state for merge-recursive * to work on. */ if (write_cache_as_tree(head, 0, NULL)) die (_("Your index file is unmerged.")); } else { unborn = get_sha1("HEAD", head); if (unborn) hashcpy(head, EMPTY_TREE_SHA1_BIN); if (index_differs_from(unborn ? EMPTY_TREE_SHA1_HEX : "HEAD", 0)) return error_dirty_index(opts); } discard_cache(); if (!commit->parents) { parent = NULL; } else if (commit->parents->next) { /* Reverting or cherry-picking a merge commit */ int cnt; struct commit_list *p; if (!opts->mainline) return error(_("Commit %s is a merge but no -m option was given."), oid_to_hex(&commit->object.oid)); for (cnt = 1, p = commit->parents; cnt != opts->mainline && p; cnt++) p = p->next; if (cnt != opts->mainline || !p) return error(_("Commit %s does not have parent %d"), oid_to_hex(&commit->object.oid), opts->mainline); parent = p->item; } else if (0 < opts->mainline) return error(_("Mainline was specified but commit %s is not a merge."), oid_to_hex(&commit->object.oid)); else parent = commit->parents->item; if (opts->allow_ff && ((parent && !hashcmp(parent->object.oid.hash, head)) || (!parent && unborn))) return fast_forward_to(commit->object.oid.hash, head, unborn, opts); if (parent && parse_commit(parent) < 0) /* TRANSLATORS: The first %s will be "revert" or "cherry-pick", the second %s a SHA1 */ return error(_("%s: cannot parse parent commit %s"), action_name(opts), oid_to_hex(&parent->object.oid)); if (get_message(commit, &msg) != 0) return error(_("Cannot get commit message for %s"), oid_to_hex(&commit->object.oid)); /* * "commit" is an existing commit. We would want to apply * the difference it introduces since its first parent "prev" * on top of the current HEAD if we are cherry-pick. Or the * reverse of it if we are revert. */ if (opts->action == REPLAY_REVERT) { base = commit; base_label = msg.label; next = parent; next_label = msg.parent_label; strbuf_addstr(&msgbuf, "Revert \""); strbuf_addstr(&msgbuf, msg.subject); strbuf_addstr(&msgbuf, "\"\n\nThis reverts commit "); strbuf_addstr(&msgbuf, oid_to_hex(&commit->object.oid)); if (commit->parents && commit->parents->next) { strbuf_addstr(&msgbuf, ", reversing\nchanges made to "); strbuf_addstr(&msgbuf, oid_to_hex(&parent->object.oid)); } strbuf_addstr(&msgbuf, ".\n"); } else { const char *p; base = parent; base_label = msg.parent_label; next = commit; next_label = msg.label; /* * Append the commit log message to msgbuf; it starts * after the tree, parent, author, committer * information followed by "\n\n". */ p = strstr(msg.message, "\n\n"); if (p) strbuf_addstr(&msgbuf, skip_blank_lines(p + 2)); if (opts->record_origin) { if (!has_conforming_footer(&msgbuf, NULL, 0)) strbuf_addch(&msgbuf, '\n'); strbuf_addstr(&msgbuf, cherry_picked_prefix); strbuf_addstr(&msgbuf, oid_to_hex(&commit->object.oid)); strbuf_addstr(&msgbuf, ")\n"); } } if (!opts->strategy || !strcmp(opts->strategy, "recursive") || opts->action == REPLAY_REVERT) { res = do_recursive_merge(base, next, base_label, next_label, head, &msgbuf, opts); write_message(&msgbuf, git_path_merge_msg()); } else { struct commit_list *common = NULL; struct commit_list *remotes = NULL; write_message(&msgbuf, git_path_merge_msg()); commit_list_insert(base, &common); commit_list_insert(next, &remotes); res = try_merge_command(opts->strategy, opts->xopts_nr, opts->xopts, common, sha1_to_hex(head), remotes); free_commit_list(common); free_commit_list(remotes); } /* * If the merge was clean or if it failed due to conflict, we write * CHERRY_PICK_HEAD for the subsequent invocation of commit to use. * However, if the merge did not even start, then we don't want to * write it at all. */ if (opts->action == REPLAY_PICK && !opts->no_commit && (res == 0 || res == 1)) update_ref(NULL, "CHERRY_PICK_HEAD", commit->object.oid.hash, NULL, REF_NODEREF, UPDATE_REFS_DIE_ON_ERR); if (opts->action == REPLAY_REVERT && ((opts->no_commit && res == 0) || res == 1)) update_ref(NULL, "REVERT_HEAD", commit->object.oid.hash, NULL, REF_NODEREF, UPDATE_REFS_DIE_ON_ERR); if (res) { error(opts->action == REPLAY_REVERT ? _("could not revert %s... %s") : _("could not apply %s... %s"), find_unique_abbrev(commit->object.oid.hash, DEFAULT_ABBREV), msg.subject); print_advice(res == 1, opts); rerere(opts->allow_rerere_auto); goto leave; } allow = allow_empty(opts, commit); if (allow < 0) { res = allow; goto leave; } if (!opts->no_commit) res = run_git_commit(git_path_merge_msg(), opts, allow); leave: free_message(commit, &msg); return res; }
static void write_tree_trivial(unsigned char *sha1) { if (write_cache_as_tree(sha1, 0, NULL)) die(_("git write-tree failed to write a tree")); }
static int do_apply_stash(const char *prefix, struct stash_info *info, int index, int quiet) { int ret; int has_index = index; struct merge_options o; struct object_id c_tree; struct object_id index_tree; struct commit *result; const struct object_id *bases[1]; read_cache_preload(NULL); if (refresh_cache(REFRESH_QUIET)) return -1; if (write_cache_as_tree(&c_tree, 0, NULL)) return error(_("cannot apply a stash in the middle of a merge")); if (index) { if (oideq(&info->b_tree, &info->i_tree) || oideq(&c_tree, &info->i_tree)) { has_index = 0; } else { struct strbuf out = STRBUF_INIT; if (diff_tree_binary(&out, &info->w_commit)) { strbuf_release(&out); return error(_("could not generate diff %s^!."), oid_to_hex(&info->w_commit)); } ret = apply_cached(&out); strbuf_release(&out); if (ret) return error(_("conflicts in index." "Try without --index.")); discard_cache(); read_cache(); if (write_cache_as_tree(&index_tree, 0, NULL)) return error(_("could not save index tree")); reset_head(); } } if (info->has_u && restore_untracked(&info->u_tree)) return error(_("could not restore untracked files from stash")); init_merge_options(&o, the_repository); o.branch1 = "Updated upstream"; o.branch2 = "Stashed changes"; if (oideq(&info->b_tree, &c_tree)) o.branch1 = "Version stash was based on"; if (quiet) o.verbosity = 0; if (o.verbosity >= 3) printf_ln(_("Merging %s with %s"), o.branch1, o.branch2); bases[0] = &info->b_tree; ret = merge_recursive_generic(&o, &c_tree, &info->w_tree, 1, bases, &result); if (ret) { rerere(0); if (index) fprintf_ln(stderr, _("Index was not unstashed.")); return ret; } if (has_index) { if (reset_tree(&index_tree, 0, 0)) return -1; } else { struct strbuf out = STRBUF_INIT; if (get_newly_staged(&out, &c_tree)) { strbuf_release(&out); return -1; } if (reset_tree(&c_tree, 0, 1)) { strbuf_release(&out); return -1; } ret = update_index(&out); strbuf_release(&out); if (ret) return -1; discard_cache(); } if (quiet) { if (refresh_cache(REFRESH_QUIET)) warning("could not refresh index"); } else { struct child_process cp = CHILD_PROCESS_INIT; /* * Status is quite simple and could be replaced with calls to * wt_status in the future, but it adds complexities which may * require more tests. */ cp.git_cmd = 1; cp.dir = prefix; argv_array_push(&cp.args, "status"); run_command(&cp); } return 0; }
static int do_create_stash(struct pathspec ps, struct strbuf *stash_msg_buf, int include_untracked, int patch_mode, struct stash_info *info, struct strbuf *patch, int quiet) { int ret = 0; int flags = 0; int untracked_commit_option = 0; const char *head_short_sha1 = NULL; const char *branch_ref = NULL; const char *branch_name = "(no branch)"; struct commit *head_commit = NULL; struct commit_list *parents = NULL; struct strbuf msg = STRBUF_INIT; struct strbuf commit_tree_label = STRBUF_INIT; struct strbuf untracked_files = STRBUF_INIT; prepare_fallback_ident("git stash", "[email protected]"); read_cache_preload(NULL); refresh_cache(REFRESH_QUIET); if (get_oid("HEAD", &info->b_commit)) { if (!quiet) fprintf_ln(stderr, _("You do not have " "the initial commit yet")); ret = -1; goto done; } else { head_commit = lookup_commit(the_repository, &info->b_commit); } if (!check_changes(ps, include_untracked, &untracked_files)) { ret = 1; goto done; } branch_ref = resolve_ref_unsafe("HEAD", 0, NULL, &flags); if (flags & REF_ISSYMREF) branch_name = strrchr(branch_ref, '/') + 1; head_short_sha1 = find_unique_abbrev(&head_commit->object.oid, DEFAULT_ABBREV); strbuf_addf(&msg, "%s: %s ", branch_name, head_short_sha1); pp_commit_easy(CMIT_FMT_ONELINE, head_commit, &msg); strbuf_addf(&commit_tree_label, "index on %s\n", msg.buf); commit_list_insert(head_commit, &parents); if (write_cache_as_tree(&info->i_tree, 0, NULL) || commit_tree(commit_tree_label.buf, commit_tree_label.len, &info->i_tree, parents, &info->i_commit, NULL, NULL)) { if (!quiet) fprintf_ln(stderr, _("Cannot save the current " "index state")); ret = -1; goto done; } if (include_untracked) { if (save_untracked_files(info, &msg, untracked_files)) { if (!quiet) fprintf_ln(stderr, _("Cannot save " "the untracked files")); ret = -1; goto done; } untracked_commit_option = 1; } if (patch_mode) { ret = stash_patch(info, ps, patch, quiet); if (ret < 0) { if (!quiet) fprintf_ln(stderr, _("Cannot save the current " "worktree state")); goto done; } else if (ret > 0) { goto done; } } else { if (stash_working_tree(info, ps)) { if (!quiet) fprintf_ln(stderr, _("Cannot save the current " "worktree state")); ret = -1; goto done; } } if (!stash_msg_buf->len) strbuf_addf(stash_msg_buf, "WIP on %s", msg.buf); else strbuf_insertf(stash_msg_buf, 0, "On %s: ", branch_name); /* * `parents` will be empty after calling `commit_tree()`, so there is * no need to call `free_commit_list()` */ parents = NULL; if (untracked_commit_option) commit_list_insert(lookup_commit(the_repository, &info->u_commit), &parents); commit_list_insert(lookup_commit(the_repository, &info->i_commit), &parents); commit_list_insert(head_commit, &parents); if (commit_tree(stash_msg_buf->buf, stash_msg_buf->len, &info->w_tree, parents, &info->w_commit, NULL, NULL)) { if (!quiet) fprintf_ln(stderr, _("Cannot record " "working tree state")); ret = -1; goto done; } done: strbuf_release(&commit_tree_label); strbuf_release(&msg); strbuf_release(&untracked_files); return ret; }
static int do_pick_commit(void) { unsigned char head[20]; struct commit *base, *next, *parent; const char *base_label, *next_label; struct commit_message msg = { NULL, NULL, NULL, NULL, NULL }; char *defmsg = NULL; struct strbuf msgbuf = STRBUF_INIT; if (no_commit) { /* * We do not intend to commit immediately. We just want to * merge the differences in, so let's compute the tree * that represents the "current" state for merge-recursive * to work on. */ if (write_cache_as_tree(head, 0, NULL)) die ("Your index file is unmerged."); } else { if (get_sha1("HEAD", head)) die ("You do not have a valid HEAD"); if (index_differs_from("HEAD", 0)) die_dirty_index(me); } discard_cache(); if (!commit->parents) { if (action == REVERT) die ("Cannot revert a root commit"); parent = NULL; } else if (commit->parents->next) { /* Reverting or cherry-picking a merge commit */ int cnt; struct commit_list *p; if (!mainline) die("Commit %s is a merge but no -m option was given.", sha1_to_hex(commit->object.sha1)); for (cnt = 1, p = commit->parents; cnt != mainline && p; cnt++) p = p->next; if (cnt != mainline || !p) die("Commit %s does not have parent %d", sha1_to_hex(commit->object.sha1), mainline); parent = p->item; } else if (0 < mainline) die("Mainline was specified but commit %s is not a merge.", sha1_to_hex(commit->object.sha1)); else parent = commit->parents->item; if (allow_ff && !hashcmp(parent->object.sha1, head)) return fast_forward_to(commit->object.sha1, head); if (parent && parse_commit(parent) < 0) die("%s: cannot parse parent commit %s", me, sha1_to_hex(parent->object.sha1)); if (get_message(commit->buffer, &msg) != 0) die("Cannot get commit message for %s", sha1_to_hex(commit->object.sha1)); /* * "commit" is an existing commit. We would want to apply * the difference it introduces since its first parent "prev" * on top of the current HEAD if we are cherry-pick. Or the * reverse of it if we are revert. */ defmsg = git_pathdup("MERGE_MSG"); if (action == REVERT) { base = commit; base_label = msg.label; next = parent; next_label = msg.parent_label; strbuf_addstr(&msgbuf, "Revert \""); strbuf_addstr(&msgbuf, msg.subject); strbuf_addstr(&msgbuf, "\"\n\nThis reverts commit "); strbuf_addstr(&msgbuf, sha1_to_hex(commit->object.sha1)); if (commit->parents->next) { strbuf_addstr(&msgbuf, ", reversing\nchanges made to "); strbuf_addstr(&msgbuf, sha1_to_hex(parent->object.sha1)); } strbuf_addstr(&msgbuf, ".\n"); } else { base = parent; base_label = msg.parent_label; next = commit; next_label = msg.label; set_author_ident_env(msg.message); add_message_to_msg(&msgbuf, msg.message); if (no_replay) { strbuf_addstr(&msgbuf, "(cherry picked from commit "); strbuf_addstr(&msgbuf, sha1_to_hex(commit->object.sha1)); strbuf_addstr(&msgbuf, ")\n"); } } if (!strategy || !strcmp(strategy, "recursive") || action == REVERT) do_recursive_merge(base, next, base_label, next_label, head, &msgbuf, defmsg); else { int res; struct commit_list *common = NULL; struct commit_list *remotes = NULL; write_message(&msgbuf, defmsg); commit_list_insert(base, &common); commit_list_insert(next, &remotes); res = try_merge_command(strategy, common, sha1_to_hex(head), remotes); free_commit_list(common); free_commit_list(remotes); if (res) { fprintf(stderr, "Automatic %s with strategy %s failed.%s\n", me, strategy, help_msg()); rerere(allow_rerere_auto); exit(1); } } free_message(&msg); /* * * If we are cherry-pick, and if the merge did not result in * hand-editing, we will hit this commit and inherit the original * author date and name. * If we are revert, or if our cherry-pick results in a hand merge, * we had better say that the current user is responsible for that. */ if (!no_commit) { /* 6 is max possible length of our args array including NULL */ const char *args[6]; int res; int i = 0; args[i++] = "commit"; args[i++] = "-n"; if (signoff) args[i++] = "-s"; if (!edit) { args[i++] = "-F"; args[i++] = defmsg; } args[i] = NULL; res = run_command_v_opt(args, RUN_GIT_CMD); free(defmsg); return res; } free(defmsg); return 0; }
static int do_pick_commit(void) { unsigned char head[20]; struct commit *base, *next, *parent; const char *base_label, *next_label; struct commit_message msg = { NULL, NULL, NULL, NULL, NULL }; char *defmsg = NULL; struct strbuf msgbuf = STRBUF_INIT; int res; if (no_commit) { /* * We do not intend to commit immediately. We just want to * merge the differences in, so let's compute the tree * that represents the "current" state for merge-recursive * to work on. */ if (write_cache_as_tree(head, 0, NULL)) die ("Your index file is unmerged."); } else { if (get_sha1("HEAD", head)) die ("You do not have a valid HEAD"); if (index_differs_from("HEAD", 0)) die_dirty_index(me); } discard_cache(); if (!commit->parents) { if (action == REVERT) die ("Cannot revert a root commit"); parent = NULL; } else if (commit->parents->next) { /* Reverting or cherry-picking a merge commit */ int cnt; struct commit_list *p; if (!mainline) die("Commit %s is a merge but no -m option was given.", sha1_to_hex(commit->object.sha1)); for (cnt = 1, p = commit->parents; cnt != mainline && p; cnt++) p = p->next; if (cnt != mainline || !p) die("Commit %s does not have parent %d", sha1_to_hex(commit->object.sha1), mainline); parent = p->item; } else if (0 < mainline) die("Mainline was specified but commit %s is not a merge.", sha1_to_hex(commit->object.sha1)); else parent = commit->parents->item; if (allow_ff && parent && !hashcmp(parent->object.sha1, head)) return fast_forward_to(commit->object.sha1, head); if (parent && parse_commit(parent) < 0) die("%s: cannot parse parent commit %s", me, sha1_to_hex(parent->object.sha1)); if (get_message(commit->buffer, &msg) != 0) die("Cannot get commit message for %s", sha1_to_hex(commit->object.sha1)); /* * "commit" is an existing commit. We would want to apply * the difference it introduces since its first parent "prev" * on top of the current HEAD if we are cherry-pick. Or the * reverse of it if we are revert. */ defmsg = git_pathdup("MERGE_MSG"); if (action == REVERT) { base = commit; base_label = msg.label; next = parent; next_label = msg.parent_label; strbuf_addstr(&msgbuf, "Revert \""); strbuf_addstr(&msgbuf, msg.subject); strbuf_addstr(&msgbuf, "\"\n\nThis reverts commit "); strbuf_addstr(&msgbuf, sha1_to_hex(commit->object.sha1)); if (commit->parents->next) { strbuf_addstr(&msgbuf, ", reversing\nchanges made to "); strbuf_addstr(&msgbuf, sha1_to_hex(parent->object.sha1)); } strbuf_addstr(&msgbuf, ".\n"); } else { base = parent; base_label = msg.parent_label; next = commit; next_label = msg.label; add_message_to_msg(&msgbuf, msg.message); if (no_replay) { strbuf_addstr(&msgbuf, "(cherry picked from commit "); strbuf_addstr(&msgbuf, sha1_to_hex(commit->object.sha1)); strbuf_addstr(&msgbuf, ")\n"); } if (!no_commit) write_cherry_pick_head(); } if (!strategy || !strcmp(strategy, "recursive") || action == REVERT) { res = do_recursive_merge(base, next, base_label, next_label, head, &msgbuf); write_message(&msgbuf, defmsg); } else { struct commit_list *common = NULL; struct commit_list *remotes = NULL; write_message(&msgbuf, defmsg); commit_list_insert(base, &common); commit_list_insert(next, &remotes); res = try_merge_command(strategy, xopts_nr, xopts, common, sha1_to_hex(head), remotes); free_commit_list(common); free_commit_list(remotes); } if (res) { error("could not %s %s... %s", action == REVERT ? "revert" : "apply", find_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV), msg.subject); print_advice(); rerere(allow_rerere_auto); } else { if (!no_commit) res = run_git_commit(defmsg); } free_message(&msg); free(defmsg); return res; }
static int revert_or_cherry_pick(int argc, const char **argv) { unsigned char head[20]; struct commit *base, *next, *parent; int i; char *oneline, *reencoded_message = NULL; const char *message, *encoding; const char *defmsg = xstrdup(git_path("MERGE_MSG")); git_config(git_default_config); me = action == REVERT ? "revert" : "cherry-pick"; setenv(GIT_REFLOG_ACTION, me, 0); parse_args(argc, argv); /* this is copied from the shell script, but it's never triggered... */ if (action == REVERT && !no_replay) die("revert is incompatible with replay"); if (no_commit) { /* * We do not intend to commit immediately. We just want to * merge the differences in, so let's compute the tree * that represents the "current" state for merge-recursive * to work on. */ if (write_cache_as_tree(head, 0, NULL)) die ("Your index file is unmerged."); } else { if (get_sha1("HEAD", head)) die ("You do not have a valid HEAD"); if (read_cache() < 0) die("could not read the index"); if (index_is_dirty()) die ("Dirty index: cannot %s", me); discard_cache(); } if (!commit->parents) die ("Cannot %s a root commit", me); if (commit->parents->next) { /* Reverting or cherry-picking a merge commit */ int cnt; struct commit_list *p; if (!mainline) die("Commit %s is a merge but no -m option was given.", sha1_to_hex(commit->object.sha1)); for (cnt = 1, p = commit->parents; cnt != mainline && p; cnt++) p = p->next; if (cnt != mainline || !p) die("Commit %s does not have parent %d", sha1_to_hex(commit->object.sha1), mainline); parent = p->item; } else if (0 < mainline) die("Mainline was specified but commit %s is not a merge.", sha1_to_hex(commit->object.sha1)); else parent = commit->parents->item; if (!(message = commit->buffer)) die ("Cannot get commit message for %s", sha1_to_hex(commit->object.sha1)); /* * "commit" is an existing commit. We would want to apply * the difference it introduces since its first parent "prev" * on top of the current HEAD if we are cherry-pick. Or the * reverse of it if we are revert. */ msg_fd = hold_lock_file_for_update(&msg_file, defmsg, 1); encoding = get_encoding(message); if (!encoding) encoding = "utf-8"; if (!git_commit_encoding) git_commit_encoding = "utf-8"; if ((reencoded_message = reencode_string(message, git_commit_encoding, encoding))) message = reencoded_message; oneline = get_oneline(message); if (action == REVERT) { char *oneline_body = strchr(oneline, ' '); base = commit; next = parent; add_to_msg("Revert \""); add_to_msg(oneline_body + 1); add_to_msg("\"\n\nThis reverts commit "); add_to_msg(sha1_to_hex(commit->object.sha1)); add_to_msg(".\n"); } else { base = parent; next = commit; set_author_ident_env(message); add_message_to_msg(message); if (no_replay) { add_to_msg("(cherry picked from commit "); add_to_msg(sha1_to_hex(commit->object.sha1)); add_to_msg(")\n"); } } if (merge_recursive(sha1_to_hex(base->object.sha1), sha1_to_hex(head), "HEAD", sha1_to_hex(next->object.sha1), oneline) || write_cache_as_tree(head, 0, NULL)) { add_to_msg("\nConflicts:\n\n"); read_cache(); for (i = 0; i < active_nr;) { struct cache_entry *ce = active_cache[i++]; if (ce_stage(ce)) { add_to_msg("\t"); add_to_msg(ce->name); add_to_msg("\n"); while (i < active_nr && !strcmp(ce->name, active_cache[i]->name)) i++; } } if (commit_lock_file(&msg_file) < 0) die ("Error wrapping up %s", defmsg); fprintf(stderr, "Automatic %s failed.%s\n", me, help_msg(commit->object.sha1)); exit(1); } if (commit_lock_file(&msg_file) < 0) die ("Error wrapping up %s", defmsg); fprintf(stderr, "Finished one %s.\n", me); /* * * If we are cherry-pick, and if the merge did not result in * hand-editing, we will hit this commit and inherit the original * author date and name. * If we are revert, or if our cherry-pick results in a hand merge, * we had better say that the current user is responsible for that. */ if (!no_commit) { /* 6 is max possible length of our args array including NULL */ const char *args[6]; int i = 0; args[i++] = "commit"; args[i++] = "-n"; if (signoff) args[i++] = "-s"; if (!edit) { args[i++] = "-F"; args[i++] = defmsg; } args[i] = NULL; return execv_git_cmd(args); } free(reencoded_message); return 0; }