@@ -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 {
636637sub 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 ;
891897y - stage this hunk
892898n - do not stage this hunk
899+ q - quit, do not stage this hunk nor any of the remaining ones
893900a - stage this and all the remaining hunks in the file
894901d - do not stage this hunk nor any of the remaining hunks in the file
895902g - 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
974981sub 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
12401236sub diff_cmd {
0 commit comments