Merge branch 'pw/sequence-rerere-autoupdate' into maint
authorJunio C Hamano <gitster@pobox.com>
Sun, 10 Sep 2017 08:02:49 +0000 (17:02 +0900)
committerJunio C Hamano <gitster@pobox.com>
Sun, 10 Sep 2017 08:02:49 +0000 (17:02 +0900)
Commands like "git rebase" accepted the --rerere-autoupdate option
from the command line, but did not always use it. This has been
fixed.

* pw/sequence-rerere-autoupdate:
cherry-pick/revert: reject --rerere-autoupdate when continuing
cherry-pick/revert: remember --rerere-autoupdate
t3504: use test_commit
rebase -i: honor --rerere-autoupdate
rebase: honor --rerere-autoupdate
am: remember --rerere-autoupdate setting

builtin/am.c
builtin/revert.c
git-rebase--am.sh
git-rebase--interactive.sh
sequencer.c
t/t3418-rebase-continue.sh
t/t3504-cherry-pick-rerere.sh
index c973bd96dcb5d630d56e935733bfa4530ccd2872..6962d4db5ffceef3022b7f877a43c8833a839b31 100644 (file)
@@ -431,6 +431,14 @@ static void am_load(struct am_state *state)
        read_state_file(&sb, state, "utf8", 1);
        state->utf8 = !strcmp(sb.buf, "t");
 
+       if (file_exists(am_path(state, "rerere-autoupdate"))) {
+               read_state_file(&sb, state, "rerere-autoupdate", 1);
+               state->allow_rerere_autoupdate = strcmp(sb.buf, "t") ?
+                       RERERE_NOAUTOUPDATE : RERERE_AUTOUPDATE;
+       } else {
+               state->allow_rerere_autoupdate = 0;
+       }
+
        read_state_file(&sb, state, "keep", 1);
        if (!strcmp(sb.buf, "t"))
                state->keep = KEEP_TRUE;
@@ -1003,6 +1011,10 @@ static void am_setup(struct am_state *state, enum patch_format patch_format,
        write_state_bool(state, "sign", state->signoff);
        write_state_bool(state, "utf8", state->utf8);
 
+       if (state->allow_rerere_autoupdate)
+               write_state_bool(state, "rerere-autoupdate",
+                        state->allow_rerere_autoupdate == RERERE_AUTOUPDATE);
+
        switch (state->keep) {
        case KEEP_FALSE:
                str = "f";
index 16028b9ea82edee9cf41044c69a47e8994d78fc6..b9d927eb09c9ed87c84681df1396f4e6d9b13c97 100644 (file)
@@ -155,6 +155,8 @@ static int run_sequencer(int argc, const char **argv, struct replay_opts *opts)
                                "--strategy-option", opts->xopts ? 1 : 0,
                                "-x", opts->record_origin,
                                "--ff", opts->allow_ff,
+                               "--rerere-autoupdate", opts->allow_rerere_auto == RERERE_AUTOUPDATE,
+                               "--no-rerere-autoupdate", opts->allow_rerere_auto == RERERE_NOAUTOUPDATE,
                                NULL);
        }
 
index 375239341fbfe885e51a25e9e0dc2d4fee791345..319933e70a34f9da4ec93d063eb102eff33b6787 100644 (file)
@@ -45,7 +45,7 @@ then
        # itself well to recording empty patches.  fortunately, cherry-pick
        # makes this easy
        git cherry-pick ${gpg_sign_opt:+"$gpg_sign_opt"} --allow-empty \
-               --right-only "$revisions" \
+               $allow_rerere_autoupdate --right-only "$revisions" \
                ${restrict_revision+^$restrict_revision}
        ret=$?
 else
@@ -82,6 +82,7 @@ else
        fi
 
        git am $git_am_opt --rebasing --resolvemsg="$resolvemsg" \
+               $allow_rerere_autoupdate \
                ${gpg_sign_opt:+"$gpg_sign_opt"} <"$GIT_DIR/rebased-patches"
        ret=$?
 
