Browse Source

fast-import: treat filemodify with empty tree as delete

Normal git processes do not allow one to build a tree with an empty
subtree entry without trying hard at it.  This is in keeping with the
general UI philosophy: git tracks content, not empty directories.

v1.7.3-rc0~75^2 (2010-06-30) changed that by making it easy to include
an empty subtree in fast-import's active commit:

	M 040000 4b825dc642 subdir

One can trigger this by reading an empty tree (for example, the tree
corresponding to an empty root commit) and trying to move it to a
subtree.  It is better and more closely analogous to 'git read-tree
--prefix' to treat such commands as requests to remove the subtree.

Noticed-by: David Barr <david.barr@cordelta.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
maint
Jonathan Nieder 14 years ago committed by Junio C Hamano
parent
commit
8fe533f686
  1. 6
      fast-import.c
  2. 42
      t/t9300-fast-import.sh

6
fast-import.c

@ -2163,6 +2163,12 @@ static void file_change_m(struct branch *b) @@ -2163,6 +2163,12 @@ static void file_change_m(struct branch *b)
p = uq.buf;
}

/* Git does not track empty, non-toplevel directories. */
if (S_ISDIR(mode) && !memcmp(sha1, EMPTY_TREE_SHA1_BIN, 20) && *p) {
tree_content_remove(&b->branch_tree, p, NULL);
return;
}

if (S_ISGITLINK(mode)) {
if (inline_data)
die("Git links cannot be specified 'inline': %s",

42
t/t9300-fast-import.sh

@ -817,6 +817,48 @@ test_expect_success \ @@ -817,6 +817,48 @@ test_expect_success \
git diff-tree -C --find-copies-harder -r N4^ N4 >actual &&
compare_diff_raw expect actual'

test_expect_success \
'N: delete directory by copying' \
'cat >expect <<-\EOF &&
OBJID
:100644 000000 OBJID OBJID D foo/bar/qux
OBJID
:000000 100644 OBJID OBJID A foo/bar/baz
:000000 100644 OBJID OBJID A foo/bar/qux
EOF
empty_tree=$(git mktree </dev/null) &&
cat >input <<-INPUT_END &&
commit refs/heads/N-delete
committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
data <<COMMIT
collect data to be deleted
COMMIT

deleteall
M 100644 inline foo/bar/baz
data <<DATA_END
hello
DATA_END
C "foo/bar/baz" "foo/bar/qux"
C "foo/bar/baz" "foo/bar/quux/1"
C "foo/bar/baz" "foo/bar/quuux"
M 040000 $empty_tree foo/bar/quux
M 040000 $empty_tree foo/bar/quuux

commit refs/heads/N-delete
committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
data <<COMMIT
delete subdirectory
COMMIT

M 040000 $empty_tree foo/bar/qux
INPUT_END
git fast-import <input &&
git rev-list N-delete |
git diff-tree -r --stdin --root --always |
sed -e "s/$_x40/OBJID/g" >actual &&
test_cmp expect actual'

test_expect_success \
'N: modify copied tree' \
'cat >expect <<-\EOF &&

Loading…
Cancel
Save