# [PATCH] add-interactive: handle deletion of empty files

2 messages from 2009-10-28 to 2009-10-28. Participants: Jeff King, Junio C Hamano.
Thread: https://gitlist.dev/t/21393

## Jeff King, 2009-10-28 00:52

Subject: [PATCH] add-interactive: handle deletion of empty files
Message-ID: <20091028005257.GA5002@sigill.intra.peff.net>
URL: https://gitlist.dev/e/20091028005257.GA5002%40sigill.intra.peff.net

```
Usually we show deletion as a big hunk deleting all of the
file's text. However, for files with no content, the diff
shows just the 'deleted file mode ...' line. This patch
cause "add -p" (and related commands) to recognize that line
and explicitly ask about deleting the file.

We only add the "stage this deletion" hunk for empty files,
since other files will already ask about the big content
deletion hunk. We could also change those files to simply
display "stage this deletion", but showing the actual
deleted content is probably what an interactive user wants.

Signed-off-by: Jeff King <peff@peff.net>
---
This bit me today. I expect it's pretty rare, but I don't see a reason
not to handle the corner case (and nor do I see a reason to change the
non-corner case, as explained above).

 git-add--interactive.perl  |   18 +++++++++++++-----
 t/t3701-add-interactive.sh |   17 +++++++++++++++++
 2 files changed, 30 insertions(+), 5 deletions(-)

diff --git a/git-add--interactive.perl b/git-add--interactive.perl
index 69aeaf0..8ce1ec9 100755
--- a/git-add--interactive.perl
+++ b/git-add--interactive.perl
@@ -731,14 +731,17 @@ sub parse_diff_header {
 
 	my $head = { TEXT => [], DISPLAY => [], TYPE => 'header' };
 	my $mode = { TEXT => [], DISPLAY => [], TYPE => 'mode' };
+	my $deletion = { TEXT => [], DISPLAY => [], TYPE => 'deletion' };
 
 	for (my $i = 0; $i < @{$src->{TEXT}}; $i++) {
-		my $dest = $src->{TEXT}->[$i] =~ /^(old|new) mode (\d+)$/ ?
-			$mode : $head;
+		my $dest =
+		   $src->{TEXT}->[$i] =~ /^(old|new) mode (\d+)$/ ? $mode :
+		   $src->{TEXT}->[$i] =~ /^deleted file/ ? $deletion :
+		   $head;
 		push @{$dest->{TEXT}}, $src->{TEXT}->[$i];
 		push @{$dest->{DISPLAY}}, $src->{DISPLAY}->[$i];
 	}
-	return ($head, $mode);
+	return ($head, $mode, $deletion);
 }
 
 sub hunk_splittable {
@@ -1206,7 +1209,7 @@ sub patch_update_file {
 	my ($ix, $num);
 	my $path = shift;
 	my ($head, @hunk) = parse_diff($path);
-	($head, my $mode) = parse_diff_header($head);
+	($head, my $mode, my $deletion) = parse_diff_header($head);
 	for (@{$head->{DISPLAY}}) {
 		print;
 	}
@@ -1214,6 +1217,9 @@ sub patch_update_file {
 	if (@{$mode->{TEXT}}) {
 		unshift @hunk, $mode;
 	}
+	if (@{$deletion->{TEXT}} && !@hunk) {
+		@hunk = ($deletion);
+	}
 
 	$num = scalar @hunk;
 	$ix = 0;
@@ -1267,7 +1273,9 @@ sub patch_update_file {
 			print;
 		}
 		print colored $prompt_color, $patch_mode_flavour{VERB},
-		  ($hunk[$ix]{TYPE} eq 'mode' ? ' mode change' : ' this hunk'),
+		  ($hunk[$ix]{TYPE} eq 'mode' ? ' mode change' :
+		   $hunk[$ix]{TYPE} eq 'deletion' ? ' deletion' :
+		   ' this hunk'),
 		  $patch_mode_flavour{TARGET},
 		  " [y,n,q,a,d,/$other,?]? ";
 		my $line = prompt_single_character;
diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh
index 687bd7a..768236b 100755
--- a/t/t3701-add-interactive.sh
+++ b/t/t3701-add-interactive.sh
@@ -228,4 +228,21 @@ test_expect_success 'add first line works' '
 	test_cmp expected diff
 '
 
+cat >expected <<EOF
+diff --git a/empty b/empty
+deleted file mode 100644
+index e69de29..0000000
+EOF
+
+test_expect_success 'deleting an empty file' '
+	git reset --hard &&
+	> empty &&
+	git add empty &&
+	git commit -m empty &&
+	rm empty &&
+	echo y | git add -p empty &&
+	git diff --cached >diff &&
+	test_cmp expected diff
+'
+
 test_done
-- 
1.6.5.2.193.g57820

```

## Junio C Hamano, 2009-10-28 07:18

Subject: Re: [PATCH] add-interactive: handle deletion of empty files
Message-ID: <7vbpjst29q.fsf@alter.siamese.dyndns.org>
URL: https://gitlist.dev/e/7vbpjst29q.fsf%40alter.siamese.dyndns.org
In-Reply-To: <20091028005257.GA5002@sigill.intra.peff.net>

```
Thanks.

```
