@@ -457,11 +457,9 @@ static int parse_diff(struct add_p_state *s, const struct pathspec *ps)
457457 eol = pend ;
458458
459459 if (starts_with (p , "diff " )) {
460- s -> file_diff_nr ++ ;
461- ALLOC_GROW (s -> file_diff , s -> file_diff_nr ,
460+ ALLOC_GROW_BY (s -> file_diff , s -> file_diff_nr , 1 ,
462461 file_diff_alloc );
463462 file_diff = s -> file_diff + s -> file_diff_nr - 1 ;
464- memset (file_diff , 0 , sizeof (* file_diff ));
465463 hunk = & file_diff -> head ;
466464 hunk -> start = p - plain -> buf ;
467465 if (colored_p )
@@ -483,11 +481,9 @@ static int parse_diff(struct add_p_state *s, const struct pathspec *ps)
483481 */
484482 hunk -> splittable_into ++ ;
485483
486- file_diff -> hunk_nr ++ ;
487- ALLOC_GROW (file_diff -> hunk , file_diff -> hunk_nr ,
484+ ALLOC_GROW_BY (file_diff -> hunk , file_diff -> hunk_nr , 1 ,
488485 file_diff -> hunk_alloc );
489486 hunk = file_diff -> hunk + file_diff -> hunk_nr - 1 ;
490- memset (hunk , 0 , sizeof (* hunk ));
491487
492488 hunk -> start = p - plain -> buf ;
493489 if (colored )
@@ -511,7 +507,7 @@ static int parse_diff(struct add_p_state *s, const struct pathspec *ps)
511507 if (file_diff -> mode_change )
512508 BUG ("double mode change?\n\n%.*s" ,
513509 (int )(eol - plain -> buf ), plain -> buf );
514- if (file_diff -> hunk_nr ++ )
510+ if (file_diff -> hunk_nr )
515511 BUG ("mode change in the middle?\n\n%.*s" ,
516512 (int )(eol - plain -> buf ), plain -> buf );
517513
@@ -520,9 +516,8 @@ static int parse_diff(struct add_p_state *s, const struct pathspec *ps)
520516 * is _part of_ the header "hunk".
521517 */
522518 file_diff -> mode_change = 1 ;
523- ALLOC_GROW (file_diff -> hunk , file_diff -> hunk_nr ,
519+ ALLOC_GROW_BY (file_diff -> hunk , file_diff -> hunk_nr , 1 ,
524520 file_diff -> hunk_alloc );
525- memset (file_diff -> hunk , 0 , sizeof (struct hunk ));
526521 file_diff -> hunk -> start = p - plain -> buf ;
527522 if (colored_p )
528523 file_diff -> hunk -> colored_start =
@@ -1357,6 +1352,15 @@ static int patch_update_file(struct add_p_state *s,
13571352 struct child_process cp = CHILD_PROCESS_INIT ;
13581353 int colored = !!s -> colored .len , quit = 0 ;
13591354 enum prompt_mode_type prompt_mode_type ;
1355+ enum {
1356+ ALLOW_GOTO_PREVIOUS_HUNK = 1 << 0 ,
1357+ ALLOW_GOTO_PREVIOUS_UNDECIDED_HUNK = 1 << 1 ,
1358+ ALLOW_GOTO_NEXT_HUNK = 1 << 2 ,
1359+ ALLOW_GOTO_NEXT_UNDECIDED_HUNK = 1 << 3 ,
1360+ ALLOW_SEARCH_AND_GOTO = 1 << 4 ,
1361+ ALLOW_SPLIT = 1 << 5 ,
1362+ ALLOW_EDIT = 1 << 6
1363+ } permitted = 0 ;
13601364
13611365 if (!file_diff -> hunk_nr )
13621366 return 0 ;
@@ -1393,22 +1397,35 @@ static int patch_update_file(struct add_p_state *s,
13931397 fputs (s -> buf .buf , stdout );
13941398
13951399 strbuf_reset (& s -> buf );
1396- if (undecided_previous >= 0 )
1400+ if (undecided_previous >= 0 ) {
1401+ permitted |= ALLOW_GOTO_PREVIOUS_UNDECIDED_HUNK ;
13971402 strbuf_addstr (& s -> buf , ",k" );
1398- if (hunk_index )
1403+ }
1404+ if (hunk_index ) {
1405+ permitted |= ALLOW_GOTO_PREVIOUS_HUNK ;
13991406 strbuf_addstr (& s -> buf , ",K" );
1400- if (undecided_next >= 0 )
1407+ }
1408+ if (undecided_next >= 0 ) {
1409+ permitted |= ALLOW_GOTO_NEXT_UNDECIDED_HUNK ;
14011410 strbuf_addstr (& s -> buf , ",j" );
1402- if (hunk_index + 1 < file_diff -> hunk_nr )
1411+ }
1412+ if (hunk_index + 1 < file_diff -> hunk_nr ) {
1413+ permitted |= ALLOW_GOTO_NEXT_HUNK ;
14031414 strbuf_addstr (& s -> buf , ",J" );
1404- if (file_diff -> hunk_nr > 1 )
1415+ }
1416+ if (file_diff -> hunk_nr > 1 ) {
1417+ permitted |= ALLOW_SEARCH_AND_GOTO ;
14051418 strbuf_addstr (& s -> buf , ",g,/" );
1406- if (hunk -> splittable_into > 1 )
1419+ }
1420+ if (hunk -> splittable_into > 1 ) {
1421+ permitted |= ALLOW_SPLIT ;
14071422 strbuf_addstr (& s -> buf , ",s" );
1423+ }
14081424 if (hunk_index + 1 > file_diff -> mode_change &&
1409- !file_diff -> deleted )
1425+ !file_diff -> deleted ) {
1426+ permitted |= ALLOW_EDIT ;
14101427 strbuf_addstr (& s -> buf , ",e" );
1411-
1428+ }
14121429 if (file_diff -> deleted )
14131430 prompt_mode_type = PROMPT_DELETION ;
14141431 else if (file_diff -> added )
@@ -1457,30 +1474,30 @@ static int patch_update_file(struct add_p_state *s,
14571474 break ;
14581475 }
14591476 } else if (s -> answer .buf [0 ] == 'K' ) {
1460- if (hunk_index )
1477+ if (permitted & ALLOW_GOTO_PREVIOUS_HUNK )
14611478 hunk_index -- ;
14621479 else
14631480 err (s , _ ("No previous hunk" ));
14641481 } else if (s -> answer .buf [0 ] == 'J' ) {
1465- if (hunk_index + 1 < file_diff -> hunk_nr )
1482+ if (permitted & ALLOW_GOTO_NEXT_HUNK )
14661483 hunk_index ++ ;
14671484 else
14681485 err (s , _ ("No next hunk" ));
14691486 } else if (s -> answer .buf [0 ] == 'k' ) {
1470- if (undecided_previous >= 0 )
1487+ if (permitted & ALLOW_GOTO_PREVIOUS_UNDECIDED_HUNK )
14711488 hunk_index = undecided_previous ;
14721489 else
14731490 err (s , _ ("No previous hunk" ));
14741491 } else if (s -> answer .buf [0 ] == 'j' ) {
1475- if (undecided_next >= 0 )
1492+ if (permitted & ALLOW_GOTO_NEXT_UNDECIDED_HUNK )
14761493 hunk_index = undecided_next ;
14771494 else
14781495 err (s , _ ("No next hunk" ));
14791496 } else if (s -> answer .buf [0 ] == 'g' ) {
14801497 char * pend ;
14811498 unsigned long response ;
14821499
1483- if (file_diff -> hunk_nr < 2 ) {
1500+ if (!( permitted & ALLOW_SEARCH_AND_GOTO ) ) {
14841501 err (s , _ ("No other hunks to goto" ));
14851502 continue ;
14861503 }
@@ -1517,7 +1534,7 @@ static int patch_update_file(struct add_p_state *s,
15171534 regex_t regex ;
15181535 int ret ;
15191536
1520- if (file_diff -> hunk_nr < 2 ) {
1537+ if (!( permitted & ALLOW_SEARCH_AND_GOTO ) ) {
15211538 err (s , _ ("No other hunks to search" ));
15221539 continue ;
15231540 }
@@ -1562,15 +1579,15 @@ static int patch_update_file(struct add_p_state *s,
15621579 hunk_index = i ;
15631580 } else if (s -> answer .buf [0 ] == 's' ) {
15641581 size_t splittable_into = hunk -> splittable_into ;
1565- if (splittable_into < 2 )
1582+ if (!( permitted & ALLOW_SPLIT ) )
15661583 err (s , _ ("Sorry, cannot split this hunk" ));
15671584 else if (!split_hunk (s , file_diff ,
15681585 hunk - file_diff -> hunk ))
15691586 color_fprintf_ln (stdout , s -> s .header_color ,
15701587 _ ("Split into %d hunks." ),
15711588 (int )splittable_into );
15721589 } else if (s -> answer .buf [0 ] == 'e' ) {
1573- if (hunk_index + 1 == file_diff -> mode_change )
1590+ if (!( permitted & ALLOW_EDIT ) )
15741591 err (s , _ ("Sorry, cannot edit this hunk" ));
15751592 else if (edit_hunk_loop (s , file_diff , hunk ) >= 0 ) {
15761593 hunk -> use = USE_HUNK ;
0 commit comments