Skip to content

Commit

Permalink
am: let command-line options override saved options
Browse files Browse the repository at this point in the history
When resuming, git-am mistakenly ignores command-line options.

For instance, when a patch fails to apply with "git am patch",
subsequently running "git am --3way" would not cause git-am to fall
back on attempting a threeway merge.  This occurs because by default
the --3way option is saved as "false", and the saved am options are
loaded after the command-line options are parsed, thus overwriting
the command-line options when resuming.

Fix this by moving the am_load() function call before parse_options(),
so that command-line options will override the saved am options.

The purpose of supporting this use case is to enable users to "wiggle"
that one conflicting patch. As such, it is expected that the
command-line options do not affect subsequent applied patches. Implement
this by calling am_load() once we apply the conflicting patch
successfully.

Noticed-by: Junio C Hamano <gitster@pobox.com>
Helped-by: Junio C Hamano <gitster@pobox.com>
Helped-by: Jeff King <peff@peff.net>
Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
Paul Tan authored and Junio C Hamano committed Aug 12, 2015
1 parent 18d8c26 commit 852a171
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 4 deletions.
16 changes: 12 additions & 4 deletions builtin/am.c
Original file line number Diff line number Diff line change
Expand Up @@ -1779,7 +1779,6 @@ static void am_run(struct am_state *state, int resume)

if (resume) {
validate_resume_state(state);
resume = 0;
} else {
int skip;

Expand Down Expand Up @@ -1841,6 +1840,10 @@ static void am_run(struct am_state *state, int resume)

next:
am_next(state);

if (resume)
am_load(state);
resume = 0;
}

if (!is_empty_file(am_path(state, "rewritten"))) {
Expand Down Expand Up @@ -1895,6 +1898,7 @@ static void am_resolve(struct am_state *state)

next:
am_next(state);
am_load(state);
am_run(state, 0);
}

Expand Down Expand Up @@ -2022,6 +2026,7 @@ static void am_skip(struct am_state *state)
die(_("failed to clean index"));

am_next(state);
am_load(state);
am_run(state, 0);
}

Expand Down Expand Up @@ -2132,6 +2137,7 @@ int cmd_am(int argc, const char **argv, const char *prefix)
int keep_cr = -1;
int patch_format = PATCH_FORMAT_UNKNOWN;
enum resume_mode resume = RESUME_FALSE;
int in_progress;

const char * const usage[] = {
N_("git am [options] [(<mbox>|<Maildir>)...]"),
Expand Down Expand Up @@ -2227,6 +2233,10 @@ int cmd_am(int argc, const char **argv, const char *prefix)

am_state_init(&state, git_path("rebase-apply"));

in_progress = am_in_progress(&state);
if (in_progress)
am_load(&state);

argc = parse_options(argc, argv, prefix, options, usage, 0);

if (binary >= 0)
Expand All @@ -2239,7 +2249,7 @@ int cmd_am(int argc, const char **argv, const char *prefix)
if (read_index_preload(&the_index, NULL) < 0)
die(_("failed to read the index"));

if (am_in_progress(&state)) {
if (in_progress) {
/*
* Catch user error to feed us patches when there is a session
* in progress:
Expand All @@ -2257,8 +2267,6 @@ int cmd_am(int argc, const char **argv, const char *prefix)

if (resume == RESUME_FALSE)
resume = RESUME_APPLY;

am_load(&state);
} else {
struct argv_array paths = ARGV_ARRAY_INIT;
int i;
Expand Down
82 changes: 82 additions & 0 deletions t/t4153-am-resume-override-opts.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#!/bin/sh

test_description='git-am command-line options override saved options'

. ./test-lib.sh
. "$TEST_DIRECTORY"/lib-terminal.sh

format_patch () {
git format-patch --stdout -1 "$1" >"$1".eml
}

test_expect_success 'setup' '
test_commit initial file &&
test_commit first file &&
git checkout initial &&
git mv file file2 &&
test_tick &&
git commit -m renamed-file &&
git tag renamed-file &&
git checkout -b side initial &&
test_commit side1 file &&
test_commit side2 file &&
format_patch side1 &&
format_patch side2
'

test_expect_success TTY '--3way overrides --no-3way' '
rm -fr .git/rebase-apply &&
git reset --hard &&
git checkout renamed-file &&
# Applying side1 will fail as the file has been renamed.
test_must_fail git am --no-3way side[12].eml &&
test_path_is_dir .git/rebase-apply &&
test_cmp_rev renamed-file HEAD &&
test -z "$(git ls-files -u)" &&
# Applying side1 with am --3way will succeed due to the threeway-merge.
# Applying side2 will fail as --3way does not apply to it.
test_must_fail test_terminal git am --3way </dev/zero &&
test_path_is_dir .git/rebase-apply &&
test side1 = "$(cat file2)"
'

test_expect_success '--no-quiet overrides --quiet' '
rm -fr .git/rebase-apply &&
git reset --hard &&
git checkout first &&
# Applying side1 will be quiet.
test_must_fail git am --quiet side[123].eml >out &&
test_path_is_dir .git/rebase-apply &&
! test_i18ngrep "^Applying: " out &&
echo side1 >file &&
git add file &&
# Applying side1 will not be quiet.
# Applying side2 will be quiet.
git am --no-quiet --continue >out &&
echo "Applying: side1" >expected &&
test_i18ncmp expected out
'

test_expect_success TTY '--reject overrides --no-reject' '
rm -fr .git/rebase-apply &&
git reset --hard &&
git checkout first &&
rm -f file.rej &&
test_must_fail git am --no-reject side1.eml &&
test_path_is_dir .git/rebase-apply &&
test_path_is_missing file.rej &&
test_must_fail test_terminal git am --reject </dev/zero &&
test_path_is_dir .git/rebase-apply &&
test_path_is_file file.rej
'

test_done

0 comments on commit 852a171

Please sign in to comment.