Skip to content

Commit 8fe533f

Browse files
jrngitster
authored andcommitted
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 4b825dc 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 <[email protected]> Signed-off-by: Jonathan Nieder <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 334fba6 commit 8fe533f

File tree

2 files changed

+48
-0
lines changed

2 files changed

+48
-0
lines changed

fast-import.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2163,6 +2163,12 @@ static void file_change_m(struct branch *b)
21632163
p = uq.buf;
21642164
}
21652165

2166+
/* Git does not track empty, non-toplevel directories. */
2167+
if (S_ISDIR(mode) && !memcmp(sha1, EMPTY_TREE_SHA1_BIN, 20) && *p) {
2168+
tree_content_remove(&b->branch_tree, p, NULL);
2169+
return;
2170+
}
2171+
21662172
if (S_ISGITLINK(mode)) {
21672173
if (inline_data)
21682174
die("Git links cannot be specified 'inline': %s",

t/t9300-fast-import.sh

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -817,6 +817,48 @@ test_expect_success \
817817
git diff-tree -C --find-copies-harder -r N4^ N4 >actual &&
818818
compare_diff_raw expect actual'
819819

820+
test_expect_success \
821+
'N: delete directory by copying' \
822+
'cat >expect <<-\EOF &&
823+
OBJID
824+
:100644 000000 OBJID OBJID D foo/bar/qux
825+
OBJID
826+
:000000 100644 OBJID OBJID A foo/bar/baz
827+
:000000 100644 OBJID OBJID A foo/bar/qux
828+
EOF
829+
empty_tree=$(git mktree </dev/null) &&
830+
cat >input <<-INPUT_END &&
831+
commit refs/heads/N-delete
832+
committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
833+
data <<COMMIT
834+
collect data to be deleted
835+
COMMIT
836+
837+
deleteall
838+
M 100644 inline foo/bar/baz
839+
data <<DATA_END
840+
hello
841+
DATA_END
842+
C "foo/bar/baz" "foo/bar/qux"
843+
C "foo/bar/baz" "foo/bar/quux/1"
844+
C "foo/bar/baz" "foo/bar/quuux"
845+
M 040000 $empty_tree foo/bar/quux
846+
M 040000 $empty_tree foo/bar/quuux
847+
848+
commit refs/heads/N-delete
849+
committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
850+
data <<COMMIT
851+
delete subdirectory
852+
COMMIT
853+
854+
M 040000 $empty_tree foo/bar/qux
855+
INPUT_END
856+
git fast-import <input &&
857+
git rev-list N-delete |
858+
git diff-tree -r --stdin --root --always |
859+
sed -e "s/$_x40/OBJID/g" >actual &&
860+
test_cmp expect actual'
861+
820862
test_expect_success \
821863
'N: modify copied tree' \
822864
'cat >expect <<-\EOF &&

0 commit comments

Comments
 (0)