index 90b1fbe9cf6e8dfb2f4331916809fa40bf9050d2..29b7e8824b53abeaa68780b95d5954f67f734098 100644 (file)
@@ -281,7 +281,7 @@ pick_one () {
 
        test -d "$rewritten" &&
                pick_one_preserving_merges "$@" && return
-       output eval git cherry-pick \
+       output eval git cherry-pick $allow_rerere_autoupdate \
                        ${gpg_sign_opt:+$(git rev-parse --sq-quote "$gpg_sign_opt")} \
                        "$strategy_args" $empty_args $ff "$@"
 
@@ -393,7 +393,8 @@ pick_one_preserving_merges () {
                        merge_args="--no-log --no-ff"
                        if ! do_with_author output eval \
                        'git merge ${gpg_sign_opt:+"$gpg_sign_opt"} \
-                               $merge_args $strategy_args -m "$msg_content" $new_parents'
+                               $allow_rerere_autoupdate $merge_args \
+                               $strategy_args -m "$msg_content" $new_parents'
                        then
                                printf "%s\n" "$msg_content" > "$GIT_DIR"/MERGE_MSG
                                die_with_patch $sha1 "$(eval_gettext "Error redoing merge \$sha1")"
@@ -401,7 +402,7 @@ pick_one_preserving_merges () {
                        echo "$sha1 $(git rev-parse HEAD^0)" >> "$rewritten_list"
                        ;;
                *)
-                       output eval git cherry-pick \
+                       output eval git cherry-pick $allow_rerere_autoupdate \
                                ${gpg_sign_opt:+$(git rev-parse --sq-quote "$gpg_sign_opt")} \
                                "$strategy_args" "$@" ||
                                die_with_patch $sha1 "$(eval_gettext "Could not pick \$sha1")"
index 3010faf86398697469e903318a35421d911acb23..e0e66b987b27072da4aea6304a565ab708be91e4 100644 (file)
@@ -127,6 +127,7 @@ static GIT_PATH_FUNC(rebase_path_onto, "rebase-merge/onto")
 static GIT_PATH_FUNC(rebase_path_autostash, "rebase-merge/autostash")
 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 inline int is_rebase_i(const struct replay_opts *opts)
 {
@@ -1438,7 +1439,11 @@ static int populate_opts_cb(const char *key, const char *value, void *data)
        else if (!strcmp(key, "options.strategy-option")) {
                ALLOC_GROW(opts->xopts, opts->xopts_nr + 1, opts->xopts_alloc);
                opts->xopts[opts->xopts_nr++] = xstrdup(value);
-       } else
+       } else if (!strcmp(key, "options.allow-rerere-auto"))
+               opts->allow_rerere_auto =
+                       git_config_bool_or_int(key, value, &error_flag) ?
+                               RERERE_AUTOUPDATE : RERERE_NOAUTOUPDATE;
+       else
                return error(_("invalid key: %s"), key);
 
        if (!error_flag)
@@ -1479,6 +1484,15 @@ static int read_populate_opts(struct replay_opts *opts)
                                free(opts->gpg_sign);
                                opts->gpg_sign = xstrdup(buf.buf + 2);
                        }
+                       strbuf_reset(&buf);
+               }
+
+               if (read_oneliner(&buf, rebase_path_allow_rerere_autoupdate(), 1)) {
+                       if (!strcmp(buf.buf, "--rerere-autoupdate"))
+                               opts->allow_rerere_auto = RERERE_AUTOUPDATE;
+                       else if (!strcmp(buf.buf, "--no-rerere-autoupdate"))
+                               opts->allow_rerere_auto = RERERE_NOAUTOUPDATE;
+                       strbuf_reset(&buf);
                }
 
                if (file_exists(rebase_path_verbose()))
@@ -1742,6 +1756,10 @@ static int save_opts(struct replay_opts *opts)
                                                        "options.strategy-option",
                                                        opts->xopts[i], "^$", 0);
        }
+       if (opts->allow_rerere_auto)
+               res |= git_config_set_in_file_gently(opts_file, "options.allow-rerere-auto",
+                                                    opts->allow_rerere_auto == RERERE_AUTOUPDATE ?
+                                                    "true" : "false");
        return res;
 }
 
index 4428b9086e8bcb383df801834d0de323f316f4fa..fcfdd197bd352a9dca10233c2ba6d2aa4a66149e 100755 (executable)
@@ -40,25 +40,6 @@ test_expect_success 'non-interactive rebase --continue works with touched file'
        git rebase --continue
 '
 
