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