@@ -902,6 +902,54 @@ static int edit_hunk_loop(struct add_p_state *s,
902
902
}
903
903
}
904
904
905
+ #define SUMMARY_HEADER_WIDTH 20
906
+ #define SUMMARY_LINE_WIDTH 80
907
+ static void summarize_hunk (struct add_p_state * s , struct hunk * hunk ,
908
+ struct strbuf * out )
909
+ {
910
+ struct hunk_header * header = & hunk -> header ;
911
+ struct strbuf * plain = & s -> plain ;
912
+ size_t len = out -> len , i ;
913
+
914
+ strbuf_addf (out , " -%lu,%lu +%lu,%lu " ,
915
+ header -> old_offset , header -> old_count ,
916
+ header -> new_offset , header -> new_count );
917
+ if (out -> len - len < SUMMARY_HEADER_WIDTH )
918
+ strbuf_addchars (out , ' ' ,
919
+ SUMMARY_HEADER_WIDTH + len - out -> len );
920
+ for (i = hunk -> start ; i < hunk -> end ; i = find_next_line (plain , i ))
921
+ if (plain -> buf [i ] != ' ' )
922
+ break ;
923
+ if (i < hunk -> end )
924
+ strbuf_add (out , plain -> buf + i , find_next_line (plain , i ) - i );
925
+ if (out -> len - len > SUMMARY_LINE_WIDTH )
926
+ strbuf_setlen (out , len + SUMMARY_LINE_WIDTH );
927
+ strbuf_complete_line (out );
928
+ }
929
+
930
+ #define DISPLAY_HUNKS_LINES 20
931
+ static size_t display_hunks (struct add_p_state * s ,
932
+ struct file_diff * file_diff , size_t start_index )
933
+ {
934
+ size_t end_index = start_index + DISPLAY_HUNKS_LINES ;
935
+
936
+ if (end_index > file_diff -> hunk_nr )
937
+ end_index = file_diff -> hunk_nr ;
938
+
939
+ while (start_index < end_index ) {
940
+ struct hunk * hunk = file_diff -> hunk + start_index ++ ;
941
+
942
+ strbuf_reset (& s -> buf );
943
+ strbuf_addf (& s -> buf , "%c%2d: " , hunk -> use == USE_HUNK ? '+'
944
+ : hunk -> use == SKIP_HUNK ? '-' : ' ' ,
945
+ (int )start_index );
946
+ summarize_hunk (s , hunk , & s -> buf );
947
+ fputs (s -> buf .buf , stdout );
948
+ }
949
+
950
+ return end_index ;
951
+ }
952
+
905
953
static const char help_patch_text [] =
906
954
N_ ("y - stage this hunk\n"
907
955
"n - do not stage this hunk\n"
@@ -911,6 +959,7 @@ N_("y - stage this hunk\n"
911
959
"J - leave this hunk undecided, see next hunk\n"
912
960
"k - leave this hunk undecided, see previous undecided hunk\n"
913
961
"K - leave this hunk undecided, see previous hunk\n"
962
+ "g - select a hunk to go to\n"
914
963
"s - split the current hunk into smaller hunks\n"
915
964
"e - manually edit the current hunk\n"
916
965
"? - print help\n" );
@@ -969,6 +1018,8 @@ static int patch_update_file(struct add_p_state *s,
969
1018
strbuf_addstr (& s -> buf , ",j" );
970
1019
if (hunk_index + 1 < file_diff -> hunk_nr )
971
1020
strbuf_addstr (& s -> buf , ",J" );
1021
+ if (file_diff -> hunk_nr > 1 )
1022
+ strbuf_addstr (& s -> buf , ",g" );
972
1023
if (hunk -> splittable_into > 1 )
973
1024
strbuf_addstr (& s -> buf , ",s" );
974
1025
if (hunk_index + 1 > file_diff -> mode_change &&
@@ -1034,6 +1085,41 @@ static int patch_update_file(struct add_p_state *s,
1034
1085
hunk_index = undecided_next ;
1035
1086
else
1036
1087
err (s , _ ("No next hunk" ));
1088
+ } else if (s -> answer .buf [0 ] == 'g' ) {
1089
+ char * pend ;
1090
+ unsigned long response ;
1091
+
1092
+ if (file_diff -> hunk_nr < 2 ) {
1093
+ err (s , _ ("No other hunks to goto" ));
1094
+ continue ;
1095
+ }
1096
+ strbuf_remove (& s -> answer , 0 , 1 );
1097
+ strbuf_trim (& s -> answer );
1098
+ i = hunk_index > 10 ? hunk_index - 10 : 0 ;
1099
+ while (s -> answer .len == 0 ) {
1100
+ i = display_hunks (s , file_diff , i );
1101
+ printf ("%s" , i < file_diff -> hunk_nr ?
1102
+ _ ("go to which hunk (<ret> to see "
1103
+ "more)? " ) : _ ("go to which hunk? " ));
1104
+ fflush (stdout );
1105
+ if (strbuf_getline (& s -> answer ,
1106
+ stdin ) == EOF )
1107
+ break ;
1108
+ strbuf_trim_trailing_newline (& s -> answer );
1109
+ }
1110
+
1111
+ strbuf_trim (& s -> answer );
1112
+ response = strtoul (s -> answer .buf , & pend , 10 );
1113
+ if (* pend || pend == s -> answer .buf )
1114
+ err (s , _ ("Invalid number: '%s'" ),
1115
+ s -> answer .buf );
1116
+ else if (0 < response && response <= file_diff -> hunk_nr )
1117
+ hunk_index = response - 1 ;
1118
+ else
1119
+ err (s , Q_ ("Sorry, only %d hunk available." ,
1120
+ "Sorry, only %d hunks available." ,
1121
+ file_diff -> hunk_nr ),
1122
+ (int )file_diff -> hunk_nr );
1037
1123
} else if (s -> answer .buf [0 ] == 's' ) {
1038
1124
size_t splittable_into = hunk -> splittable_into ;
1039
1125
if (splittable_into < 2 )
0 commit comments