summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLibravatar Johannes Schindelin <johannes.schindelin@gmx.de>2019-12-13 08:07:55 +0000
committerLibravatar Junio C Hamano <gitster@pobox.com>2019-12-13 12:37:13 -0800
commit47dc4fd5eb4ab8fbe8ea6bb10e35d398da991cea (patch)
treec0fcdbfd88ae033016bd49dd82f23db9955028e7
parentbuilt-in add -p: support multi-file diffs (diff)
downloadtgif-47dc4fd5eb4ab8fbe8ea6bb10e35d398da991cea.tar.xz
built-in add -p: handle deleted empty files
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>
-rw-r--r--add-patch.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/add-patch.c b/add-patch.c
index 7c1b3b3935..c32541f46d 100644
--- a/add-patch.c
+++ b/add-patch.c
@@ -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;
}