X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=add-patch.c;h=bd94bd3a7c9e86f4af6d9b887c824ff5be2db9a5;hb=1b7ac4e6d4d490b224f5206af7418ed74e490608;hp=cd5cfc93fad5a04643718edd56b65326b51ff7ee;hpb=45f462b5c5a55039c35fc7001f2256329220bf4f;p=thirdparty%2Fgit.git diff --git a/add-patch.c b/add-patch.c index cd5cfc93fa..bd94bd3a7c 100644 --- a/add-patch.c +++ b/add-patch.c @@ -465,7 +465,7 @@ static int parse_diff(struct add_p_state *s, const struct pathspec *ps) pend = p + plain->len; while (p != pend) { char *eol = memchr(p, '\n', pend - p); - const char *deleted = NULL, *added = NULL, *mode_change = NULL; + const char *deleted = NULL, *mode_change = NULL; if (!eol) eol = pend; @@ -482,12 +482,11 @@ static int parse_diff(struct add_p_state *s, const struct pathspec *ps) } else if (p == plain->buf) BUG("diff starts with unexpected line:\n" "%.*s\n", (int)(eol - p), p); - else if (file_diff->deleted || file_diff->added) + else if (file_diff->deleted) ; /* keep the rest of the file in a single "hunk" */ else if (starts_with(p, "@@ ") || (hunk == &file_diff->head && - (skip_prefix(p, "deleted file", &deleted) || - skip_prefix(p, "new file", &added)))) { + (skip_prefix(p, "deleted file", &deleted)))) { if (marker == '-' || marker == '+') /* * 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) if (deleted) file_diff->deleted = 1; - else if (added) - file_diff->added = 1; else if (parse_hunk_header(s, hunk) < 0) return -1; @@ -515,6 +512,9 @@ static int parse_diff(struct add_p_state *s, const struct pathspec *ps) * split */ marker = *p; + } else if (hunk == &file_diff->head && + starts_with(p, "new file")) { + file_diff->added = 1; } else if (hunk == &file_diff->head && skip_prefix(p, "old mode ", &mode_change) && is_octal(mode_change, eol - mode_change)) { @@ -1376,7 +1376,8 @@ static int patch_update_file(struct add_p_state *s, ALLOW_EDIT = 1 << 6 } permitted = 0; - if (!file_diff->hunk_nr) + /* Empty added files have no hunks */ + if (!file_diff->hunk_nr && !file_diff->added) return 0; strbuf_reset(&s->buf); @@ -1385,21 +1386,25 @@ static int patch_update_file(struct add_p_state *s, for (;;) { if (hunk_index >= file_diff->hunk_nr) hunk_index = 0; - hunk = file_diff->hunk + hunk_index; - + hunk = file_diff->hunk_nr + ? file_diff->hunk + hunk_index + : &file_diff->head; undecided_previous = -1; - for (i = hunk_index - 1; i >= 0; i--) - if (file_diff->hunk[i].use == UNDECIDED_HUNK) { - undecided_previous = i; - break; - } - undecided_next = -1; - for (i = hunk_index + 1; i < file_diff->hunk_nr; i++) - if (file_diff->hunk[i].use == UNDECIDED_HUNK) { - undecided_next = i; - break; - } + + if (file_diff->hunk_nr) { + for (i = hunk_index - 1; i >= 0; i--) + if (file_diff->hunk[i].use == UNDECIDED_HUNK) { + undecided_previous = i; + break; + } + + for (i = hunk_index + 1; i < file_diff->hunk_nr; i++) + if (file_diff->hunk[i].use == UNDECIDED_HUNK) { + undecided_next = i; + break; + } + } /* Everything decided? */ if (undecided_previous < 0 && undecided_next < 0 && @@ -1407,38 +1412,40 @@ static int patch_update_file(struct add_p_state *s, break; strbuf_reset(&s->buf); - render_hunk(s, hunk, 0, colored, &s->buf); - fputs(s->buf.buf, stdout); + if (file_diff->hunk_nr) { + render_hunk(s, hunk, 0, colored, &s->buf); + fputs(s->buf.buf, stdout); - strbuf_reset(&s->buf); - if (undecided_previous >= 0) { - permitted |= ALLOW_GOTO_PREVIOUS_UNDECIDED_HUNK; - strbuf_addstr(&s->buf, ",k"); - } - if (hunk_index) { - permitted |= ALLOW_GOTO_PREVIOUS_HUNK; - strbuf_addstr(&s->buf, ",K"); - } - if (undecided_next >= 0) { - permitted |= ALLOW_GOTO_NEXT_UNDECIDED_HUNK; - strbuf_addstr(&s->buf, ",j"); - } - if (hunk_index + 1 < file_diff->hunk_nr) { - permitted |= ALLOW_GOTO_NEXT_HUNK; - strbuf_addstr(&s->buf, ",J"); - } - if (file_diff->hunk_nr > 1) { - permitted |= ALLOW_SEARCH_AND_GOTO; - strbuf_addstr(&s->buf, ",g,/"); - } - if (hunk->splittable_into > 1) { - permitted |= ALLOW_SPLIT; - strbuf_addstr(&s->buf, ",s"); - } - if (hunk_index + 1 > file_diff->mode_change && - !file_diff->deleted) { - permitted |= ALLOW_EDIT; - strbuf_addstr(&s->buf, ",e"); + strbuf_reset(&s->buf); + if (undecided_previous >= 0) { + permitted |= ALLOW_GOTO_PREVIOUS_UNDECIDED_HUNK; + strbuf_addstr(&s->buf, ",k"); + } + if (hunk_index) { + permitted |= ALLOW_GOTO_PREVIOUS_HUNK; + strbuf_addstr(&s->buf, ",K"); + } + if (undecided_next >= 0) { + permitted |= ALLOW_GOTO_NEXT_UNDECIDED_HUNK; + strbuf_addstr(&s->buf, ",j"); + } + if (hunk_index + 1 < file_diff->hunk_nr) { + permitted |= ALLOW_GOTO_NEXT_HUNK; + strbuf_addstr(&s->buf, ",J"); + } + if (file_diff->hunk_nr > 1) { + permitted |= ALLOW_SEARCH_AND_GOTO; + strbuf_addstr(&s->buf, ",g,/"); + } + if (hunk->splittable_into > 1) { + permitted |= ALLOW_SPLIT; + strbuf_addstr(&s->buf, ",s"); + } + if (hunk_index + 1 > file_diff->mode_change && + !file_diff->deleted) { + permitted |= ALLOW_EDIT; + strbuf_addstr(&s->buf, ",e"); + } } if (file_diff->deleted) prompt_mode_type = PROMPT_DELETION; @@ -1452,7 +1459,9 @@ static int patch_update_file(struct add_p_state *s, color_fprintf(stdout, s->s.prompt_color, "(%"PRIuMAX"/%"PRIuMAX") ", (uintmax_t)hunk_index + 1, - (uintmax_t)file_diff->hunk_nr); + (uintmax_t)(file_diff->hunk_nr + ? file_diff->hunk_nr + : 1)); color_fprintf(stdout, s->s.prompt_color, _(s->mode->prompt_mode[prompt_mode_type]), s->buf.buf); @@ -1472,16 +1481,24 @@ soft_increment: hunk->use = SKIP_HUNK; goto soft_increment; } else if (ch == 'a') { - for (; hunk_index < file_diff->hunk_nr; hunk_index++) { - hunk = file_diff->hunk + hunk_index; - if (hunk->use == UNDECIDED_HUNK) - hunk->use = USE_HUNK; + if (file_diff->hunk_nr) { + for (; hunk_index < file_diff->hunk_nr; hunk_index++) { + hunk = file_diff->hunk + hunk_index; + if (hunk->use == UNDECIDED_HUNK) + hunk->use = USE_HUNK; + } + } else if (hunk->use == UNDECIDED_HUNK) { + hunk->use = USE_HUNK; } } else if (ch == 'd' || ch == 'q') { - for (; hunk_index < file_diff->hunk_nr; hunk_index++) { - hunk = file_diff->hunk + hunk_index; - if (hunk->use == UNDECIDED_HUNK) - hunk->use = SKIP_HUNK; + if (file_diff->hunk_nr) { + for (; hunk_index < file_diff->hunk_nr; hunk_index++) { + hunk = file_diff->hunk + hunk_index; + if (hunk->use == UNDECIDED_HUNK) + hunk->use = SKIP_HUNK; + } + } else if (hunk->use == UNDECIDED_HUNK) { + hunk->use = SKIP_HUNK; } if (ch == 'q') { quit = 1; @@ -1639,7 +1656,8 @@ soft_increment: if (file_diff->hunk[i].use == USE_HUNK) break; - if (i < file_diff->hunk_nr) { + if (i < file_diff->hunk_nr || + (!file_diff->hunk_nr && file_diff->head.use == USE_HUNK)) { /* At least one hunk selected: apply */ strbuf_reset(&s->buf); reassemble_patch(s, file_diff, 0, &s->buf);