]> git.ipfire.org Git - thirdparty/git.git/blobdiff - sequencer.c
Merge branch 'fr_2.26.0' of github.com:jnavila/git
[thirdparty/git.git] / sequencer.c
index ba90a513b95f1ddd2b53d6eeafd28ef5d49745e6..7477b15422a7a7e42e1406bd7ecf20b458a93658 100644 (file)
@@ -160,6 +160,8 @@ 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 GIT_PATH_FUNC(rebase_path_reschedule_failed_exec, "rebase-merge/reschedule-failed-exec")
+static GIT_PATH_FUNC(rebase_path_drop_redundant_commits, "rebase-merge/drop_redundant_commits")
+static GIT_PATH_FUNC(rebase_path_keep_redundant_commits, "rebase-merge/keep_redundant_commits")
 
 static int git_sequencer_config(const char *k, const char *v, void *cb)
 {
@@ -290,7 +292,7 @@ int sequencer_remove_state(struct replay_opts *opts)
                        char *eol = strchr(p, '\n');
                        if (eol)
                                *eol = '\0';
-                       if (delete_ref("(rebase -i) cleanup", p, NULL, 0) < 0) {
+                       if (delete_ref("(rebase) cleanup", p, NULL, 0) < 0) {
                                warning(_("could not delete '%s'"), p);
                                ret = -1;
                        }
@@ -324,7 +326,7 @@ static const char *action_name(const struct replay_opts *opts)
        case REPLAY_PICK:
                return N_("cherry-pick");
        case REPLAY_INTERACTIVE_REBASE:
-               return N_("rebase -i");
+               return N_("rebase");
        }
        die(_("unknown action: %d"), opts->action);
 }
@@ -628,7 +630,7 @@ static int do_recursive_merge(struct repository *r,
                               COMMIT_LOCK | SKIP_IF_UNCHANGED))
                /*
                 * TRANSLATORS: %s will be "revert", "cherry-pick" or
-                * "rebase -i".
+                * "rebase".
                 */
                return error(_("%s: Unable to write new index file"),
                        _(action_name(opts)));
