mirror of
https://github.com/git/git.git
synced 2024-11-23 18:05:29 +08:00
Merge branch 'jk/am-retry'
"git am" has a safety feature to prevent it from starting a new session when there already is a session going. It reliably triggers when a mbox is given on the command line, but it has to rely on the tty-ness of the standard input. Add an explicit way to opt out of this safety with a command line option. * jk/am-retry: test-terminal: drop stdin handling am: add explicit "--retry" option
This commit is contained in:
commit
42b8b5bfd0
@ -18,7 +18,7 @@ SYNOPSIS
|
||||
[--quoted-cr=<action>]
|
||||
[--empty=(stop|drop|keep)]
|
||||
[(<mbox> | <Maildir>)...]
|
||||
'git am' (--continue | --skip | --abort | --quit | --show-current-patch[=(diff|raw)] | --allow-empty)
|
||||
'git am' (--continue | --skip | --abort | --quit | --retry | --show-current-patch[=(diff|raw)] | --allow-empty)
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
@ -208,6 +208,12 @@ Valid <action> for the `--whitespace` option are:
|
||||
Abort the patching operation but keep HEAD and the index
|
||||
untouched.
|
||||
|
||||
--retry::
|
||||
Try to apply the last conflicting patch again. This is generally
|
||||
only useful for passing extra options to the retry attempt
|
||||
(e.g., `--3way`), since otherwise you'll just see the same
|
||||
failure again.
|
||||
|
||||
--show-current-patch[=(diff|raw)]::
|
||||
Show the message at which `git am` has stopped due to
|
||||
conflicts. If `raw` is specified, show the raw contents of
|
||||
|
@ -2393,6 +2393,9 @@ int cmd_am(int argc, const char **argv, const char *prefix)
|
||||
N_("show the patch being applied"),
|
||||
PARSE_OPT_CMDMODE | PARSE_OPT_OPTARG | PARSE_OPT_NONEG | PARSE_OPT_LITERAL_ARGHELP,
|
||||
parse_opt_show_current_patch, RESUME_SHOW_PATCH_RAW },
|
||||
OPT_CMDMODE(0, "retry", &resume_mode,
|
||||
N_("try to apply current patch again"),
|
||||
RESUME_APPLY),
|
||||
OPT_CMDMODE(0, "allow-empty", &resume_mode,
|
||||
N_("record the empty patch as an empty commit"),
|
||||
RESUME_ALLOW_EMPTY),
|
||||
|
@ -3,7 +3,6 @@
|
||||
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
|
||||
@ -27,7 +26,12 @@ test_expect_success 'setup' '
|
||||
format_patch side2
|
||||
'
|
||||
|
||||
test_expect_success TTY '--3way overrides --no-3way' '
|
||||
test_expect_success '--retry fails without in-progress operation' '
|
||||
test_must_fail git am --retry 2>err &&
|
||||
test_grep "operation not in progress" err
|
||||
'
|
||||
|
||||
test_expect_success '--3way overrides --no-3way' '
|
||||
rm -fr .git/rebase-apply &&
|
||||
git reset --hard &&
|
||||
git checkout renamed-file &&
|
||||
@ -40,7 +44,7 @@ test_expect_success TTY '--3way overrides --no-3way' '
|
||||
|
||||
# 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_must_fail git am --retry --3way &&
|
||||
test_path_is_dir .git/rebase-apply &&
|
||||
test side1 = "$(cat file2)"
|
||||
'
|
||||
@ -84,7 +88,7 @@ test_expect_success '--signoff overrides --no-signoff' '
|
||||
test $(git cat-file commit HEAD | grep -c "Signed-off-by:") -eq 0
|
||||
'
|
||||
|
||||
test_expect_success TTY '--reject overrides --no-reject' '
|
||||
test_expect_success '--reject overrides --no-reject' '
|
||||
rm -fr .git/rebase-apply &&
|
||||
git reset --hard &&
|
||||
git checkout first &&
|
||||
@ -94,7 +98,7 @@ test_expect_success TTY '--reject overrides --no-reject' '
|
||||
test_path_is_dir .git/rebase-apply &&
|
||||
test_path_is_missing file.rej &&
|
||||
|
||||
test_must_fail test_terminal git am --reject </dev/zero &&
|
||||
test_must_fail git am --retry --reject </dev/zero &&
|
||||
test_path_is_dir .git/rebase-apply &&
|
||||
test_path_is_file file.rej
|
||||
'
|
||||
|
@ -5,17 +5,15 @@ use warnings;
|
||||
use IO::Pty;
|
||||
use File::Copy;
|
||||
|
||||
# Run @$argv in the background with stdio redirected to $in, $out and $err.
|
||||
# Run @$argv in the background with stdio redirected to $out and $err.
|
||||
sub start_child {
|
||||
my ($argv, $in, $out, $err) = @_;
|
||||
my ($argv, $out, $err) = @_;
|
||||
my $pid = fork;
|
||||
if (not defined $pid) {
|
||||
die "fork failed: $!"
|
||||
} elsif ($pid == 0) {
|
||||
open STDIN, "<&", $in;
|
||||
open STDOUT, ">&", $out;
|
||||
open STDERR, ">&", $err;
|
||||
close $in;
|
||||
close $out;
|
||||
exec(@$argv) or die "cannot exec '$argv->[0]': $!"
|
||||
}
|
||||
@ -51,17 +49,6 @@ sub xsendfile {
|
||||
copy($in, $out, 4096) or $!{EIO} or die "cannot copy from child: $!";
|
||||
}
|
||||
|
||||
sub copy_stdin {
|
||||
my ($in) = @_;
|
||||
my $pid = fork;
|
||||
if (!$pid) {
|
||||
xsendfile($in, \*STDIN);
|
||||
exit 0;
|
||||
}
|
||||
close($in);
|
||||
return $pid;
|
||||
}
|
||||
|
||||
sub copy_stdio {
|
||||
my ($out, $err) = @_;
|
||||
my $pid = fork;
|
||||
@ -81,25 +68,15 @@ if ($#ARGV < 1) {
|
||||
die "usage: test-terminal program args";
|
||||
}
|
||||
$ENV{TERM} = 'vt100';
|
||||
my $parent_in = new IO::Pty;
|
||||
my $parent_out = new IO::Pty;
|
||||
my $parent_err = new IO::Pty;
|
||||
$parent_in->set_raw();
|
||||
$parent_out->set_raw();
|
||||
$parent_err->set_raw();
|
||||
$parent_in->slave->set_raw();
|
||||
$parent_out->slave->set_raw();
|
||||
$parent_err->slave->set_raw();
|
||||
my $pid = start_child(\@ARGV, $parent_in->slave, $parent_out->slave, $parent_err->slave);
|
||||
close $parent_in->slave;
|
||||
my $pid = start_child(\@ARGV, $parent_out->slave, $parent_err->slave);
|
||||
close $parent_out->slave;
|
||||
close $parent_err->slave;
|
||||
my $in_pid = copy_stdin($parent_in);
|
||||
copy_stdio($parent_out, $parent_err);
|
||||
my $ret = finish_child($pid);
|
||||
# If the child process terminates before our copy_stdin() process is able to
|
||||
# write all of its data to $parent_in, the copy_stdin() process could stall.
|
||||
# Send SIGTERM to it to ensure it terminates.
|
||||
kill 'TERM', $in_pid;
|
||||
finish_child($in_pid);
|
||||
exit($ret);
|
||||
|
Loading…
Reference in New Issue
Block a user