@@ -465,7 +465,7 @@ static int parse_diff(struct add_p_state *s, const struct pathspec *ps)
465465 pend = p + plain -> len ;
466466 while (p != pend ) {
467467 char * eol = memchr (p , '\n' , pend - p );
468- const char * deleted = NULL , * added = NULL , * mode_change = NULL ;
468+ const char * deleted = NULL , * mode_change = NULL ;
469469
470470 if (!eol )
471471 eol = pend ;
@@ -482,12 +482,11 @@ static int parse_diff(struct add_p_state *s, const struct pathspec *ps)
482482 } else if (p == plain -> buf )
483483 BUG ("diff starts with unexpected line:\n"
484484 "%.*s\n" , (int )(eol - p ), p );
485- else if (file_diff -> deleted || file_diff -> added )
485+ else if (file_diff -> deleted )
486486 ; /* keep the rest of the file in a single "hunk" */
487487 else if (starts_with (p , "@@ " ) ||
488488 (hunk == & file_diff -> head &&
489- (skip_prefix (p , "deleted file" , & deleted ) ||
490- skip_prefix (p , "new file" , & added )))) {
489+ (skip_prefix (p , "deleted file" , & deleted )))) {
491490 if (marker == '-' || marker == '+' )
492491 /*
493492 * Should not happen; previous hunk did not end
@@ -505,8 +504,6 @@ static int parse_diff(struct add_p_state *s, const struct pathspec *ps)
505504
506505 if (deleted )
507506 file_diff -> deleted = 1 ;
508- else if (added )
509- file_diff -> added = 1 ;
510507 else if (parse_hunk_header (s , hunk ) < 0 )
511508 return -1 ;
512509
@@ -515,6 +512,9 @@ static int parse_diff(struct add_p_state *s, const struct pathspec *ps)
515512 * split
516513 */
517514 marker = * p ;
515+ } else if (hunk == & file_diff -> head &&
516+ starts_with (p , "new file" )) {
517+ file_diff -> added = 1 ;
518518 } else if (hunk == & file_diff -> head &&
519519 skip_prefix (p , "old mode " , & mode_change ) &&
520520 is_octal (mode_change , eol - mode_change )) {
@@ -1376,7 +1376,8 @@ static int patch_update_file(struct add_p_state *s,
13761376 ALLOW_EDIT = 1 << 6
13771377 } permitted = 0 ;
13781378
1379- if (!file_diff -> hunk_nr )
1379+ /* Empty added files have no hunks */
1380+ if (!file_diff -> hunk_nr && !file_diff -> added )
13801381 return 0 ;
13811382
13821383 strbuf_reset (& s -> buf );
@@ -1385,60 +1386,66 @@ static int patch_update_file(struct add_p_state *s,
13851386 for (;;) {
13861387 if (hunk_index >= file_diff -> hunk_nr )
13871388 hunk_index = 0 ;
1388- hunk = file_diff -> hunk + hunk_index ;
1389-
1389+ hunk = file_diff -> hunk_nr
1390+ ? file_diff -> hunk + hunk_index
1391+ : & file_diff -> head ;
13901392 undecided_previous = -1 ;
1391- for (i = hunk_index - 1 ; i >= 0 ; i -- )
1392- if (file_diff -> hunk [i ].use == UNDECIDED_HUNK ) {
1393- undecided_previous = i ;
1394- break ;
1395- }
1396-
13971393 undecided_next = -1 ;
1398- for (i = hunk_index + 1 ; i < file_diff -> hunk_nr ; i ++ )
1399- if (file_diff -> hunk [i ].use == UNDECIDED_HUNK ) {
1400- undecided_next = i ;
1401- break ;
1402- }
1394+
1395+ if (file_diff -> hunk_nr ) {
1396+ for (i = hunk_index - 1 ; i >= 0 ; i -- )
1397+ if (file_diff -> hunk [i ].use == UNDECIDED_HUNK ) {
1398+ undecided_previous = i ;
1399+ break ;
1400+ }
1401+
1402+ for (i = hunk_index + 1 ; i < file_diff -> hunk_nr ; i ++ )
1403+ if (file_diff -> hunk [i ].use == UNDECIDED_HUNK ) {
1404+ undecided_next = i ;
1405+ break ;
1406+ }
1407+ }
14031408
14041409 /* Everything decided? */
14051410 if (undecided_previous < 0 && undecided_next < 0 &&
14061411 hunk -> use != UNDECIDED_HUNK )
14071412 break ;
14081413
14091414 strbuf_reset (& s -> buf );
1410- render_hunk (s , hunk , 0 , colored , & s -> buf );
1411- fputs (s -> buf .buf , stdout );
1415+ if (file_diff -> hunk_nr ) {
1416+ render_hunk (s , hunk , 0 , colored , & s -> buf );
1417+ fputs (s -> buf .buf , stdout );
14121418
1413- strbuf_reset (& s -> buf );
1414- if (undecided_previous >= 0 ) {
1415- permitted |= ALLOW_GOTO_PREVIOUS_UNDECIDED_HUNK ;
1416- strbuf_addstr (& s -> buf , ",k" );
1417- }
1418- if (hunk_index ) {
1419- permitted |= ALLOW_GOTO_PREVIOUS_HUNK ;
1420- strbuf_addstr (& s -> buf , ",K" );
1421- }
1422- if (undecided_next >= 0 ) {
1423- permitted |= ALLOW_GOTO_NEXT_UNDECIDED_HUNK ;
1424- strbuf_addstr (& s -> buf , ",j" );
1425- }
1426- if (hunk_index + 1 < file_diff -> hunk_nr ) {
1427- permitted |= ALLOW_GOTO_NEXT_HUNK ;
1428- strbuf_addstr (& s -> buf , ",J" );
1429- }
1430- if (file_diff -> hunk_nr > 1 ) {
1431- permitted |= ALLOW_SEARCH_AND_GOTO ;
1432- strbuf_addstr (& s -> buf , ",g,/" );
1433- }
1434- if (hunk -> splittable_into > 1 ) {
1435- permitted |= ALLOW_SPLIT ;
1436- strbuf_addstr (& s -> buf , ",s" );
1437- }
1438- if (hunk_index + 1 > file_diff -> mode_change &&
1439- !file_diff -> deleted ) {
1440- permitted |= ALLOW_EDIT ;
1441- strbuf_addstr (& s -> buf , ",e" );
1419+ strbuf_reset (& s -> buf );
1420+ if (undecided_previous >= 0 ) {
1421+ permitted |= ALLOW_GOTO_PREVIOUS_UNDECIDED_HUNK ;
1422+ strbuf_addstr (& s -> buf , ",k" );
1423+ }
1424+ if (hunk_index ) {
1425+ permitted |= ALLOW_GOTO_PREVIOUS_HUNK ;
1426+ strbuf_addstr (& s -> buf , ",K" );
1427+ }
1428+ if (undecided_next >= 0 ) {
1429+ permitted |= ALLOW_GOTO_NEXT_UNDECIDED_HUNK ;
1430+ strbuf_addstr (& s -> buf , ",j" );
1431+ }
1432+ if (hunk_index + 1 < file_diff -> hunk_nr ) {
1433+ permitted |= ALLOW_GOTO_NEXT_HUNK ;
1434+ strbuf_addstr (& s -> buf , ",J" );
1435+ }
1436+ if (file_diff -> hunk_nr > 1 ) {
1437+ permitted |= ALLOW_SEARCH_AND_GOTO ;
1438+ strbuf_addstr (& s -> buf , ",g,/" );
1439+ }
1440+ if (hunk -> splittable_into > 1 ) {
1441+ permitted |= ALLOW_SPLIT ;
1442+ strbuf_addstr (& s -> buf , ",s" );
1443+ }
1444+ if (hunk_index + 1 > file_diff -> mode_change &&
1445+ !file_diff -> deleted ) {
1446+ permitted |= ALLOW_EDIT ;
1447+ strbuf_addstr (& s -> buf , ",e" );
1448+ }
14421449 }
14431450 if (file_diff -> deleted )
14441451 prompt_mode_type = PROMPT_DELETION ;
@@ -1452,7 +1459,9 @@ static int patch_update_file(struct add_p_state *s,
14521459 color_fprintf (stdout , s -> s .prompt_color ,
14531460 "(%" PRIuMAX "/%" PRIuMAX ") " ,
14541461 (uintmax_t )hunk_index + 1 ,
1455- (uintmax_t )file_diff -> hunk_nr );
1462+ (uintmax_t )(file_diff -> hunk_nr
1463+ ? file_diff -> hunk_nr
1464+ : 1 ));
14561465 color_fprintf (stdout , s -> s .prompt_color ,
14571466 _ (s -> mode -> prompt_mode [prompt_mode_type ]),
14581467 s -> buf .buf );
@@ -1472,16 +1481,24 @@ static int patch_update_file(struct add_p_state *s,
14721481 hunk -> use = SKIP_HUNK ;
14731482 goto soft_increment ;
14741483 } else if (ch == 'a' ) {
1475- for (; hunk_index < file_diff -> hunk_nr ; hunk_index ++ ) {
1476- hunk = file_diff -> hunk + hunk_index ;
1477- if (hunk -> use == UNDECIDED_HUNK )
1478- hunk -> use = USE_HUNK ;
1484+ if (file_diff -> hunk_nr ) {
1485+ for (; hunk_index < file_diff -> hunk_nr ; hunk_index ++ ) {
1486+ hunk = file_diff -> hunk + hunk_index ;
1487+ if (hunk -> use == UNDECIDED_HUNK )
1488+ hunk -> use = USE_HUNK ;
1489+ }
1490+ } else if (hunk -> use == UNDECIDED_HUNK ) {
1491+ hunk -> use = USE_HUNK ;
14791492 }
14801493 } else if (ch == 'd' || ch == 'q' ) {
1481- for (; hunk_index < file_diff -> hunk_nr ; hunk_index ++ ) {
1482- hunk = file_diff -> hunk + hunk_index ;
1483- if (hunk -> use == UNDECIDED_HUNK )
1484- hunk -> use = SKIP_HUNK ;
1494+ if (file_diff -> hunk_nr ) {
1495+ for (; hunk_index < file_diff -> hunk_nr ; hunk_index ++ ) {
1496+ hunk = file_diff -> hunk + hunk_index ;
1497+ if (hunk -> use == UNDECIDED_HUNK )
1498+ hunk -> use = SKIP_HUNK ;
1499+ }
1500+ } else if (hunk -> use == UNDECIDED_HUNK ) {
1501+ hunk -> use = SKIP_HUNK ;
14851502 }
14861503 if (ch == 'q' ) {
14871504 quit = 1 ;
@@ -1639,7 +1656,8 @@ static int patch_update_file(struct add_p_state *s,
16391656 if (file_diff -> hunk [i ].use == USE_HUNK )
16401657 break ;
16411658
1642- if (i < file_diff -> hunk_nr ) {
1659+ if (i < file_diff -> hunk_nr ||
1660+ (!file_diff -> hunk_nr && file_diff -> head .use == USE_HUNK )) {
16431661 /* At least one hunk selected: apply */
16441662 strbuf_reset (& s -> buf );
16451663 reassemble_patch (s , file_diff , 0 , & s -> buf );
0 commit comments