@@ -955,6 +955,54 @@ static int edit_hunk_loop(struct add_p_state *s,
955
955
}
956
956
}
957
957
958
+ #define SUMMARY_HEADER_WIDTH 20
959
+ #define SUMMARY_LINE_WIDTH 80
960
+ static void summarize_hunk (struct add_p_state * s , struct hunk * hunk ,
961
+ struct strbuf * out )
962
+ {
963
+ struct hunk_header * header = & hunk -> header ;
964
+ struct strbuf * plain = & s -> plain ;
965
+ size_t len = out -> len , i ;
966
+
967
+ strbuf_addf (out , " -%lu,%lu +%lu,%lu " ,
968
+ header -> old_offset , header -> old_count ,
969
+ header -> new_offset , header -> new_count );
970
+ if (out -> len - len < SUMMARY_HEADER_WIDTH )
971
+ strbuf_addchars (out , ' ' ,
972
+ SUMMARY_HEADER_WIDTH + len - out -> len );
973
+ for (i = hunk -> start ; i < hunk -> end ; i = find_next_line (plain , i ))
974
+ if (plain -> buf [i ] != ' ' )
975
+ break ;
976
+ if (i < hunk -> end )
977
+ strbuf_add (out , plain -> buf + i , find_next_line (plain , i ) - i );
978
+ if (out -> len - len > SUMMARY_LINE_WIDTH )
979
+ strbuf_setlen (out , len + SUMMARY_LINE_WIDTH );
980
+ strbuf_complete_line (out );
981
+ }
982
+
983
+ #define DISPLAY_HUNKS_LINES 20
984
+ static size_t display_hunks (struct add_p_state * s ,
985
+ struct file_diff * file_diff , size_t start_index )
986
+ {
987
+ size_t end_index = start_index + DISPLAY_HUNKS_LINES ;
988
+
989
+ if (end_index > file_diff -> hunk_nr )
990
+ end_index = file_diff -> hunk_nr ;
991
+
992
+ while (start_index < end_index ) {
993
+ struct hunk * hunk = file_diff -> hunk + start_index ++ ;
994
+
995
+ strbuf_reset (& s -> buf );
996
+ strbuf_addf (& s -> buf , "%c%2d: " , hunk -> use == USE_HUNK ? '+'
997
+ : hunk -> use == SKIP_HUNK ? '-' : ' ' ,
998
+ (int )start_index );
999
+ summarize_hunk (s , hunk , & s -> buf );
1000
+ fputs (s -> buf .buf , stdout );
1001
+ }
1002
+
1003
+ return end_index ;
1004
+ }
1005
+
958
1006
static const char help_patch_text [] =
959
1007
N_ ("y - stage this hunk\n"
960
1008
"n - do not stage this hunk\n"
@@ -964,6 +1012,7 @@ N_("y - stage this hunk\n"
964
1012
"J - leave this hunk undecided, see next hunk\n"
965
1013
"k - leave this hunk undecided, see previous undecided hunk\n"
966
1014
"K - leave this hunk undecided, see previous hunk\n"
1015
+ "g - select a hunk to go to\n"
967
1016
"s - split the current hunk into smaller hunks\n"
968
1017
"e - manually edit the current hunk\n"
969
1018
"? - print help\n" );
@@ -1022,6 +1071,8 @@ static int patch_update_file(struct add_p_state *s,
1022
1071
strbuf_addstr (& s -> buf , ",j" );
1023
1072
if (hunk_index + 1 < file_diff -> hunk_nr )
1024
1073
strbuf_addstr (& s -> buf , ",J" );
1074
+ if (file_diff -> hunk_nr > 1 )
1075
+ strbuf_addstr (& s -> buf , ",g" );
1025
1076
if (hunk -> splittable_into > 1 )
1026
1077
strbuf_addstr (& s -> buf , ",s" );
1027
1078
if (hunk_index + 1 > file_diff -> mode_change &&
@@ -1089,6 +1140,43 @@ static int patch_update_file(struct add_p_state *s,
1089
1140
hunk_index = undecided_next ;
1090
1141
else
1091
1142
err (s , _ ("No next hunk" ));
1143
+ } else if (s -> answer .buf [0 ] == 'g' ) {
1144
+ char * pend ;
1145
+ unsigned long response ;
1146
+
1147
+ if (file_diff -> hunk_nr < 2 ) {
1148
+ err (s , _ ("No other hunks to goto" ));
1149
+ continue ;
1150
+ }
1151
+ strbuf_remove (& s -> answer , 0 , 1 );
1152
+ strbuf_trim (& s -> answer );
1153
+ i = hunk_index - DISPLAY_HUNKS_LINES / 2 ;
1154
+ if (i < file_diff -> mode_change )
1155
+ i = file_diff -> mode_change ;
1156
+ while (s -> answer .len == 0 ) {
1157
+ i = display_hunks (s , file_diff , i );
1158
+ printf ("%s" , i < file_diff -> hunk_nr ?
1159
+ _ ("go to which hunk (<ret> to see "
1160
+ "more)? " ) : _ ("go to which hunk? " ));
1161
+ fflush (stdout );
1162
+ if (strbuf_getline (& s -> answer ,
1163
+ stdin ) == EOF )
1164
+ break ;
1165
+ strbuf_trim_trailing_newline (& s -> answer );
1166
+ }
1167
+
1168
+ strbuf_trim (& s -> answer );
1169
+ response = strtoul (s -> answer .buf , & pend , 10 );
1170
+ if (* pend || pend == s -> answer .buf )
1171
+ err (s , _ ("Invalid number: '%s'" ),
1172
+ s -> answer .buf );
1173
+ else if (0 < response && response <= file_diff -> hunk_nr )
1174
+ hunk_index = response - 1 ;
1175
+ else
1176
+ err (s , Q_ ("Sorry, only %d hunk available." ,
1177
+ "Sorry, only %d hunks available." ,
1178
+ file_diff -> hunk_nr ),
1179
+ (int )file_diff -> hunk_nr );
1092
1180
} else if (s -> answer .buf [0 ] == 's' ) {
1093
1181
size_t splittable_into = hunk -> splittable_into ;
1094
1182
if (splittable_into < 2 )
0 commit comments