@@ -677,7 +677,7 @@ sub add_untracked_cmd {
677
677
sub run_git_apply {
678
678
my $cmd = shift ;
679
679
my $fh ;
680
- open $fh , ' | git ' . $cmd . " --recount -- allow-overlap" ;
680
+ open $fh , ' | git ' . $cmd . " --allow-overlap" ;
681
681
print $fh @_ ;
682
682
return close $fh ;
683
683
}
@@ -751,6 +751,15 @@ sub parse_hunk_header {
751
751
return ($o_ofs , $o_cnt , $n_ofs , $n_cnt );
752
752
}
753
753
754
+ sub format_hunk_header {
755
+ my ($o_ofs , $o_cnt , $n_ofs , $n_cnt ) = @_ ;
756
+ return (" @@ -$o_ofs " .
757
+ (($o_cnt != 1) ? " ,$o_cnt " : ' ' ) .
758
+ " +$n_ofs " .
759
+ (($n_cnt != 1) ? " ,$n_cnt " : ' ' ) .
760
+ " @@\n " );
761
+ }
762
+
754
763
sub split_hunk {
755
764
my ($text , $display ) = @_ ;
756
765
my @split = ();
@@ -784,6 +793,11 @@ sub split_hunk {
784
793
while (++$i < @$text ) {
785
794
my $line = $text -> [$i ];
786
795
my $display = $display -> [$i ];
796
+ if ($line =~ / ^\\ / ) {
797
+ push @{$this -> {TEXT }}, $line ;
798
+ push @{$this -> {DISPLAY }}, $display ;
799
+ next ;
800
+ }
787
801
if ($line =~ / ^ / ) {
788
802
if ($this -> {ADDDEL } &&
789
803
!defined $next_hunk_start ) {
@@ -838,11 +852,7 @@ sub split_hunk {
838
852
my $o_cnt = $hunk -> {OCNT };
839
853
my $n_cnt = $hunk -> {NCNT };
840
854
841
- my $head = (" @@ -$o_ofs " .
842
- (($o_cnt != 1) ? " ,$o_cnt " : ' ' ) .
843
- " +$n_ofs " .
844
- (($n_cnt != 1) ? " ,$n_cnt " : ' ' ) .
845
- " @@\n " );
855
+ my $head = format_hunk_header($o_ofs , $o_cnt , $n_ofs , $n_cnt );
846
856
my $display_head = $head ;
847
857
unshift @{$hunk -> {TEXT }}, $head ;
848
858
if ($diff_use_color ) {
@@ -886,6 +896,9 @@ sub merge_hunk {
886
896
$n_cnt ++;
887
897
push @line , $line ;
888
898
next ;
899
+ } elsif ($line =~ / ^\\ / ) {
900
+ push @line , $line ;
901
+ next ;
889
902
}
890
903
891
904
last if ($o1_ofs <= $ofs );
@@ -904,6 +917,9 @@ sub merge_hunk {
904
917
$n_cnt ++;
905
918
push @line , $line ;
906
919
next ;
920
+ } elsif ($line =~ / ^\\ / ) {
921
+ push @line , $line ;
922
+ next ;
907
923
}
908
924
$ofs ++;
909
925
$o_cnt ++;
@@ -912,11 +928,7 @@ sub merge_hunk {
912
928
}
913
929
push @line , $line ;
914
930
}
915
- my $head = (" @@ -$o0_ofs " .
916
- (($o_cnt != 1) ? " ,$o_cnt " : ' ' ) .
917
- " +$n0_ofs " .
918
- (($n_cnt != 1) ? " ,$n_cnt " : ' ' ) .
919
- " @@\n " );
931
+ my $head = format_hunk_header($o0_ofs , $o_cnt , $n0_ofs , $n_cnt );
920
932
@{$prev -> {TEXT }} = ($head , @line );
921
933
}
922
934
@@ -925,14 +937,35 @@ sub coalesce_overlapping_hunks {
925
937
my @out = ();
926
938
927
939
my ($last_o_ctx , $last_was_dirty );
940
+ my $ofs_delta = 0;
928
941
929
- for (grep { $_ -> { USE } } @in ) {
942
+ for (@in ) {
930
943
if ($_ -> {TYPE } ne ' hunk' ) {
931
944
push @out , $_ ;
932
945
next ;
933
946
}
934
947
my $text = $_ -> {TEXT };
935
- my ($o_ofs ) = parse_hunk_header($text -> [0]);
948
+ my ($o_ofs , $o_cnt , $n_ofs , $n_cnt ) =
949
+ parse_hunk_header($text -> [0]);
950
+ unless ($_ -> {USE }) {
951
+ $ofs_delta += $o_cnt - $n_cnt ;
952
+ # If this hunk has been edited then subtract
953
+ # the delta that is due to the edit.
954
+ if ($_ -> {OFS_DELTA }) {
955
+ $ofs_delta -= $_ -> {OFS_DELTA };
956
+ }
957
+ next ;
958
+ }
959
+ if ($ofs_delta ) {
960
+ $n_ofs += $ofs_delta ;
961
+ $_ -> {TEXT }-> [0] = format_hunk_header($o_ofs , $o_cnt ,
962
+ $n_ofs , $n_cnt );
963
+ }
964
+ # If this hunk was edited then adjust the offset delta
965
+ # to reflect the edit.
966
+ if ($_ -> {OFS_DELTA }) {
967
+ $ofs_delta += $_ -> {OFS_DELTA };
968
+ }
936
969
if (defined $last_o_ctx &&
937
970
$o_ofs <= $last_o_ctx &&
938
971
!$_ -> {DIRTY } &&
@@ -1004,6 +1037,30 @@ sub color_diff {
1004
1037
marked for applying." ),
1005
1038
);
1006
1039
1040
+ sub recount_edited_hunk {
1041
+ local $_ ;
1042
+ my ($oldtext , $newtext ) = @_ ;
1043
+ my ($o_cnt , $n_cnt ) = (0, 0);
1044
+ for (@{$newtext }[1..$# {$newtext }]) {
1045
+ my $mode = substr ($_ , 0, 1);
1046
+ if ($mode eq ' -' ) {
1047
+ $o_cnt ++;
1048
+ } elsif ($mode eq ' +' ) {
1049
+ $n_cnt ++;
1050
+ } elsif ($mode eq ' ' ) {
1051
+ $o_cnt ++;
1052
+ $n_cnt ++;
1053
+ }
1054
+ }
1055
+ my ($o_ofs , undef , $n_ofs , undef ) =
1056
+ parse_hunk_header($newtext -> [0]);
1057
+ $newtext -> [0] = format_hunk_header($o_ofs , $o_cnt , $n_ofs , $n_cnt );
1058
+ my (undef , $orig_o_cnt , undef , $orig_n_cnt ) =
1059
+ parse_hunk_header($oldtext -> [0]);
1060
+ # Return the change in the number of lines inserted by this hunk
1061
+ return $orig_o_cnt - $orig_n_cnt - $o_cnt + $n_cnt ;
1062
+ }
1063
+
1007
1064
sub edit_hunk_manually {
1008
1065
my ($oldtext ) = @_ ;
1009
1066
@@ -1102,25 +1159,32 @@ sub prompt_yesno {
1102
1159
}
1103
1160
1104
1161
sub edit_hunk_loop {
1105
- my ($head , $hunk , $ix ) = @_ ;
1106
- my $text = $hunk -> [$ix ]-> {TEXT };
1162
+ my ($head , $hunks , $ix ) = @_ ;
1163
+ my $hunk = $hunks -> [$ix ];
1164
+ my $text = $hunk -> {TEXT };
1107
1165
1108
1166
while (1) {
1109
- $text = edit_hunk_manually($text );
1110
- if (!defined $text ) {
1167
+ my $newtext = edit_hunk_manually($text );
1168
+ if (!defined $newtext ) {
1111
1169
return undef ;
1112
1170
}
1113
1171
my $newhunk = {
1114
- TEXT => $text ,
1115
- TYPE => $hunk -> [ $ix ] -> {TYPE },
1172
+ TEXT => $newtext ,
1173
+ TYPE => $hunk -> {TYPE },
1116
1174
USE => 1,
1117
1175
DIRTY => 1,
1118
1176
};
1177
+ $newhunk -> {OFS_DELTA } = recount_edited_hunk($text , $newtext );
1178
+ # If this hunk has already been edited then add the
1179
+ # offset delta of the previous edit to get the real
1180
+ # delta from the original unedited hunk.
1181
+ $hunk -> {OFS_DELTA } and
1182
+ $newhunk -> {OFS_DELTA } += $hunk -> {OFS_DELTA };
1119
1183
if (diff_applies($head ,
1120
- @{$hunk }[0..$ix -1],
1184
+ @{$hunks }[0..$ix -1],
1121
1185
$newhunk ,
1122
- @{$hunk }[$ix +1..$# {$hunk }])) {
1123
- $newhunk -> {DISPLAY } = [color_diff(@{$text })];
1186
+ @{$hunks }[$ix +1..$# {$hunks }])) {
1187
+ $newhunk -> {DISPLAY } = [color_diff(@{$newtext })];
1124
1188
return $newhunk ;
1125
1189
}
1126
1190
else {
0 commit comments