@@ -1485,23 +1487,30 @@ static int is_original_commit_empty(struct commit *commit)
 }
 
 /*
- * Do we run "git commit" with "--allow-empty"?
+ * Should empty commits be allowed?  Return status:
+ *    <0: Error in is_index_unchanged(r) or is_original_commit_empty(commit)
+ *     0: Halt on empty commit
+ *     1: Allow empty commit
+ *     2: Drop empty commit
  */
 static int allow_empty(struct repository *r,
                       struct replay_opts *opts,
                       struct commit *commit)
 {
-       int index_unchanged, empty_commit;
+       int index_unchanged, originally_empty;
 
        /*
-        * Three cases:
+        * Four cases:
         *
         * (1) we do not allow empty at all and error out.
         *
-        * (2) we allow ones that were initially empty, but
-        * forbid the ones that become empty;
+        * (2) we allow ones that were initially empty, and
+        *     just drop the ones that become empty
         *
-        * (3) we allow both.
+        * (3) we allow ones that were initially empty, but
+        *     halt for the ones that become empty;
+        *
+        * (4) we allow both.
         */
        if (!opts->allow_empty)
                return 0; /* let "git commit" barf as necessary */
@@ -1515,13 +1524,15 @@ static int allow_empty(struct repository *r,
        if (opts->keep_redundant_commits)
                return 1;
 
-       empty_commit = is_original_commit_empty(commit);
-       if (empty_commit < 0)
-               return empty_commit;
-       if (!empty_commit)
-               return 0;
-       else
+       originally_empty = is_original_commit_empty(commit);
+       if (originally_empty < 0)
+               return originally_empty;
+       if (originally_empty)
                return 1;
+       else if (opts->drop_redundant_commits)
+               return 2;
+       else
+               return 0;
 }
 
 static struct {
@@ -1732,7 +1743,7 @@ static int do_pick_commit(struct repository *r,
        char *author = NULL;
        struct commit_message msg = { NULL, NULL, NULL, NULL };
        struct strbuf msgbuf = STRBUF_INIT;
-       int res, unborn = 0, reword = 0, allow;
+       int res, unborn = 0, reword = 0, allow, drop_commit;
 
        if (opts->no_commit) {
                /*
@@ -1937,13 +1948,20 @@ static int do_pick_commit(struct repository *r,
                goto leave;
        }
 
+       drop_commit = 0;
        allow = allow_empty(r, opts, commit);
        if (allow < 0) {
                res = allow;
                goto leave;
-       } else if (allow)
+       } else if (allow == 1) {
                flags |= ALLOW_EMPTY;
-       if (!opts->no_commit) {
+       } else if (allow == 2) {
+               drop_commit = 1;
+               fprintf(stderr,
+                       _("dropping %s %s -- patch contents already upstream\n"),
+                       oid_to_hex(&commit->object.oid), msg.subject);
+       } /* else allow == 0 and there's nothing special to do */
+       if (!opts->no_commit && !drop_commit) {
                if (author || command == TODO_REVERT || (flags & AMEND_MSG))
                        res = do_commit(r, msg_file, author, opts, flags);
                else
@@ -2498,6 +2516,12 @@ static int read_populate_opts(struct replay_opts *opts)
                if (file_exists(rebase_path_reschedule_failed_exec()))
                        opts->reschedule_failed_exec = 1;
 
+               if (file_exists(rebase_path_drop_redundant_commits()))
+                       opts->drop_redundant_commits = 1;
+
+               if (file_exists(rebase_path_keep_redundant_commits()))
+                       opts->keep_redundant_commits = 1;
+
                read_strategy_opts(opts, &buf);
                strbuf_release(&buf);
 
@@ -2549,8 +2573,6 @@ static void write_strategy_opts(struct replay_opts *opts)
 int write_basic_state(struct replay_opts *opts, const char *head_name,
                      struct commit *onto, const char *orig_head)
 {
-       const char *quiet = getenv("GIT_QUIET");
-
        if (head_name)
                write_file(rebase_path_head_name(), "%s\n", head_name);
        if (onto)
@@ -2559,8 +2581,8 @@ int write_basic_state(struct replay_opts *opts, const char *head_name,
        if (orig_head)
                write_file(rebase_path_orig_head(), "%s\n", orig_head);
 
-       if (quiet)
-               write_file(rebase_path_quiet(), "%s\n", quiet);
+       if (opts->quiet)
+               write_file(rebase_path_quiet(), "%s", "");
        if (opts->verbose)
                write_file(rebase_path_verbose(), "%s", "");
        if (opts->strategy)
@@ -2577,6 +2599,10 @@ int write_basic_state(struct replay_opts *opts, const char *head_name,
                write_file(rebase_path_gpg_sign_opt(), "-S%s\n", opts->gpg_sign);
        if (opts->signoff)
                write_file(rebase_path_signoff(), "--signoff\n");
+       if (opts->drop_redundant_commits)
+               write_file(rebase_path_drop_redundant_commits(), "%s", "");
+       if (opts->keep_redundant_commits)
+               write_file(rebase_path_keep_redundant_commits(), "%s", "");
        if (opts->reschedule_failed_exec)
                write_file(rebase_path_reschedule_failed_exec(), "%s", "");
 
@@ -3176,7 +3202,7 @@ static int do_label(struct repository *r, const char *name, int len)
                return error(_("illegal label name: '%.*s'"), len, name);
 
        strbuf_addf(&ref_name, "refs/rewritten/%.*s", len, name);
-       strbuf_addf(&msg, "rebase -i (label) '%.*s'", len, name);
+       strbuf_addf(&msg, "rebase (label) '%.*s'", len, name);
 
        transaction = ref_store_transaction_begin(refs, &err);
        if (!transaction) {
@@ -4563,7 +4589,6 @@ static int make_script_with_merges(struct pretty_print_context *pp,
                                   struct rev_info *revs, struct strbuf *out,
                                   unsigned flags)
 {
-       int keep_empty = flags & TODO_LIST_KEEP_EMPTY;
        int rebase_cousins = flags & TODO_LIST_REBASE_COUSINS;
        int root_with_onto = flags & TODO_LIST_ROOT_WITH_ONTO;
        struct strbuf buf = STRBUF_INIT, oneline = STRBUF_INIT;
@@ -4626,8 +4651,6 @@ static int make_script_with_merges(struct pretty_print_context *pp,
                if (!to_merge) {
                        /* non-merge commit: easy case */
                        strbuf_reset(&buf);
-                       if (!keep_empty && is_empty)
-                               strbuf_addf(&buf, "%c ", comment_line_char);
                        strbuf_addf(&buf, "%s %s %s", cmd_pick,
                                    oid_to_hex(&commit->object.oid),
                                    oneline.buf);
@@ -4794,7 +4817,6 @@ int sequencer_make_script(struct repository *r, struct strbuf *out, int argc,
        struct pretty_print_context pp = {0};
        struct rev_info revs;
        struct commit *commit;
-       int keep_empty = flags & TODO_LIST_KEEP_EMPTY;
        const char *insn = flags & TODO_LIST_ABBREVIATE_CMDS ? "p" : "pick";
        int rebase_merges = flags & TODO_LIST_REBASE_MERGES;
 
@@ -4830,12 +4852,10 @@ int sequencer_make_script(struct repository *r, struct strbuf *out, int argc,
                return make_script_with_merges(&pp, &revs, out, flags);
 
        while ((commit = get_revision(&revs))) {
-               int is_empty  = is_original_commit_empty(commit);
+               int is_empty = is_original_commit_empty(commit);
 
                if (!is_empty && (commit->object.flags & PATCHSAME))
                        continue;
-               if (!keep_empty && is_empty)
-                       strbuf_addf(out, "%c ", comment_line_char);
                strbuf_addf(out, "%s %s ", insn,
                            oid_to_hex(&commit->object.oid));
                pretty_print_commit(&pp, commit, out);
@@ -4972,7 +4992,7 @@ int todo_list_write_to_file(struct repository *r, struct todo_list *todo_list,
 
        todo_list_to_strbuf(r, todo_list, &buf, num, flags);
        if (flags & TODO_LIST_APPEND_TODO_HELP)
-               append_todo_help(flags & TODO_LIST_KEEP_EMPTY, count_commands(todo_list),
+               append_todo_help(count_commands(todo_list),
                                 shortrevisions, shortonto, &buf);
 
        res = write_message(buf.buf, buf.len, file, 0);