Merge branch 'ms/core-icase-doc'
[gitweb.git] / sequencer.c
index ee1f7b2df74572b1bff71436fa7961f47ac25378..03c47405fbf2c1896d4a1d38ef9f204518d7e92d 100644 (file)
@@ -2,6 +2,7 @@
 #include "config.h"
 #include "lockfile.h"
 #include "dir.h"
+#include "object-store.h"
 #include "object.h"
 #include "commit.h"
 #include "sequencer.h"
@@ -176,6 +177,7 @@ static int git_sequencer_config(const char *k, const char *v, void *cb)
                        warning(_("invalid commit message cleanup mode '%s'"),
                                  s);
 
+               free((char *)s);
                return status;
        }
 
@@ -356,7 +358,7 @@ static void print_advice(int show_hint, struct replay_opts *opts)
                 * (typically rebase --interactive) wants to take care
                 * of the commit itself so remove CHERRY_PICK_HEAD
                 */
-               unlink(git_path_cherry_pick_head());
+               unlink(git_path_cherry_pick_head(the_repository));
                return;
        }
 
@@ -1323,8 +1325,8 @@ static int do_commit(const char *msg_file, const char *author,
                                    &oid);
                strbuf_release(&sb);
                if (!res) {
-                       unlink(git_path_cherry_pick_head());
-                       unlink(git_path_merge_msg());
+                       unlink(git_path_cherry_pick_head(the_repository));
+                       unlink(git_path_merge_msg(the_repository));
                        if (!is_rebase_i(opts))
                                print_commit_summary(NULL, &oid,
                                                SUMMARY_SHOW_AUTHOR_DATE);
@@ -1612,7 +1614,7 @@ static int do_pick_commit(enum todo_command command, struct commit *commit,
                struct replay_opts *opts, int final_fixup)
 {
        unsigned int flags = opts->edit ? EDIT_MSG : 0;
-       const char *msg_file = opts->edit ? NULL : git_path_merge_msg();
+       const char *msg_file = opts->edit ? NULL : git_path_merge_msg(the_repository);
        struct object_id head;
        struct commit *base, *next, *parent;
        const char *base_label, *next_label;
@@ -1754,12 +1756,12 @@ static int do_pick_commit(enum todo_command command, struct commit *commit,
                        flags |= CLEANUP_MSG;
                        msg_file = rebase_path_fixup_msg();
                } else {
-                       const char *dest = git_path_squash_msg();
+                       const char *dest = git_path_squash_msg(the_repository);
                        unlink(dest);
                        if (copy_file(dest, rebase_path_squash_msg(), 0666))
                                return error(_("could not rename '%s' to '%s'"),
                                             rebase_path_squash_msg(), dest);
-                       unlink(git_path_merge_msg());
+                       unlink(git_path_merge_msg(the_repository));
                        msg_file = dest;
                        flags |= EDIT_MSG;
                }
@@ -1774,15 +1776,16 @@ static int do_pick_commit(enum todo_command command, struct commit *commit,
                res = do_recursive_merge(base, next, base_label, next_label,
                                         &head, &msgbuf, opts);
                if (res < 0)
-                       return res;
+                       goto leave;
+
                res |= write_message(msgbuf.buf, msgbuf.len,
-                                    git_path_merge_msg(), 0);
+                                    git_path_merge_msg(the_repository), 0);
        } else {
                struct commit_list *common = NULL;
                struct commit_list *remotes = NULL;
 
                res = write_message(msgbuf.buf, msgbuf.len,
-                                   git_path_merge_msg(), 0);
+                                   git_path_merge_msg(the_repository), 0);
 
                commit_list_insert(base, &common);
                commit_list_insert(next, &remotes);
@@ -2204,6 +2207,7 @@ static int populate_opts_cb(const char *key, const char *value, void *data)
 static void read_strategy_opts(struct replay_opts *opts, struct strbuf *buf)
 {
        int i;
+       char *strategy_opts_string;
 
        strbuf_reset(buf);
        if (!read_oneliner(buf, rebase_path_strategy(), 0))
@@ -2212,7 +2216,11 @@ static void read_strategy_opts(struct replay_opts *opts, struct strbuf *buf)
        if (!read_oneliner(buf, rebase_path_strategy_opts(), 0))
                return;
 
-       opts->xopts_nr = split_cmdline(buf->buf, (const char ***)&opts->xopts);
+       strategy_opts_string = buf->buf;
+       if (*strategy_opts_string == ' ')
+               strategy_opts_string++;
+       opts->xopts_nr = split_cmdline(strategy_opts_string,
+                                      (const char ***)&opts->xopts);
        for (i = 0; i < opts->xopts_nr; i++) {
                const char *arg = opts->xopts[i];
 
@@ -2392,8 +2400,8 @@ static int rollback_single_pick(void)
 {
        struct object_id head_oid;
 
-       if (!file_exists(git_path_cherry_pick_head()) &&
-           !file_exists(git_path_revert_head()))
+       if (!file_exists(git_path_cherry_pick_head(the_repository)) &&
+           !file_exists(git_path_revert_head(the_repository)))
                return error(_("no cherry-pick or revert in progress"));
        if (read_ref_full("HEAD", 0, &head_oid, NULL))
                return error(_("cannot resolve HEAD"));
@@ -2618,10 +2626,11 @@ static int error_failed_squash(struct commit *commit,
        if (copy_file(rebase_path_message(), rebase_path_squash_msg(), 0666))
                return error(_("could not copy '%s' to '%s'"),
                        rebase_path_squash_msg(), rebase_path_message());
-       unlink(git_path_merge_msg());
-       if (copy_file(git_path_merge_msg(), rebase_path_message(), 0666))
+       unlink(git_path_merge_msg(the_repository));
+       if (copy_file(git_path_merge_msg(the_repository), rebase_path_message(), 0666))
                return error(_("could not copy '%s' to '%s'"),
-                            rebase_path_message(), git_path_merge_msg());
+                            rebase_path_message(),
+                            git_path_merge_msg(the_repository));
        return error_with_patch(commit, subject, subject_len, opts, 1, 0);
 }
 
@@ -2911,11 +2920,11 @@ static int do_merge(struct commit *commit, const char *arg, int arg_len,
                write_author_script(message);
                find_commit_subject(message, &body);
                len = strlen(body);
-               ret = write_message(body, len, git_path_merge_msg(), 0);
+               ret = write_message(body, len, git_path_merge_msg(the_repository), 0);
                unuse_commit_buffer(commit, message);
                if (ret) {
                        error_errno(_("could not write '%s'"),
-                                   git_path_merge_msg());
+                                   git_path_merge_msg(the_repository));
                        goto leave_merge;
                }
        } else {
@@ -2936,11 +2945,11 @@ static int do_merge(struct commit *commit, const char *arg, int arg_len,
                        len = buf.len;
                }
 
-               ret = write_message(p, len, git_path_merge_msg(), 0);
+               ret = write_message(p, len, git_path_merge_msg(the_repository), 0);
                strbuf_release(&buf);
                if (ret) {
                        error_errno(_("could not write '%s'"),
-                                   git_path_merge_msg());
+                                   git_path_merge_msg(the_repository));
                        goto leave_merge;
                }
        }
@@ -2977,8 +2986,8 @@ static int do_merge(struct commit *commit, const char *arg, int arg_len,
        }
 
        write_message(oid_to_hex(&merge_commit->object.oid), GIT_SHA1_HEXSZ,
-                     git_path_merge_head(), 0);
-       write_message("no-ff", 5, git_path_merge_mode(), 0);
+                     git_path_merge_head(the_repository), 0);
+       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,
@@ -3032,7 +3041,7 @@ static int do_merge(struct commit *commit, const char *arg, int arg_len,
                 * value (a negative one would indicate that the `merge`
                 * command needs to be rescheduled).
                 */
-               ret = !!run_git_commit(git_path_merge_msg(), opts,
+               ret = !!run_git_commit(git_path_merge_msg(the_repository), opts,
                                     run_commit_flags);
 
 leave_merge:
@@ -3215,10 +3224,27 @@ static int pick_commits(struct todo_list *todo_list, struct replay_opts *opts)
                                        intend_to_amend();
                                return error_failed_squash(item->commit, opts,
                                        item->arg_len, item->arg);
-                       } else if (res && is_rebase_i(opts) && item->commit)
+                       } else if (res && is_rebase_i(opts) && item->commit) {
+                               int to_amend = 0;
+                               struct object_id oid;
+
+                               /*
+                                * If we are rewording and have either
+                                * fast-forwarded already, or are about to
+                                * create a new root commit, we want to amend,
+                                * otherwise we do not.
+                                */
+                               if (item->command == TODO_REWORD &&
+                                   !get_oid("HEAD", &oid) &&
+                                   (!oidcmp(&item->commit->object.oid, &oid) ||
+                                    (opts->have_squash_onto &&
+                                     !oidcmp(&opts->squash_onto, &oid))))
+                                       to_amend = 1;
+
                                return res | error_with_patch(item->commit,
-                                       item->arg, item->arg_len, opts, res,
-                                       item->command == TODO_REWORD);
+                                               item->arg, item->arg_len, opts,
+                                               res, to_amend);
+                       }
                } else if (item->command == TODO_EXEC) {
                        char *end_of_arg = (char *)(item->arg + item->arg_len);
                        int saved = *end_of_arg;
@@ -3399,8 +3425,8 @@ static int continue_single_pick(void)
 {
        const char *argv[] = { "commit", NULL };
 
-       if (!file_exists(git_path_cherry_pick_head()) &&
-           !file_exists(git_path_revert_head()))
+       if (!file_exists(git_path_cherry_pick_head(the_repository)) &&
+           !file_exists(git_path_revert_head(the_repository)))
                return error(_("no cherry-pick or revert in progress"));
        return run_command_v_opt(argv, RUN_GIT_CMD);
 }
@@ -3503,7 +3529,7 @@ static int commit_staged_changes(struct replay_opts *opts,
        }
 
        if (is_clean) {
-               const char *cherry_pick_head = git_path_cherry_pick_head();
+               const char *cherry_pick_head = git_path_cherry_pick_head(the_repository);
 
                if (file_exists(cherry_pick_head) && unlink(cherry_pick_head))
                        return error(_("could not remove CHERRY_PICK_HEAD"));
@@ -3553,8 +3579,8 @@ int sequencer_continue(struct replay_opts *opts)
 
        if (!is_rebase_i(opts)) {
                /* Verify that the conflict has been resolved */
-               if (file_exists(git_path_cherry_pick_head()) ||
-                   file_exists(git_path_revert_head())) {
+               if (file_exists(git_path_cherry_pick_head(the_repository)) ||
+                   file_exists(git_path_revert_head(the_repository))) {
                        res = continue_single_pick();
                        if (res)
                                goto release_todo_list;