diff options
Diffstat (limited to 'sequencer.c')
-rw-r--r-- | sequencer.c | 113 |
1 files changed, 67 insertions, 46 deletions
diff --git a/sequencer.c b/sequencer.c index a23b948ac1..fcceabb80f 100644 --- a/sequencer.c +++ b/sequencer.c @@ -1,4 +1,5 @@ #include "cache.h" +#include "config.h" #include "lockfile.h" #include "sequencer.h" #include "dir.h" @@ -126,6 +127,7 @@ static GIT_PATH_FUNC(rebase_path_onto, "rebase-merge/onto") static GIT_PATH_FUNC(rebase_path_autostash, "rebase-merge/autostash") static GIT_PATH_FUNC(rebase_path_strategy, "rebase-merge/strategy") static GIT_PATH_FUNC(rebase_path_strategy_opts, "rebase-merge/strategy_opts") +static GIT_PATH_FUNC(rebase_path_allow_rerere_autoupdate, "rebase-merge/allow_rerere_autoupdate") static inline int is_rebase_i(const struct replay_opts *opts) { @@ -464,7 +466,8 @@ static int do_recursive_merge(struct commit *base, struct commit *next, if (active_cache_changed && write_locked_index(&the_index, &index_lock, COMMIT_LOCK)) - /* TRANSLATORS: %s will be "revert", "cherry-pick" or + /* + * TRANSLATORS: %s will be "revert", "cherry-pick" or * "rebase -i". */ return error(_("%s: Unable to write new index file"), @@ -689,7 +692,7 @@ static int run_git_commit(const char *defmsg, struct replay_opts *opts, static int is_original_commit_empty(struct commit *commit) { - const unsigned char *ptree_sha1; + const struct object_id *ptree_oid; if (parse_commit(commit)) return error(_("could not parse commit %s\n"), @@ -699,12 +702,12 @@ static int is_original_commit_empty(struct commit *commit) if (parse_commit(parent)) return error(_("could not parse parent commit %s\n"), oid_to_hex(&parent->object.oid)); - ptree_sha1 = parent->tree->object.oid.hash; + ptree_oid = &parent->tree->object.oid; } else { - ptree_sha1 = EMPTY_TREE_SHA1_BIN; /* commit is root */ + ptree_oid = &empty_tree_oid; /* commit is root */ } - return !hashcmp(ptree_sha1, commit->tree->object.oid.hash); + return !oidcmp(ptree_oid, &commit->tree->object.oid); } /* @@ -894,18 +897,18 @@ static int update_squash_messages(enum todo_command command, static void flush_rewritten_pending(void) { struct strbuf buf = STRBUF_INIT; - unsigned char newsha1[20]; + struct object_id newoid; FILE *out; - if (strbuf_read_file(&buf, rebase_path_rewritten_pending(), 82) > 0 && - !get_sha1("HEAD", newsha1) && - (out = fopen(rebase_path_rewritten_list(), "a"))) { + if (strbuf_read_file(&buf, rebase_path_rewritten_pending(), (GIT_MAX_HEXSZ + 1) * 2) > 0 && + !get_oid("HEAD", &newoid) && + (out = fopen_or_warn(rebase_path_rewritten_list(), "a"))) { char *bol = buf.buf, *eol; while (*bol) { eol = strchrnul(bol, '\n'); fprintf(out, "%.*s %s\n", (int)(eol - bol), - bol, sha1_to_hex(newsha1)); + bol, oid_to_hex(&newoid)); if (!*eol) break; bol = eol + 1; @@ -918,7 +921,7 @@ static void flush_rewritten_pending(void) { static void record_in_rewritten(struct object_id *oid, enum todo_command next_command) { - FILE *out = fopen(rebase_path_rewritten_pending(), "a"); + FILE *out = fopen_or_warn(rebase_path_rewritten_pending(), "a"); if (!out) return; @@ -1210,8 +1213,7 @@ struct todo_list { static void todo_list_release(struct todo_list *todo_list) { strbuf_release(&todo_list->buf); - free(todo_list->items); - todo_list->items = NULL; + FREE_AND_NULL(todo_list->items); todo_list->nr = todo_list->alloc = 0; } @@ -1380,7 +1382,7 @@ static int read_populate_todo(struct todo_list *todo_list, if (is_rebase_i(opts)) { struct todo_list done = TODO_LIST_INIT; - FILE *f = fopen(rebase_path_msgtotal(), "w"); + FILE *f = fopen_or_warn(rebase_path_msgtotal(), "w"); if (strbuf_read_file(&done.buf, rebase_path_done(), 0) > 0 && !parse_insn_buffer(done.buf.buf, &done)) @@ -1437,7 +1439,11 @@ static int populate_opts_cb(const char *key, const char *value, void *data) else if (!strcmp(key, "options.strategy-option")) { ALLOC_GROW(opts->xopts, opts->xopts_nr + 1, opts->xopts_alloc); opts->xopts[opts->xopts_nr++] = xstrdup(value); - } else + } else if (!strcmp(key, "options.allow-rerere-auto")) + opts->allow_rerere_auto = + git_config_bool_or_int(key, value, &error_flag) ? + RERERE_AUTOUPDATE : RERERE_NOAUTOUPDATE; + else return error(_("invalid key: %s"), key); if (!error_flag) @@ -1478,6 +1484,15 @@ static int read_populate_opts(struct replay_opts *opts) free(opts->gpg_sign); opts->gpg_sign = xstrdup(buf.buf + 2); } + strbuf_reset(&buf); + } + + if (read_oneliner(&buf, rebase_path_allow_rerere_autoupdate(), 1)) { + if (!strcmp(buf.buf, "--rerere-autoupdate")) + opts->allow_rerere_auto = RERERE_AUTOUPDATE; + else if (!strcmp(buf.buf, "--no-rerere-autoupdate")) + opts->allow_rerere_auto = RERERE_NOAUTOUPDATE; + strbuf_reset(&buf); } if (file_exists(rebase_path_verbose())) @@ -1593,36 +1608,37 @@ static int rollback_is_safe(void) return !oidcmp(&actual_head, &expected_head); } -static int reset_for_rollback(const unsigned char *sha1) +static int reset_for_rollback(const struct object_id *oid) { const char *argv[4]; /* reset --merge <arg> + NULL */ argv[0] = "reset"; argv[1] = "--merge"; - argv[2] = sha1_to_hex(sha1); + argv[2] = oid_to_hex(oid); argv[3] = NULL; return run_command_v_opt(argv, RUN_GIT_CMD); } static int rollback_single_pick(void) { - unsigned char head_sha1[20]; + struct object_id head_oid; if (!file_exists(git_path_cherry_pick_head()) && !file_exists(git_path_revert_head())) return error(_("no cherry-pick or revert in progress")); - if (read_ref_full("HEAD", 0, head_sha1, NULL)) + if (read_ref_full("HEAD", 0, head_oid.hash, NULL)) return error(_("cannot resolve HEAD")); - if (is_null_sha1(head_sha1)) + if (is_null_oid(&head_oid)) return error(_("cannot abort from a branch yet to be born")); - return reset_for_rollback(head_sha1); + return reset_for_rollback(&head_oid); } int sequencer_rollback(struct replay_opts *opts) { FILE *f; - unsigned char sha1[20]; + struct object_id oid; struct strbuf buf = STRBUF_INIT; + const char *p; f = fopen(git_path_head_file(), "r"); if (!f && errno == ENOENT) { @@ -1642,12 +1658,12 @@ int sequencer_rollback(struct replay_opts *opts) goto fail; } fclose(f); - if (get_sha1_hex(buf.buf, sha1) || buf.buf[40] != '\0') { + if (parse_oid_hex(buf.buf, &oid, &p) || *p != '\0') { error(_("stored pre-cherry-pick HEAD file '%s' is corrupt"), git_path_head_file()); goto fail; } - if (is_null_sha1(sha1)) { + if (is_null_oid(&oid)) { error(_("cannot abort from a branch yet to be born")); goto fail; } @@ -1657,7 +1673,7 @@ int sequencer_rollback(struct replay_opts *opts) warning(_("You seem to have moved HEAD. " "Not rewinding, check your HEAD!")); } else - if (reset_for_rollback(sha1)) + if (reset_for_rollback(&oid)) goto fail; strbuf_release(&buf); return sequencer_remove_state(opts); @@ -1741,6 +1757,10 @@ static int save_opts(struct replay_opts *opts) "options.strategy-option", opts->xopts[i], "^$", 0); } + if (opts->allow_rerere_auto) + res |= git_config_set_in_file_gently(opts_file, "options.allow-rerere-auto", + opts->allow_rerere_auto == RERERE_AUTOUPDATE ? + "true" : "false"); return res; } @@ -1787,13 +1807,13 @@ static int make_patch(struct commit *commit, struct replay_opts *opts) static int intend_to_amend(void) { - unsigned char head[20]; + struct object_id head; char *p; - if (get_sha1("HEAD", head)) + if (get_oid("HEAD", &head)) return error(_("cannot read HEAD")); - p = sha1_to_hex(head); + p = oid_to_hex(&head); return write_message(p, strlen(p), rebase_path_amend(), 1); } @@ -1921,7 +1941,7 @@ static int apply_autostash(struct replay_opts *opts) argv_array_push(&child.args, "apply"); argv_array_push(&child.args, stash_sha1.buf); if (!run_command(&child)) - printf(_("Applied autostash.\n")); + fprintf(stderr, _("Applied autostash.\n")); else { struct child_process store = CHILD_PROCESS_INIT; @@ -1935,10 +1955,11 @@ static int apply_autostash(struct replay_opts *opts) if (run_command(&store)) ret = error(_("cannot store %s"), stash_sha1.buf); else - printf(_("Applying autostash resulted in conflicts.\n" - "Your changes are safe in the stash.\n" - "You can run \"git stash pop\" or" - " \"git stash drop\" at any time.\n")); + fprintf(stderr, + _("Applying autostash resulted in conflicts.\n" + "Your changes are safe in the stash.\n" + "You can run \"git stash pop\" or" + " \"git stash drop\" at any time.\n")); } strbuf_release(&stash_sha1); @@ -2077,10 +2098,10 @@ static int pick_commits(struct todo_list *todo_list, struct replay_opts *opts) if (read_oneliner(&head_ref, rebase_path_head_name(), 0) && starts_with(head_ref.buf, "refs/")) { const char *msg; - unsigned char head[20], orig[20]; + struct object_id head, orig; int res; - if (get_sha1("HEAD", head)) { + if (get_oid("HEAD", &head)) { res = error(_("cannot read HEAD")); cleanup_head_ref: strbuf_release(&head_ref); @@ -2088,7 +2109,7 @@ cleanup_head_ref: return res; } if (!read_oneliner(&buf, rebase_path_orig_head(), 0) || - get_sha1_hex(buf.buf, orig)) { + get_oid_hex(buf.buf, &orig)) { res = error(_("could not read orig-head")); goto cleanup_head_ref; } @@ -2099,7 +2120,7 @@ cleanup_head_ref: } msg = reflog_message(opts, "finish", "%s onto %s", head_ref.buf, buf.buf); - if (update_ref(msg, head_ref.buf, head, orig, + if (update_ref(msg, head_ref.buf, head.hash, orig.hash, REF_NODEREF, UPDATE_REFS_MSG_ON_ERR)) { res = error(_("could not update %s"), head_ref.buf); @@ -2127,10 +2148,10 @@ cleanup_head_ref: log_tree_opt.disable_stdin = 1; if (read_oneliner(&buf, rebase_path_orig_head(), 0) && - !get_sha1(buf.buf, orig.hash) && - !get_sha1("HEAD", head.hash)) { - diff_tree_sha1(orig.hash, head.hash, - "", &log_tree_opt.diffopt); + !get_oid(buf.buf, &orig) && + !get_oid("HEAD", &head)) { + diff_tree_oid(&orig, &head, "", + &log_tree_opt.diffopt); log_tree_diff_flush(&log_tree_opt); } } @@ -2203,16 +2224,16 @@ static int commit_staged_changes(struct replay_opts *opts) if (file_exists(rebase_path_amend())) { struct strbuf rev = STRBUF_INIT; - unsigned char head[20], to_amend[20]; + struct object_id head, to_amend; - if (get_sha1("HEAD", head)) + if (get_oid("HEAD", &head)) return error(_("cannot amend non-existing commit")); if (!read_oneliner(&rev, rebase_path_amend(), 0)) return error(_("invalid file: '%s'"), rebase_path_amend()); - if (get_sha1_hex(rev.buf, to_amend)) + if (get_oid_hex(rev.buf, &to_amend)) return error(_("invalid contents: '%s'"), rebase_path_amend()); - if (hashcmp(head, to_amend)) + if (oidcmp(&head, &to_amend)) return error(_("\nYou have uncommitted changes in your " "working tree. Please, commit them\n" "first and then run 'git rebase " @@ -2264,7 +2285,7 @@ int sequencer_continue(struct replay_opts *opts) struct object_id oid; if (read_oneliner(&buf, rebase_path_stopped_sha(), 1) && - !get_sha1_committish(buf.buf, oid.hash)) + !get_oid_committish(buf.buf, &oid)) record_in_rewritten(&oid, peek_command(&todo_list, 0)); strbuf_release(&buf); } |