Merge branch 'js/rebase-stat-unrelated-fix'
authorJunio C Hamano <gitster@pobox.com>
Sat, 1 Dec 2018 12:41:42 +0000 (21:41 +0900)
committerJunio C Hamano <gitster@pobox.com>
Sat, 1 Dec 2018 12:41:42 +0000 (21:41 +0900)
"git rebase --stat" to transplant a piece of history onto a totally
unrelated history were not working before and silently showed wrong
result. With the recent reimplementation in C, it started to instead
die with an error message, as the original logic was not prepared
to cope with this case. This has now been fixed.

* js/rebase-stat-unrelated-fix:
rebase --stat: fix when rebasing to an unrelated history

Documentation/git-format-patch.txt
builtin/log.c
builtin/rebase.c
log-tree.c
range-diff.c
range-diff.h
t/t3406-rebase-message.sh
index aba4c5febeb7ef4248d50a638d0a8bd58f7d553b..27304428a12ce9d0ee46e10e3c63069b4677838a 100644 (file)
@@ -250,6 +250,11 @@ feeding the result to `git send-email`.
        feature/v2`), or a revision range if the two versions of the series are
        disjoint (for example `git format-patch --cover-letter
        --range-diff=feature/v1~3..feature/v1 -3 feature/v2`).
++
+Note that diff options passed to the command affect how the primary
+product of `format-patch` is generated, and they are not passed to
+the underlying `range-diff` machinery used to generate the cover-letter
+material (this may change in the future).
 
 --creation-factor=<percent>::
        Used with `--range-diff`, tweak the heuristic which matches up commits
index 0fe6f9ba1e94ec496f2e083ca964592272d898f2..5ac18e28486b61b91239d859c445bc620c51c5ad 100644 (file)
@@ -1096,7 +1096,7 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,
        if (rev->rdiff1) {
                fprintf_ln(rev->diffopt.file, "%s", rev->rdiff_title);
                show_range_diff(rev->rdiff1, rev->rdiff2,
-                               rev->creation_factor, 1, &rev->diffopt);
+                               rev->creation_factor, 1, NULL);
        }
 }
 
index 1c6f817f4b7197114729a367c97d1950ac3080a5..c87da417fb387570bd3af27e0f5479b628012953 100644 (file)
@@ -776,6 +776,23 @@ static void NORETURN error_on_missing_default_upstream(void)
        exit(1);
 }
 
+static void set_reflog_action(struct rebase_options *options)
+{
+       const char *env;
+       struct strbuf buf = STRBUF_INIT;
+
+       if (!is_interactive(options))
+               return;
+
+       env = getenv(GIT_REFLOG_ACTION_ENVIRONMENT);
+       if (env && strcmp("rebase", env))
+               return; /* only override it if it is "rebase" */
+
+       strbuf_addf(&buf, "rebase -i (%s)", options->action);
+       setenv(GIT_REFLOG_ACTION_ENVIRONMENT, buf.buf, 1);
+       strbuf_release(&buf);
+}
+
 int cmd_rebase(int argc, const char **argv, const char *prefix)
 {
        struct rebase_options options = {
@@ -978,6 +995,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
 
        if (action != NO_ACTION && !in_progress)
                die(_("No rebase in progress?"));
+       setenv(GIT_REFLOG_ACTION_ENVIRONMENT, "rebase", 0);
 
        if (action == ACTION_EDIT_TODO && !is_interactive(&options))
                die(_("The --edit-todo action can only be used during "
@@ -990,6 +1008,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
                int fd;
 
                options.action = "continue";
+               set_reflog_action(&options);
 
                /* Sanity check */
                if (get_oid("HEAD", &head))
@@ -1018,6 +1037,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
                struct string_list merge_rr = STRING_LIST_INIT_DUP;
 
                options.action = "skip";
+               set_reflog_action(&options);
 
                rerere_clear(&merge_rr);
                string_list_clear(&merge_rr, 1);
@@ -1033,6 +1053,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
        case ACTION_ABORT: {
                struct string_list merge_rr = STRING_LIST_INIT_DUP;
                options.action = "abort";
+               set_reflog_action(&options);
 
                rerere_clear(&merge_rr);
                string_list_clear(&merge_rr, 1);
@@ -1440,11 +1461,12 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
                                }
 
                                strbuf_reset(&buf);
-                               strbuf_addf(&buf, "rebase: checkout %s",
+                               strbuf_addf(&buf, "%s: checkout %s",
+                                           getenv(GIT_REFLOG_ACTION_ENVIRONMENT),
                                            options.switch_to);
                                if (reset_head(&oid, "checkout",
                                               options.head_name, 0,
-                                              NULL, NULL) < 0) {
+                                              NULL, buf.buf) < 0) {
                                        ret = !!error(_("could not switch to "
                                                        "%s"),
                                                      options.switch_to);
@@ -1514,7 +1536,8 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
                printf(_("First, rewinding head to replay your work on top of "
                         "it...\n"));
 
-       strbuf_addf(&msg, "rebase: checkout %s", options.onto_name);
+       strbuf_addf(&msg, "%s: checkout %s",
+                   getenv(GIT_REFLOG_ACTION_ENVIRONMENT), options.onto_name);
        if (reset_head(&options.onto->object.oid, "checkout", NULL,
                       RESET_HEAD_DETACH, NULL, msg.buf))
                die(_("Could not detach HEAD"));
index 7a83e99250c5245bbbbd43908f3c116567f39b62..b243779a0b7dc15200689febe68549a85ce5c6a7 100644 (file)
@@ -762,7 +762,7 @@ void show_log(struct rev_info *opt)
                next_commentary_block(opt, NULL);
                fprintf_ln(opt->diffopt.file, "%s", opt->rdiff_title);
                show_range_diff(opt->rdiff1, opt->rdiff2,
-                               opt->creation_factor, 1, &opt->diffopt);
+                               opt->creation_factor, 1, NULL);
 
                memcpy(&diff_queued_diff, &dq, sizeof(diff_queued_diff));
        }
index 767af8c5bb5617016ba2c341334c05696fdcbcc1..48b0e1b4ce0ff69b9c7a430174db25b1ca6494f8 100644 (file)
@@ -460,7 +460,11 @@ int show_range_diff(const char *range1, const char *range2,
                struct diff_options opts;
                struct strbuf indent = STRBUF_INIT;
 
-               memcpy(&opts, diffopt, sizeof(opts));
+               if (diffopt)
+                       memcpy(&opts, diffopt, sizeof(opts));
+               else
+                       diff_setup(&opts);
+
                if (!opts.output_format)
                        opts.output_format = DIFF_FORMAT_PATCH;
                opts.flags.suppress_diff_headers = 1;
index 190593f0c78151c99cc6e87161137b99c2615c80..08a50b6e98fc768f42e48b33c70ffbf17a7e8e4c 100644 (file)
@@ -5,6 +5,11 @@
 
 #define RANGE_DIFF_CREATION_FACTOR_DEFAULT 60
 
+/*
+ * Compare series of commmits in RANGE1 and RANGE2, and emit to the
+ * standard output.  NULL can be passed to DIFFOPT to use the built-in
+ * default.
+ */
 int show_range_diff(const char *range1, const char *range2,
                    int creation_factor, int dual_color,
                    struct diff_options *diffopt);
index c2c9950568f27e17d49d166c647dfc8794dd1a35..f64b130cb805bbca8475f3c262693fa0faa2cafe 100755 (executable)
@@ -91,6 +91,32 @@ test_expect_success 'error out early upon -C<n> or --whitespace=<bad>' '
        test_i18ngrep "Invalid whitespace option" err
 '
 
+test_expect_success 'GIT_REFLOG_ACTION' '
+       git checkout start &&
+       test_commit reflog-onto &&
+       git checkout -b reflog-topic start &&
+       test_commit reflog-to-rebase &&
+
+       git rebase reflog-onto &&
+       git log -g --format=%gs -3 >actual &&
+       cat >expect <<-\EOF &&
+       rebase finished: returning to refs/heads/reflog-topic
+       rebase: reflog-to-rebase
+       rebase: checkout reflog-onto
+       EOF
+       test_cmp expect actual &&
+
+       git checkout -b reflog-prefix reflog-to-rebase &&
+       GIT_REFLOG_ACTION=change-the-reflog git rebase reflog-onto &&
+       git log -g --format=%gs -3 >actual &&
+       cat >expect <<-\EOF &&
+       rebase finished: returning to refs/heads/reflog-prefix
+       change-the-reflog: reflog-to-rebase
+       change-the-reflog: checkout reflog-onto
+       EOF
+       test_cmp expect actual
+'
+
 test_expect_success 'rebase -i onto unrelated history' '
        git init unrelated &&
        test_commit -C unrelated 1 &&