]> git.ipfire.org Git - thirdparty/git.git/commitdiff
built-in add -p: handle deleted empty files
authorJohannes Schindelin <johannes.schindelin@gmx.de>
Fri, 13 Dec 2019 08:07:55 +0000 (08:07 +0000)
committerJunio C Hamano <gitster@pobox.com>
Fri, 13 Dec 2019 20:37:13 +0000 (12:37 -0800)
This addresses the same problem as 24ab81ae4d (add-interactive: handle
deletion of empty files, 2009-10-27), although in a different way: we
not only stick the "deleted file" line into its own pseudo hunk, but
also the entire remainder (if any) of the same diff.

That way, we do not have to play any funny games with regards to
coalescing the diff after the user selected what (possibly pseudo-)hunks
to stage.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
add-patch.c

index 7c1b3b3935f09d6cd35af8448d7a1993de8e0c17..c32541f46d7ad19860709571d50ca01a63a65e3c 100644 (file)
@@ -33,6 +33,7 @@ struct add_p_state {
                struct hunk head;
                struct hunk *hunk;
                size_t hunk_nr, hunk_alloc;
+               unsigned deleted:1;
        } *file_diff;
        size_t file_diff_nr;
 };
@@ -180,6 +181,8 @@ 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;
+
                if (!eol)
                        eol = pend;
 
@@ -196,7 +199,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 (starts_with(p, "@@ ")) {
+               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))) {
                        file_diff->hunk_nr++;
                        ALLOC_GROW(file_diff->hunk, file_diff->hunk_nr,
                                   file_diff->hunk_alloc);
@@ -207,7 +214,9 @@ static int parse_diff(struct add_p_state *s, const struct pathspec *ps)
                        if (colored)
                                hunk->colored_start = colored_p - colored->buf;
 
-                       if (parse_hunk_header(s, hunk) < 0)
+                       if (deleted)
+                               file_diff->deleted = 1;
+                       else if (parse_hunk_header(s, hunk) < 0)
                                return -1;
                }