Merge branch 'pw/sequence-rerere-autoupdate'

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
This commit is contained in:
Junio C Hamano 2017-08-22 10:29:00 -07:00
commit 1016495a71
7 changed files with 170 additions and 49 deletions

View 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";

View 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);
}

View 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=$?

View 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")"

View 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()))
@ -1743,6 +1757,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;
}

View File

@ -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

View File

@ -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 &&
test_commit foo &&
test_commit foo-master foo &&
test_commit bar-master bar &&
git checkout -b dev HEAD^ &&
echo foo-dev >foo &&
git add foo && test_tick && git commit -q -m 3 &&
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 'reconfigure' '
git config rerere.enabled false &&
git reset --hard
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 '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
'