-test_expect_success 'non-interactive rebase --continue with rerere enabled' '
-       test_config rerere.enabled true &&
-       test_when_finished "test_might_fail git rebase --abort" &&
-       git reset --hard commit-new-file-F2-on-topic-branch &&
-       git checkout master &&
-       rm -fr .git/rebase-* &&
-
-       test_must_fail git rebase --onto master master topic &&
-       echo "Resolved" >F2 &&
-       git add F2 &&
-       cp F2 F2.expected &&
-       git rebase --continue &&
-
-       git reset --hard commit-new-file-F2-on-topic-branch &&
-       git checkout master &&
-       test_must_fail git rebase --onto master master topic &&
-       test_cmp F2.expected F2
-'
-
 test_expect_success 'rebase --continue can not be used with other options' '
        test_must_fail git rebase -v --continue &&
        test_must_fail git rebase --continue -v
@@ -93,25 +74,75 @@ test_expect_success 'rebase --continue remembers merge strategy and options' '
        test -f funny.was.run
 '
 
-test_expect_success 'rebase --continue remembers --rerere-autoupdate' '
+test_expect_success 'setup rerere database' '
        rm -fr .git/rebase-* &&
        git reset --hard commit-new-file-F3-on-topic-branch &&
        git checkout master &&
        test_commit "commit-new-file-F3" F3 3 &&
-       git config rerere.enabled true &&
+       test_config rerere.enabled true &&
        test_must_fail git rebase -m master topic &&
        echo "Resolved" >F2 &&
+       cp F2 expected-F2 &&
        git add F2 &&
        test_must_fail git rebase --continue &&
        echo "Resolved" >F3 &&
+       cp F3 expected-F3 &&
        git add F3 &&
        git rebase --continue &&
-       git reset --hard topic@{1} &&
-       test_must_fail git rebase -m --rerere-autoupdate master &&
-       test "$(cat F2)" = "Resolved" &&
-       test_must_fail git rebase --continue &&
-       test "$(cat F3)" = "Resolved" &&
-       git rebase --continue
+       git reset --hard topic@{1}
 '
 
+prepare () {
+       rm -fr .git/rebase-* &&
+       git reset --hard commit-new-file-F3-on-topic-branch &&
+       git checkout master &&
+       test_config rerere.enabled true
+}
+
+test_rerere_autoupdate () {
+       action=$1 &&
+       test_expect_success "rebase $action --continue remembers --rerere-autoupdate" '
+               prepare &&
+               test_must_fail git rebase $action --rerere-autoupdate master topic &&
+               test_cmp expected-F2 F2 &&
+               git diff-files --quiet &&
+               test_must_fail git rebase --continue &&
+               test_cmp expected-F3 F3 &&
+               git diff-files --quiet &&
+               git rebase --continue
+       '
+
+       test_expect_success "rebase $action --continue honors rerere.autoUpdate" '
+               prepare &&
+               test_config rerere.autoupdate true &&
+               test_must_fail git rebase $action master topic &&
+               test_cmp expected-F2 F2 &&
+               git diff-files --quiet &&
+               test_must_fail git rebase --continue &&
+               test_cmp expected-F3 F3 &&
+               git diff-files --quiet &&
+               git rebase --continue
+       '
+
+       test_expect_success "rebase $action --continue remembers --no-rerere-autoupdate" '
+               prepare &&
+               test_config rerere.autoupdate true &&
+               test_must_fail git rebase $action --no-rerere-autoupdate master topic &&
+               test_cmp expected-F2 F2 &&
+               test_must_fail git diff-files --quiet &&
+               git add F2 &&
+               test_must_fail git rebase --continue &&
+               test_cmp expected-F3 F3 &&
+               test_must_fail git diff-files --quiet &&
+               git add F3 &&
+               git rebase --continue
+       '
+}
+
+test_rerere_autoupdate
+test_rerere_autoupdate -m
+GIT_SEQUENCE_EDITOR=: && export GIT_SEQUENCE_EDITOR
+test_rerere_autoupdate -i
+test_rerere_autoupdate --preserve-merges
+
 test_done
index e6a64816efef0e53018c7a56784d1af62602e9d3..a267b2d144df4a84f18ba4907b317e757ba98f16 100755 (executable)
@@ -5,14 +5,13 @@ test_description='cherry-pick should rerere for conflicts'
 . ./test-lib.sh
 
 test_expect_success setup '
-       echo foo >foo &&
-       git add foo && test_tick && git commit -q -m 1 &&
-       echo foo-master >foo &&
-       git add foo && test_tick && git commit -q -m 2 &&
-
-       git checkout -b dev HEAD^ &&
-       echo foo-dev >foo &&
-       git add foo && test_tick && git commit -q -m 3 &&
+       test_commit foo &&
+       test_commit foo-master foo &&
+       test_commit bar-master bar &&
+
+       git checkout -b dev foo &&
+       test_commit foo-dev foo &&
+       test_commit bar-dev bar &&
        git config rerere.enabled true
 '
 
