diff options
Diffstat (limited to 'sequencer.c')
| -rw-r--r-- | sequencer.c | 223 |
1 files changed, 134 insertions, 89 deletions
diff --git a/sequencer.c b/sequencer.c index cf45070b7b..a2284ac9e9 100644 --- a/sequencer.c +++ b/sequencer.c @@ -1,3 +1,5 @@ +#define USE_THE_REPOSITORY_VARIABLE + #include "git-compat-util.h" #include "abspath.h" #include "advice.h" @@ -266,7 +268,7 @@ static struct update_ref_record *init_update_ref_record(const char *ref) oidcpy(&rec->after, null_oid()); /* This may fail, but that's fine, we will keep the null OID. */ - read_ref(ref, &rec->before); + refs_read_ref(get_main_ref_store(the_repository), ref, &rec->before); return rec; } @@ -306,7 +308,7 @@ static int git_sequencer_config(const char *k, const char *v, } if (!opts->default_strategy && !strcmp(k, "pull.twohead")) { - int ret = git_config_string((const char**)&opts->default_strategy, k, v); + int ret = git_config_string(&opts->default_strategy, k, v); if (ret == 0) { /* * pull.twohead is allowed to be multi-valued; we only @@ -359,35 +361,32 @@ static const char *get_todo_path(const struct replay_opts *opts) static int has_conforming_footer(struct strbuf *sb, struct strbuf *sob, size_t ignore_footer) { - struct process_trailer_options opts = PROCESS_TRAILER_OPTIONS_INIT; - struct trailer_info info; - size_t i; + struct trailer_iterator iter; + size_t i = 0; int found_sob = 0, found_sob_last = 0; char saved_char; - opts.no_divider = 1; - if (ignore_footer) { saved_char = sb->buf[sb->len - ignore_footer]; sb->buf[sb->len - ignore_footer] = '\0'; } - trailer_info_get(&opts, sb->buf, &info); + trailer_iterator_init(&iter, sb->buf); if (ignore_footer) sb->buf[sb->len - ignore_footer] = saved_char; - if (info.trailer_block_start == info.trailer_block_end) - return 0; + while (trailer_iterator_advance(&iter)) { + i++; + if (sob && !strncmp(iter.raw, sob->buf, sob->len)) + found_sob = i; + } + trailer_iterator_release(&iter); - for (i = 0; i < info.trailer_nr; i++) - if (sob && !strncmp(info.trailers[i], sob->buf, sob->len)) { - found_sob = 1; - if (i == info.trailer_nr - 1) - found_sob_last = 1; - } + if (!i) + return 0; - trailer_info_release(&info); + found_sob_last = (int)i == found_sob; if (found_sob_last) return 3; @@ -440,7 +439,7 @@ int sequencer_remove_state(struct replay_opts *opts) char *eol = strchr(p, '\n'); if (eol) *eol = '\0'; - if (delete_ref("(rebase) cleanup", p, NULL, 0) < 0) { + if (refs_delete_ref(get_main_ref_store(the_repository), "(rebase) cleanup", p, NULL, 0) < 0) { warning(_("could not delete '%s'"), p); ret = -1; } @@ -661,11 +660,12 @@ static int fast_forward_to(struct repository *r, strbuf_addf(&sb, "%s: fast-forward", action_name(opts)); - transaction = ref_transaction_begin(&err); + transaction = ref_store_transaction_begin(get_main_ref_store(the_repository), + &err); if (!transaction || ref_transaction_update(transaction, "HEAD", to, unborn && !is_rebase_i(opts) ? - null_oid() : from, + null_oid() : from, NULL, NULL, 0, sb.buf, &err) || ref_transaction_commit(transaction, &err)) { ref_transaction_free(transaction); @@ -841,11 +841,12 @@ static int is_index_unchanged(struct repository *r) struct index_state *istate = r->index; const char *head_name; - if (!resolve_ref_unsafe("HEAD", RESOLVE_REF_READING, &head_oid, NULL)) { + if (!refs_resolve_ref_unsafe(get_main_ref_store(the_repository), "HEAD", RESOLVE_REF_READING, &head_oid, NULL)) { /* Check to see if this is an unborn branch */ - head_name = resolve_ref_unsafe("HEAD", - RESOLVE_REF_READING | RESOLVE_REF_NO_RECURSE, - &head_oid, NULL); + head_name = refs_resolve_ref_unsafe(get_main_ref_store(the_repository), + "HEAD", + RESOLVE_REF_READING | RESOLVE_REF_NO_RECURSE, + &head_oid, NULL); if (!head_name || !starts_with(head_name, "refs/heads/") || !is_null_oid(&head_oid)) @@ -1294,11 +1295,12 @@ int update_head_with_reflog(const struct commit *old_head, strbuf_addch(&sb, '\n'); } - transaction = ref_transaction_begin(err); + transaction = ref_store_transaction_begin(get_main_ref_store(the_repository), + err); if (!transaction || ref_transaction_update(transaction, "HEAD", new_head, old_head ? &old_head->object.oid : null_oid(), - 0, sb.buf, err) || + NULL, NULL, 0, sb.buf, err) || ref_transaction_commit(transaction, err)) { ret = -1; } @@ -1711,6 +1713,7 @@ static int try_to_commit(struct repository *r, out: free_commit_extra_headers(extra); + free_commit_list(parents); strbuf_release(&err); strbuf_release(&commit_msg); free(amend_author); @@ -1720,8 +1723,8 @@ out: static int write_rebase_head(struct object_id *oid) { - if (update_ref("rebase", "REBASE_HEAD", oid, - NULL, REF_NO_DEREF, UPDATE_REFS_MSG_ON_ERR)) + if (refs_update_ref(get_main_ref_store(the_repository), "rebase", "REBASE_HEAD", oid, + NULL, REF_NO_DEREF, UPDATE_REFS_MSG_ON_ERR)) return error(_("could not update %s"), "REBASE_HEAD"); return 0; @@ -2263,7 +2266,7 @@ static int do_pick_commit(struct repository *r, unborn = 1; } else if (unborn) oidcpy(&head, the_hash_algo->empty_tree); - if (index_differs_from(r, unborn ? empty_tree_oid_hex() : "HEAD", + if (index_differs_from(r, unborn ? empty_tree_oid_hex(the_repository->hash_algo) : "HEAD", NULL, 0)) return error_dirty_index(r, opts); } @@ -2455,12 +2458,12 @@ static int do_pick_commit(struct repository *r, if ((command == TODO_PICK || command == TODO_REWORD || command == TODO_EDIT) && !opts->no_commit && (res == 0 || res == 1) && - update_ref(NULL, "CHERRY_PICK_HEAD", &commit->object.oid, NULL, - REF_NO_DEREF, UPDATE_REFS_MSG_ON_ERR)) + refs_update_ref(get_main_ref_store(the_repository), NULL, "CHERRY_PICK_HEAD", &commit->object.oid, NULL, + REF_NO_DEREF, UPDATE_REFS_MSG_ON_ERR)) res = -1; if (command == TODO_REVERT && ((opts->no_commit && res == 0) || res == 1) && - update_ref(NULL, "REVERT_HEAD", &commit->object.oid, NULL, - REF_NO_DEREF, UPDATE_REFS_MSG_ON_ERR)) + refs_update_ref(get_main_ref_store(the_repository), NULL, "REVERT_HEAD", &commit->object.oid, NULL, + REF_NO_DEREF, UPDATE_REFS_MSG_ON_ERR)) res = -1; if (res) { @@ -3394,12 +3397,12 @@ static int rollback_is_safe(void) strbuf_release(&sb); } else if (errno == ENOENT) - oidclr(&expected_head); + oidclr(&expected_head, the_repository->hash_algo); else die_errno(_("could not read '%s'"), git_path_abort_safety_file()); if (repo_get_oid(the_repository, "HEAD", &actual_head)) - oidclr(&actual_head); + oidclr(&actual_head, the_repository->hash_algo); return oideq(&actual_head, &expected_head); } @@ -3424,7 +3427,7 @@ static int rollback_single_pick(struct repository *r) if (!refs_ref_exists(get_main_ref_store(r), "CHERRY_PICK_HEAD") && !refs_ref_exists(get_main_ref_store(r), "REVERT_HEAD")) return error(_("no cherry-pick or revert in progress")); - if (read_ref_full("HEAD", 0, &head_oid, NULL)) + if (refs_read_ref_full(get_main_ref_store(the_repository), "HEAD", 0, &head_oid, NULL)) return error(_("cannot resolve HEAD")); if (is_null_oid(&head_oid)) return error(_("cannot abort from a branch yet to be born")); @@ -3435,7 +3438,7 @@ static int skip_single_pick(void) { struct object_id head; - if (read_ref_full("HEAD", 0, &head, NULL)) + if (refs_read_ref_full(get_main_ref_store(the_repository), "HEAD", 0, &head, NULL)) return error(_("cannot resolve HEAD")); return reset_merge(&head); } @@ -3892,8 +3895,9 @@ static int do_label(struct repository *r, const char *name, int len) } else if (repo_get_oid(r, "HEAD", &head_oid)) { error(_("could not read HEAD")); ret = -1; - } else if (ref_transaction_update(transaction, ref_name.buf, &head_oid, - NULL, 0, msg.buf, &err) < 0 || + } else if (ref_transaction_update(transaction, ref_name.buf, + &head_oid, NULL, NULL, NULL, + 0, msg.buf, &err) < 0 || ref_transaction_commit(transaction, &err)) { error("%s", err.buf); ret = -1; @@ -3951,7 +3955,7 @@ static struct commit *lookup_label(struct repository *r, const char *label, strbuf_reset(buf); strbuf_addf(buf, "refs/rewritten/%.*s", len, label); - if (!read_ref(buf->buf, &oid)) { + if (!refs_read_ref(get_main_ref_store(the_repository), buf->buf, &oid)) { commit = lookup_commit_object(r, &oid); } else { /* fall back to non-rewritten ref or commit */ @@ -4047,9 +4051,10 @@ static int do_reset(struct repository *r, ret = error(_("could not write index")); if (!ret) - ret = update_ref(reflog_message(opts, "reset", "'%.*s'", - len, name), "HEAD", &oid, - NULL, 0, UPDATE_REFS_MSG_ON_ERR); + ret = refs_update_ref(get_main_ref_store(the_repository), reflog_message(opts, "reset", "'%.*s'", + len, name), + "HEAD", &oid, + NULL, 0, UPDATE_REFS_MSG_ON_ERR); cleanup: free((void *)desc.buffer); if (ret < 0) @@ -4372,6 +4377,7 @@ leave_merge: strbuf_release(&ref_name); rollback_lock_file(&lock); free_commit_list(to_merge); + free_commit_list(bases); return ret; } @@ -4531,7 +4537,7 @@ static int do_update_ref(struct repository *r, const char *refname) for_each_string_list_item(item, &list) { if (!strcmp(item->string, refname)) { struct update_ref_record *rec = item->util; - if (read_ref("HEAD", &rec->after)) + if (refs_read_ref(get_main_ref_store(the_repository), "HEAD", &rec->after)) return -1; break; } @@ -5091,15 +5097,15 @@ 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, - REF_NO_DEREF, UPDATE_REFS_MSG_ON_ERR)) { + if (refs_update_ref(get_main_ref_store(the_repository), msg, head_ref.buf, &head, &orig, + REF_NO_DEREF, UPDATE_REFS_MSG_ON_ERR)) { res = error(_("could not update %s"), head_ref.buf); goto cleanup_head_ref; } msg = reflog_message(opts, "finish", "returning to %s", head_ref.buf); - if (create_symref("HEAD", head_ref.buf, msg)) { + if (refs_update_symref(get_main_ref_store(the_repository), "HEAD", head_ref.buf, msg)) { res = error(_("could not update HEAD to %s"), head_ref.buf); goto cleanup_head_ref; @@ -5203,33 +5209,47 @@ static int commit_staged_changes(struct repository *r, struct replay_ctx *ctx = opts->ctx; unsigned int flags = ALLOW_EMPTY | EDIT_MSG; unsigned int final_fixup = 0, is_clean; + struct strbuf rev = STRBUF_INIT; + int ret; - if (has_unstaged_changes(r, 1)) - return error(_("cannot rebase: You have unstaged changes.")); + if (has_unstaged_changes(r, 1)) { + ret = error(_("cannot rebase: You have unstaged changes.")); + goto out; + } is_clean = !has_uncommitted_changes(r, 0); if (!is_clean && !file_exists(rebase_path_message())) { const char *gpg_opt = gpg_sign_opt_quoted(opts); - - return error(_(staged_changes_advice), gpg_opt, gpg_opt); + ret = error(_(staged_changes_advice), gpg_opt, gpg_opt); + goto out; } + if (file_exists(rebase_path_amend())) { - struct strbuf rev = STRBUF_INIT; struct object_id head, to_amend; - if (repo_get_oid(r, "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_oid_hex(rev.buf, &to_amend)) - return error(_("invalid contents: '%s'"), - rebase_path_amend()); - if (!is_clean && !oideq(&head, &to_amend)) - return error(_("\nYou have uncommitted changes in your " - "working tree. Please, commit them\n" - "first and then run 'git rebase " - "--continue' again.")); + if (repo_get_oid(r, "HEAD", &head)) { + ret = error(_("cannot amend non-existing commit")); + goto out; + } + + if (!read_oneliner(&rev, rebase_path_amend(), 0)) { + ret = error(_("invalid file: '%s'"), rebase_path_amend()); + goto out; + } + + if (get_oid_hex(rev.buf, &to_amend)) { + ret = error(_("invalid contents: '%s'"), + rebase_path_amend()); + goto out; + } + if (!is_clean && !oideq(&head, &to_amend)) { + ret = error(_("\nYou have uncommitted changes in your " + "working tree. Please, commit them\n" + "first and then run 'git rebase " + "--continue' again.")); + goto out; + } /* * When skipping a failed fixup/squash, we need to edit the * commit message, the current fixup list and count, and if it @@ -5261,9 +5281,11 @@ static int commit_staged_changes(struct repository *r, len--; strbuf_setlen(&ctx->current_fixups, len); if (write_message(p, len, rebase_path_current_fixups(), - 0) < 0) - return error(_("could not write file: '%s'"), - rebase_path_current_fixups()); + 0) < 0) { + ret = error(_("could not write file: '%s'"), + rebase_path_current_fixups()); + goto out; + } /* * If a fixup/squash in a fixup/squash chain failed, the @@ -5293,35 +5315,38 @@ static int commit_staged_changes(struct repository *r, * We need to update the squash message to skip * the latest commit message. */ - int res = 0; struct commit *commit; const char *msg; const char *path = rebase_path_squash_msg(); const char *encoding = get_commit_output_encoding(); - if (parse_head(r, &commit)) - return error(_("could not parse HEAD")); + if (parse_head(r, &commit)) { + ret = error(_("could not parse HEAD")); + goto out; + } p = repo_logmsg_reencode(r, commit, NULL, encoding); if (!p) { - res = error(_("could not parse commit %s"), + ret = error(_("could not parse commit %s"), oid_to_hex(&commit->object.oid)); goto unuse_commit_buffer; } find_commit_subject(p, &msg); if (write_message(msg, strlen(msg), path, 0)) { - res = error(_("could not write file: " + ret = error(_("could not write file: " "'%s'"), path); goto unuse_commit_buffer; } + + ret = 0; + unuse_commit_buffer: repo_unuse_commit_buffer(r, commit, p); - if (res) - return res; + if (ret) + goto out; } } - strbuf_release(&rev); flags |= AMEND_MSG; } @@ -5329,18 +5354,29 @@ static int commit_staged_changes(struct repository *r, if (refs_ref_exists(get_main_ref_store(r), "CHERRY_PICK_HEAD") && refs_delete_ref(get_main_ref_store(r), "", - "CHERRY_PICK_HEAD", NULL, REF_NO_DEREF)) - return error(_("could not remove CHERRY_PICK_HEAD")); - if (unlink(git_path_merge_msg(r)) && errno != ENOENT) - return error_errno(_("could not remove '%s'"), - git_path_merge_msg(r)); - if (!final_fixup) - return 0; + "CHERRY_PICK_HEAD", NULL, REF_NO_DEREF)) { + ret = error(_("could not remove CHERRY_PICK_HEAD")); + goto out; + } + + if (unlink(git_path_merge_msg(r)) && errno != ENOENT) { + ret = error_errno(_("could not remove '%s'"), + git_path_merge_msg(r)); + goto out; + } + + if (!final_fixup) { + ret = 0; + goto out; + } } if (run_git_commit(final_fixup ? NULL : rebase_path_message(), - opts, flags)) - return error(_("could not commit staged changes.")); + opts, flags)) { + ret = error(_("could not commit staged changes.")); + goto out; + } + unlink(rebase_path_amend()); unlink(git_path_merge_head(r)); refs_delete_ref(get_main_ref_store(r), "", "AUTO_MERGE", @@ -5358,7 +5394,12 @@ static int commit_staged_changes(struct repository *r, strbuf_reset(&ctx->current_fixups); ctx->current_fixup_count = 0; } - return 0; + + ret = 0; + +out: + strbuf_release(&rev); + return ret; } int sequencer_continue(struct repository *r, struct replay_opts *opts) @@ -5974,6 +6015,9 @@ static int make_script_with_merges(struct pretty_print_context *pp, strbuf_release(&oneline); strbuf_release(&buf); + oidset_clear(&interesting); + oidset_clear(&child_seen); + oidset_clear(&shown); oidmap_free(&commit2todo, 1); oidmap_free(&state.commit2label, 1); hashmap_clear_and_free(&state.labels, struct labels_entry, entry); @@ -6270,10 +6314,11 @@ static int add_decorations_to_list(const struct commit *commit, struct todo_add_branch_context *ctx) { const struct name_decoration *decoration = get_name_decoration(&commit->object); - const char *head_ref = resolve_ref_unsafe("HEAD", - RESOLVE_REF_READING, - NULL, - NULL); + const char *head_ref = refs_resolve_ref_unsafe(get_main_ref_store(the_repository), + "HEAD", + RESOLVE_REF_READING, + NULL, + NULL); while (decoration) { struct todo_item *item; |
