# [PATCH] add-patch: stop getting confused by deletions of binary files

1 messages from 2025-12-10 to 2025-12-10. Participants: Ahelenia Ziemiańska.
Thread: https://gitlist.dev/t/64609

## Ahelenia Ziemiańska, 2025-12-10 23:50

Subject: [PATCH] add-patch: stop getting confused by deletions of binary files
Message-ID: <lfh7rez2sgajamk632sea2s6sm65vbllxuvi6shihdgmtwvdmh@tarta.nabijaczleweli.xyz>
URL: https://gitlist.dev/e/lfh7rez2sgajamk632sea2s6sm65vbllxuvi6shihdgmtwvdmh%40tarta.nabijaczleweli.xyz

```
git add -p can't handle binary files and ignores them:
  $ git init
  $ printf 'a\0' > a
  $ printf 'b\0' > b
  $ git add .
  $ git commit -m a
  $ printf 'A\0' > a
  $ rm b
  $ git add -p
  diff --git a/b b/b
  deleted file mode 100644
  index 28eacf2..0000000
  Binary files a/b and /dev/null differ
  (1/1) Stage deletion [y,n,q,a,d,?]? y
  error: cannot apply binary patch to 'b' without full index line
  error: b: patch does not apply
  error: 'git apply' failed
but didn't do this for deletions of binary files.

The parsed diff looks like
  diff --git a/a b/a
  index 90802fe..e2b43e3 100644
  Binary files a/a and b/a differ
  diff --git a/b b/b
  deleted file mode 100644
  index 28eacf2..0000000
  Binary files a/b and /dev/null differ
which ended up with
  a: binary=1 deleted=0 hunk_nr=0
  b: binary=0 deleted=1 hunk_nr=1

Seeing "deleted file" inserts a hunk and prevented detecting
the "Binary files" header, so detect it even in this case:
  b: binary=1 deleted=1 hunk_nr=1

We can't do anything useful to binary files anyway,
so skip them regardless of how many hunks they seem to have.

This makes the final add -p in the scenario above exit with
"Only binary files changed.".

Closes: https://bugs.debian.org/1122502
Signed-off-by: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz>
---
 add-patch.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git add-patch.c add-patch.c
index 173a53241e..2e1ea2cb33 100644
--- add-patch.c
+++ add-patch.c
@@ -518,9 +518,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)
-			; /* keep the rest of the file in a single "hunk" */
-		else if (starts_with(p, "@@ ") ||
+		else if (file_diff->deleted) {
+			/* keep the rest of the file in a single "hunk" */
+			if (starts_with(p, "Binary files "))
+				file_diff->binary = 1;
+		} else if (starts_with(p, "@@ ") ||
 			 (hunk == &file_diff->head &&
 			  (skip_prefix(p, "deleted file", &deleted)))) {
 			if (marker == '-' || marker == '+')
@@ -1853,7 +1855,7 @@ int run_add_p(struct repository *r, enum add_p_mode mode,
 	}
 
 	for (i = 0; i < s.file_diff_nr; i++)
-		if (s.file_diff[i].binary && !s.file_diff[i].hunk_nr)
+		if (s.file_diff[i].binary)
 			binary_count++;
 		else if (patch_update_file(&s, s.file_diff + i))
 			break;
-- 
2.39.5

```
