Browse Source

add-interactive: handle deletion of empty files

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>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
maint
Jeff King 15 years ago committed by Junio C Hamano
parent
commit
24ab81ae4d
  1. 18
      git-add--interactive.perl
  2. 17
      t/t3701-add-interactive.sh

18
git-add--interactive.perl

@ -731,14 +731,17 @@ sub parse_diff_header { @@ -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 { @@ -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 { @@ -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 { @@ -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;

17
t/t3701-add-interactive.sh

@ -214,4 +214,21 @@ test_expect_success 'add first line works' ' @@ -214,4 +214,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

Loading…
Cancel
Save