commit-reach.c: allow merge_bases_many to handle any repo
[gitweb.git] / sequencer.c
index dc2c58d464c14be033f4bcba2ab4332886ead327..0c164d5f98f152156ef21a79159f6348fecb0273 100644 (file)
@@ -30,6 +30,7 @@
 #include "oidset.h"
 #include "commit-slab.h"
 #include "alias.h"
+#include "commit-reach.h"
 
 #define GIT_REFLOG_ACTION "GIT_REFLOG_ACTION"
 
@@ -225,13 +226,16 @@ static const char *get_todo_path(const struct replay_opts *opts)
  * Returns 3 when sob exists within conforming footer as last entry
  */
 static int has_conforming_footer(struct strbuf *sb, struct strbuf *sob,
-       int ignore_footer)
+       size_t ignore_footer)
 {
+       struct process_trailer_options opts = PROCESS_TRAILER_OPTIONS_INIT;
        struct trailer_info info;
-       int i;
+       size_t i;
        int found_sob = 0, found_sob_last = 0;
 
-       trailer_info_get(&info, sb->buf);
+       opts.no_divider = 1;
+
+       trailer_info_get(&info, sb->buf, &opts);
 
        if (info.trailer_start == info.trailer_end)
                return 0;
@@ -470,8 +474,8 @@ static int fast_forward_to(const struct object_id *to, const struct object_id *f
        struct strbuf sb = STRBUF_INIT;
        struct strbuf err = STRBUF_INIT;
 
-       read_cache();
-       if (checkout_fast_forward(from, to, 1))
+       read_index(&the_index);
+       if (checkout_fast_forward(the_repository, from, to, 1))
                return -1; /* the callee should have complained already */
 
        strbuf_addf(&sb, _("%s: fast-forward"), _(action_name(opts)));
@@ -610,7 +614,7 @@ static int is_index_unchanged(void)
        if (!(cache_tree_oid = get_cache_tree_oid()))
                return -1;
 
-       return !oidcmp(cache_tree_oid, get_commit_tree_oid(head_commit));
+       return oideq(cache_tree_oid, get_commit_tree_oid(head_commit));
 }
 
 static int write_author_script(const char *message)
@@ -899,7 +903,7 @@ static int run_git_commit(const char *defmsg, struct replay_opts *opts,
        if ((flags & ALLOW_EMPTY))
                argv_array_push(&cmd.args, "--allow-empty");
 
-       if (opts->allow_empty_message)
+       if (!(flags & EDIT_MSG))
                argv_array_push(&cmd.args, "--allow-empty-message");
 
        if (cmd.err == -1) {
@@ -1172,7 +1176,7 @@ void print_commit_summary(const char *prefix, const struct object_id *oid,
        strbuf_release(&author_ident);
        strbuf_release(&committer_ident);
 
-       init_revisions(&rev, prefix);
+       repo_init_revisions(the_repository, &rev, prefix);
        setup_revisions(0, NULL, &rev, NULL);
 
        rev.diff = 1;
@@ -1217,7 +1221,7 @@ static int parse_head(struct commit **head)
                current_head = lookup_commit_reference(the_repository, &oid);
                if (!current_head)
                        return error(_("could not parse HEAD"));
-               if (oidcmp(&oid, &current_head->object.oid)) {
+               if (!oideq(&oid, &current_head->object.oid)) {
                        warning(_("HEAD %s is not a commit!"),
                                oid_to_hex(&oid));
                }
@@ -1287,9 +1291,9 @@ static int try_to_commit(struct strbuf *msg, const char *author,
                goto out;
        }
 
-       if (!(flags & ALLOW_EMPTY) && !oidcmp(current_head ?
-                                             get_commit_tree_oid(current_head) :
-                                             the_hash_algo->empty_tree, &tree)) {
+       if (!(flags & ALLOW_EMPTY) && oideq(current_head ?
+                                           get_commit_tree_oid(current_head) :
+                                           the_hash_algo->empty_tree, &tree)) {
                res = 1; /* run 'git commit' to display error message */
                goto out;
        }
@@ -1313,7 +1317,7 @@ static int try_to_commit(struct strbuf *msg, const char *author,
 
        if (cleanup != COMMIT_MSG_CLEANUP_NONE)
                strbuf_stripspace(msg, cleanup == COMMIT_MSG_CLEANUP_ALL);
-       if (!opts->allow_empty_message && message_is_empty(msg, cleanup)) {
+       if ((flags & EDIT_MSG) && message_is_empty(msg, cleanup)) {
                res = 1; /* run 'git commit' to display error message */
                goto out;
        }
@@ -1394,7 +1398,7 @@ static int is_original_commit_empty(struct commit *commit)
                ptree_oid = the_hash_algo->empty_tree; /* commit is root */
        }
 
-       return !oidcmp(ptree_oid, get_commit_tree_oid(commit));
+       return oideq(ptree_oid, get_commit_tree_oid(commit));
 }
 
 /*
@@ -1674,7 +1678,7 @@ static int do_pick_commit(enum todo_command command, struct commit *commit,
                unborn = get_oid("HEAD", &head);
                /* Do we want to generate a root commit? */
                if (is_pick_or_similar(command) && opts->have_squash_onto &&
-                   !oidcmp(&head, &opts->squash_onto)) {
+                   oideq(&head, &opts->squash_onto)) {
                        if (is_fixup(command))
                                return error(_("cannot fixup root commit"));
                        flags |= CREATE_ROOT_COMMIT;
@@ -1717,7 +1721,7 @@ static int do_pick_commit(enum todo_command command, struct commit *commit,
                        oid_to_hex(&commit->object.oid));
 
        if (opts->allow_ff && !is_fixup(command) &&
-           ((parent && !oidcmp(&parent->object.oid, &head)) ||
+           ((parent && oideq(&parent->object.oid, &head)) ||
             (!parent && unborn))) {
                if (is_rebase_i(opts))
                        write_author_script(msg.message);
@@ -1827,7 +1831,7 @@ static int do_pick_commit(enum todo_command command, struct commit *commit,
 
                commit_list_insert(base, &common);
                commit_list_insert(next, &remotes);
-               res |= try_merge_command(opts->strategy,
+               res |= try_merge_command(the_repository, opts->strategy,
                                         opts->xopts_nr, (const char **)opts->xopts,
                                        common, oid_to_hex(&head), remotes);
                free_commit_list(common);
@@ -1856,7 +1860,7 @@ static int do_pick_commit(enum todo_command command, struct commit *commit,
                      : _("could not apply %s... %s"),
                      short_commit_name(commit), msg.subject);
                print_advice(res == 1, opts);
-               rerere(opts->allow_rerere_auto);
+               repo_rerere(the_repository, opts->allow_rerere_auto);
                goto leave;
        }
 
@@ -1909,7 +1913,7 @@ static int read_and_refresh_cache(struct replay_opts *opts)
 {
        struct lock_file index_lock = LOCK_INIT;
        int index_fd = hold_locked_index(&index_lock, 0);
-       if (read_index_preload(&the_index, NULL) < 0) {
+       if (read_index_preload(&the_index, NULL, 0) < 0) {
                rollback_lock_file(&index_lock);
                return error(_("git %s: failed to read the index"),
                        _(action_name(opts)));
@@ -2422,7 +2426,7 @@ static int rollback_is_safe(void)
        if (get_oid("HEAD", &actual_head))
                oidclr(&actual_head);
 
-       return !oidcmp(&actual_head, &expected_head);
+       return oideq(&actual_head, &expected_head);
 }
 
 static int reset_for_rollback(const struct object_id *oid)
@@ -2595,7 +2599,7 @@ static int make_patch(struct commit *commit, struct replay_opts *opts)
 
        strbuf_addf(&buf, "%s/patch", get_dir(opts));
        memset(&log_tree_opt, 0, sizeof(log_tree_opt));
-       init_revisions(&log_tree_opt, NULL);
+       repo_init_revisions(the_repository, &log_tree_opt, NULL);
        log_tree_opt.abbrev = 0;
        log_tree_opt.diff = 1;
        log_tree_opt.diffopt.output_format = DIFF_FORMAT_PATCH;
@@ -2983,7 +2987,7 @@ static int do_merge(struct commit *commit, const char *arg, int arg_len,
        }
 
        if (opts->have_squash_onto &&
-           !oidcmp(&head_commit->object.oid, &opts->squash_onto)) {
+           oideq(&head_commit->object.oid, &opts->squash_onto)) {
                /*
                 * When the user tells us to "merge" something into a
                 * "[new root]", let's simply fast-forward to the merge head.
@@ -3052,8 +3056,8 @@ static int do_merge(struct commit *commit, const char *arg, int arg_len,
         * commit, we cannot fast-forward.
         */
        can_fast_forward = opts->allow_ff && commit && commit->parents &&
-               !oidcmp(&commit->parents->item->object.oid,
-                       &head_commit->object.oid);
+               oideq(&commit->parents->item->object.oid,
+                     &head_commit->object.oid);
 
        /*
         * If any merge head is different from the original one, we cannot
@@ -3063,7 +3067,7 @@ static int do_merge(struct commit *commit, const char *arg, int arg_len,
                struct commit_list *p = commit->parents->next;
 
                for (j = to_merge; j && p; j = j->next, p = p->next)
-                       if (oidcmp(&j->item->object.oid,
+                       if (!oideq(&j->item->object.oid,
                                   &p->item->object.oid)) {
                                can_fast_forward = 0;
                                break;
@@ -3131,8 +3135,8 @@ static int do_merge(struct commit *commit, const char *arg, int arg_len,
        write_message("no-ff", 5, git_path_merge_mode(the_repository), 0);
 
        bases = get_merge_bases(head_commit, merge_commit);
-       if (bases && !oidcmp(&merge_commit->object.oid,
-                            &bases->item->object.oid)) {
+       if (bases && oideq(&merge_commit->object.oid,
+                          &bases->item->object.oid)) {
                ret = 0;
                /* skip merging an ancestor of HEAD */
                goto leave_merge;
@@ -3175,7 +3179,7 @@ static int do_merge(struct commit *commit, const char *arg, int arg_len,
 
        rollback_lock_file(&lock);
        if (ret)
-               rerere(opts->allow_rerere_auto);
+               repo_rerere(the_repository, opts->allow_rerere_auto);
        else
                /*
                 * In case of problems, we now want to return a positive
@@ -3378,9 +3382,9 @@ static int pick_commits(struct todo_list *todo_list, struct replay_opts *opts)
                                 */
                                if (item->command == TODO_REWORD &&
                                    !get_oid("HEAD", &oid) &&
-                                   (!oidcmp(&item->commit->object.oid, &oid) ||
+                                   (oideq(&item->commit->object.oid, &oid) ||
                                     (opts->have_squash_onto &&
-                                     !oidcmp(&opts->squash_onto, &oid))))
+                                     oideq(&opts->squash_onto, &oid))))
                                        to_amend = 1;
 
                                return res | error_with_patch(item->commit,
@@ -3506,7 +3510,7 @@ static int pick_commits(struct todo_list *todo_list, struct replay_opts *opts)
                        struct object_id orig, head;
 
                        memset(&log_tree_opt, 0, sizeof(log_tree_opt));
-                       init_revisions(&log_tree_opt, NULL);
+                       repo_init_revisions(the_repository, &log_tree_opt, NULL);
                        log_tree_opt.diff = 1;
                        log_tree_opt.diffopt.output_format =
                                DIFF_FORMAT_DIFFSTAT;
@@ -3595,7 +3599,7 @@ static int commit_staged_changes(struct replay_opts *opts,
                if (get_oid_hex(rev.buf, &to_amend))
                        return error(_("invalid contents: '%s'"),
                                rebase_path_amend());
-               if (!is_clean && oidcmp(&head, &to_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 "
@@ -3607,9 +3611,20 @@ static int commit_staged_changes(struct replay_opts *opts,
                 * the commit message and if there was a squash, let the user
                 * edit it.
                 */
-               if (is_clean && !oidcmp(&head, &to_amend) &&
-                   opts->current_fixup_count > 0 &&
-                   file_exists(rebase_path_stopped_sha())) {
+               if (!is_clean || !opts->current_fixup_count)
+                       ; /* this is not the final fixup */
+               else if (!oideq(&head, &to_amend) ||
+                        !file_exists(rebase_path_stopped_sha())) {
+                       /* was a final fixup or squash done manually? */
+                       if (!is_fixup(peek_command(todo_list, 0))) {
+                               unlink(rebase_path_fixup_msg());
+                               unlink(rebase_path_squash_msg());
+                               unlink(rebase_path_current_fixups());
+                               strbuf_reset(&opts->current_fixups);
+                               opts->current_fixup_count = 0;
+                       }
+               } else {
+                       /* we are in a fixup/squash chain */
                        const char *p = opts->current_fixups.buf;
                        int len = opts->current_fixups.len;
 
@@ -3828,7 +3843,7 @@ int sequencer_pick_revisions(struct replay_opts *opts)
        return res;
 }
 
-void append_signoff(struct strbuf *msgbuf, int ignore_footer, unsigned flag)
+void append_signoff(struct strbuf *msgbuf, size_t ignore_footer, unsigned flag)
 {
        unsigned no_dup_sob = flag & APPEND_SIGNOFF_DEDUP;
        struct strbuf sob = STRBUF_INIT;
@@ -4131,9 +4146,7 @@ static int make_script_with_merges(struct pretty_print_context *pp,
                        struct object_id *oid = &parent->item->object.oid;
                        if (!oidset_contains(&interesting, oid))
                                continue;
-                       if (!oidset_contains(&child_seen, oid))
-                               oidset_insert(&child_seen, oid);
-                       else
+                       if (oidset_insert(&child_seen, oid))
                                label_oid(oid, "branch-point", &state);
                }
 
@@ -4241,7 +4254,7 @@ int sequencer_make_script(FILE *out, int argc, const char **argv,
        const char *insn = flags & TODO_LIST_ABBREVIATE_CMDS ? "p" : "pick";
        int rebase_merges = flags & TODO_LIST_REBASE_MERGES;
 
-       init_revisions(&revs, NULL);
+       repo_init_revisions(the_repository, &revs, NULL);
        revs.verbose_header = 1;
        if (!rebase_merges)
                revs.max_parents = 1;
@@ -4574,7 +4587,7 @@ int skip_unnecessary_picks(void)
                if (item->commit->parents->next)
                        break; /* merge commit */
                parent_oid = &item->commit->parents->item->object.oid;
-               if (hashcmp(parent_oid->hash, oid->hash))
+               if (!oideq(parent_oid, oid))
                        break;
                oid = &item->commit->object.oid;
        }