Skip to content

Commit cce5178

Browse files
committed
Merge branch 'pw/add-p-allowed-options-fix'
"git add -p" update. * pw/add-p-allowed-options-fix: add -p: fix checking of user input add -p: use ALLOC_GROW_BY instead of ALLOW_GROW
2 parents bdccf5e + ce91028 commit cce5178

File tree

1 file changed

+42
-25
lines changed

1 file changed

+42
-25
lines changed

add-patch.c

Lines changed: 42 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)