Skip to content

Commit fe4ce3a

Browse files
committed
Merge branch 'mm/maint-add-p-quit' into maint
* mm/maint-add-p-quit: Update git-add.txt according to the new possibilities of 'git add -p'. add-interactive: refactor mode hunk handling git add -p: new "quit" command at the prompt.
2 parents 84047e0 + cafa567 commit fe4ce3a

File tree

2 files changed

+38
-39
lines changed

2 files changed

+38
-39
lines changed

Documentation/git-add.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,8 +245,11 @@ patch::
245245

246246
y - stage this hunk
247247
n - do not stage this hunk
248+
q - quit, do not stage this hunk nor any of the remaining ones
248249
a - stage this and all the remaining hunks in the file
249250
d - do not stage this hunk nor any of the remaining hunks in the file
251+
g - select a hunk to go to
252+
/ - search for a hunk matching the given regex
250253
j - leave this hunk undecided, see next undecided hunk
251254
J - leave this hunk undecided, see next hunk
252255
k - leave this hunk undecided, see previous undecided hunk

git-add--interactive.perl

Lines changed: 35 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -620,11 +620,12 @@ sub parse_diff {
620620
if ($diff_use_color) {
621621
@colored = run_cmd_pipe(qw(git diff-files -p --color --), $path);
622622
}
623-
my (@hunk) = { TEXT => [], DISPLAY => [] };
623+
my (@hunk) = { TEXT => [], DISPLAY => [], TYPE => 'header' };
624624

625625
for (my $i = 0; $i < @diff; $i++) {
626626
if ($diff[$i] =~ /^@@ /) {
627-
push @hunk, { TEXT => [], DISPLAY => [] };
627+
push @hunk, { TEXT => [], DISPLAY => [],
628+
TYPE => 'hunk' };
628629
}
629630
push @{$hunk[-1]{TEXT}}, $diff[$i];
630631
push @{$hunk[-1]{DISPLAY}},
@@ -636,8 +637,8 @@ sub parse_diff {
636637
sub parse_diff_header {
637638
my $src = shift;
638639

639-
my $head = { TEXT => [], DISPLAY => [] };
640-
my $mode = { TEXT => [], DISPLAY => [] };
640+
my $head = { TEXT => [], DISPLAY => [], TYPE => 'header' };
641+
my $mode = { TEXT => [], DISPLAY => [], TYPE => 'mode' };
641642

642643
for (my $i = 0; $i < @{$src->{TEXT}}; $i++) {
643644
my $dest = $src->{TEXT}->[$i] =~ /^(old|new) mode (\d+)$/ ?
@@ -684,6 +685,7 @@ sub split_hunk {
684685
my $this = +{
685686
TEXT => [],
686687
DISPLAY => [],
688+
TYPE => 'hunk',
687689
OLD => $o_ofs,
688690
NEW => $n_ofs,
689691
OCNT => 0,
@@ -869,7 +871,11 @@ sub edit_hunk_loop {
869871
if (!defined $text) {
870872
return undef;
871873
}
872-
my $newhunk = { TEXT => $text, USE => 1 };
874+
my $newhunk = {
875+
TEXT => $text,
876+
TYPE => $hunk->[$ix]->{TYPE},
877+
USE => 1
878+
};
873879
if (diff_applies($head,
874880
@{$hunk}[0..$ix-1],
875881
$newhunk,
@@ -890,6 +896,7 @@ sub help_patch_cmd {
890896
print colored $help_color, <<\EOF ;
891897
y - stage this hunk
892898
n - do not stage this hunk
899+
q - quit, do not stage this hunk nor any of the remaining ones
893900
a - stage this and all the remaining hunks in the file
894901
d - do not stage this hunk nor any of the remaining hunks in the file
895902
g - select a hunk to go to
@@ -926,7 +933,7 @@ sub patch_update_cmd {
926933
@mods);
927934
}
928935
for (@them) {
929-
patch_update_file($_->{VALUE});
936+
return 0 if patch_update_file($_->{VALUE});
930937
}
931938
}
932939

@@ -972,6 +979,7 @@ sub display_hunks {
972979
}
973980

974981
sub patch_update_file {
982+
my $quit = 0;
975983
my ($ix, $num);
976984
my $path = shift;
977985
my ($head, @hunk) = parse_diff($path);
@@ -981,32 +989,7 @@ sub patch_update_file {
981989
}
982990

983991
if (@{$mode->{TEXT}}) {
984-
while (1) {
985-
print @{$mode->{DISPLAY}};
986-
print colored $prompt_color,
987-
"Stage mode change [y/n/a/d/?]? ";
988-
my $line = prompt_single_character;
989-
if ($line =~ /^y/i) {
990-
$mode->{USE} = 1;
991-
last;
992-
}
993-
elsif ($line =~ /^n/i) {
994-
$mode->{USE} = 0;
995-
last;
996-
}
997-
elsif ($line =~ /^a/i) {
998-
$_->{USE} = 1 foreach ($mode, @hunk);
999-
last;
1000-
}
1001-
elsif ($line =~ /^d/i) {
1002-
$_->{USE} = 0 foreach ($mode, @hunk);
1003-
last;
1004-
}
1005-
else {
1006-
help_patch_cmd('');
1007-
next;
1008-
}
1009-
}
992+
unshift @hunk, $mode;
1010993
}
1011994

1012995
$num = scalar @hunk;
@@ -1050,14 +1033,19 @@ sub patch_update_file {
10501033
}
10511034
last if (!$undecided);
10521035

1053-
if (hunk_splittable($hunk[$ix]{TEXT})) {
1036+
if ($hunk[$ix]{TYPE} eq 'hunk' &&
1037+
hunk_splittable($hunk[$ix]{TEXT})) {
10541038
$other .= ',s';
10551039
}
1056-
$other .= ',e';
1040+
if ($hunk[$ix]{TYPE} eq 'hunk') {
1041+
$other .= ',e';
1042+
}
10571043
for (@{$hunk[$ix]{DISPLAY}}) {
10581044
print;
10591045
}
1060-
print colored $prompt_color, "Stage this hunk [y,n,a,d,/$other,?]? ";
1046+
print colored $prompt_color, 'Stage ',
1047+
($hunk[$ix]{TYPE} eq 'mode' ? 'mode change' : 'this hunk'),
1048+
" [y,n,a,d,/$other,?]? ";
10611049
my $line = prompt_single_character;
10621050
if ($line) {
10631051
if ($line =~ /^y/i) {
@@ -1109,6 +1097,16 @@ sub patch_update_file {
11091097
}
11101098
next;
11111099
}
1100+
elsif ($line =~ /^q/i) {
1101+
while ($ix < $num) {
1102+
if (!defined $hunk[$ix]{USE}) {
1103+
$hunk[$ix]{USE} = 0;
1104+
}
1105+
$ix++;
1106+
}
1107+
$quit = 1;
1108+
next;
1109+
}
11121110
elsif ($line =~ m|^/(.*)|) {
11131111
my $regex = $1;
11141112
if ($1 eq "") {
@@ -1189,7 +1187,7 @@ sub patch_update_file {
11891187
$num = scalar @hunk;
11901188
next;
11911189
}
1192-
elsif ($line =~ /^e/) {
1190+
elsif ($other =~ /e/ && $line =~ /^e/) {
11931191
my $newhunk = edit_hunk_loop($head, \@hunk, $ix);
11941192
if (defined $newhunk) {
11951193
splice @hunk, $ix, 1, $newhunk;
@@ -1210,9 +1208,6 @@ sub patch_update_file {
12101208

12111209
my $n_lofs = 0;
12121210
my @result = ();
1213-
if ($mode->{USE}) {
1214-
push @result, @{$mode->{TEXT}};
1215-
}
12161211
for (@hunk) {
12171212
if ($_->{USE}) {
12181213
push @result, @{$_->{TEXT}};
@@ -1235,6 +1230,7 @@ sub patch_update_file {
12351230
}
12361231

12371232
print "\n";
1233+
return $quit;
12381234
}
12391235

12401236
sub diff_cmd {

0 commit comments

Comments
 (0)