@@ -21,23 +20,80 @@ test_expect_success 'conflicting merge' '
 '
 
 test_expect_success 'fixup' '
-       echo foo-dev >foo &&
-       git add foo && test_tick && git commit -q -m 4 &&
-       git reset --hard HEAD^ &&
-       echo foo-dev >expect
+       echo foo-resolved >foo &&
+       echo bar-resolved >bar &&
+       git commit -am resolved &&
+       cp foo foo-expect &&
+       cp bar bar-expect &&
+       git reset --hard HEAD^
 '
 
-test_expect_success 'cherry-pick conflict' '
-       test_must_fail git cherry-pick master &&
-       test_cmp expect foo
+test_expect_success 'cherry-pick conflict with --rerere-autoupdate' '
+       test_must_fail git cherry-pick --rerere-autoupdate foo..bar-master &&
+       test_cmp foo-expect foo &&
+       git diff-files --quiet &&
+       test_must_fail git cherry-pick --continue &&
+       test_cmp bar-expect bar &&
+       git diff-files --quiet &&
+       git cherry-pick --continue &&
+       git reset --hard bar-dev
+'
+
+test_expect_success 'cherry-pick conflict repsects rerere.autoUpdate' '
+       test_config rerere.autoUpdate true &&
+       test_must_fail git cherry-pick foo..bar-master &&
+       test_cmp foo-expect foo &&
+       git diff-files --quiet &&
+       test_must_fail git cherry-pick --continue &&
+       test_cmp bar-expect bar &&
+       git diff-files --quiet &&
+       git cherry-pick --continue &&
+       git reset --hard bar-dev
+'
+
+test_expect_success 'cherry-pick conflict with --no-rerere-autoupdate' '
+       test_config rerere.autoUpdate true &&
+       test_must_fail git cherry-pick --no-rerere-autoupdate foo..bar-master &&
+       test_cmp foo-expect foo &&
+       test_must_fail git diff-files --quiet &&
+       git add foo &&
+       test_must_fail git cherry-pick --continue &&
+       test_cmp bar-expect bar &&
+       test_must_fail git diff-files --quiet &&
+       git add bar &&
+       git cherry-pick --continue &&
+       git reset --hard bar-dev
+'
+
+test_expect_success 'cherry-pick --continue rejects --rerere-autoupdate' '
+       test_must_fail git cherry-pick --rerere-autoupdate foo..bar-master &&
+       test_cmp foo-expect foo &&
+       git diff-files --quiet &&
+       test_must_fail git cherry-pick --continue --rerere-autoupdate >actual 2>&1 &&
+       echo "fatal: cherry-pick: --rerere-autoupdate cannot be used with --continue" >expect &&
+       test_i18ncmp expect actual &&
+       test_must_fail git cherry-pick --continue --no-rerere-autoupdate >actual 2>&1 &&
+       echo "fatal: cherry-pick: --no-rerere-autoupdate cannot be used with --continue" >expect &&
+       test_i18ncmp expect actual &&
+       git cherry-pick --abort
 '
 
-test_expect_success 'reconfigure' '
-       git config rerere.enabled false &&
-       git reset --hard
+test_expect_success 'cherry-pick --rerere-autoupdate more than once' '
+       test_must_fail git cherry-pick --rerere-autoupdate --rerere-autoupdate foo..bar-master &&
+       test_cmp foo-expect foo &&
+       git diff-files --quiet &&
+       git cherry-pick --abort &&
+       test_must_fail git cherry-pick --rerere-autoupdate --no-rerere-autoupdate --rerere-autoupdate foo..bar-master &&
+       test_cmp foo-expect foo &&
+       git diff-files --quiet &&
+       git cherry-pick --abort &&
+       test_must_fail git cherry-pick --rerere-autoupdate --no-rerere-autoupdate foo..bar-master &&
+       test_must_fail git diff-files --quiet &&
+       git cherry-pick --abort
 '
 
 test_expect_success 'cherry-pick conflict without rerere' '
+       test_config rerere.enabled false &&
        test_must_fail git cherry-pick master &&
        test_must_fail test_cmp expect foo
 '