fsck: warn about ".git" in trees

Having a ".git" entry inside a tree can cause confusing results on checkout. At the top-level, you could not checkout such a tree, as it would complain about overwriting the real ".git" directory. In a subdirectory, you might check it out, but performing operations in the subdirectory would confusingly consider the in-tree ".git" directory as the repository. The regular git tools already make it hard to accidentally add such an entry to a tree, and do not allow such entries to enter the index at all. Teaching fsck about it provides an additional safety check, and let's us avoid propagating any such bogosity when transfer.fsckObjects is on. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jeff King committed Nov 28, 2012 at 16:35 UTC 5c17f51270e1b384e03fb9c16b5a0040b115ae8c
2 files changed +20
fsck.c
+5
@@ -144,6 +144,7 @@ static int fsck_tree(struct tree *item, int strict, fsck_error error_func)
144 int has_empty_name = 0;
145 int has_dot = 0;
146 int has_dotdot = 0;
147 + int has_dotgit = 0;
148 int has_zero_pad = 0;
149 int has_bad_modes = 0;
150 int has_dup_entries = 0;
@@ -174,6 +175,8 @@ static int fsck_tree(struct tree *item, int strict, fsck_error error_func)
175 has_dot = 1;
176 if (!strcmp(name, ".."))
177 has_dotdot = 1;
178 + if (!strcmp(name, ".git"))
179 + has_dotgit = 1;
180 has_zero_pad |= *(char *)desc.buffer == '0';
181 update_tree_entry(&desc);
182
@@ -227,6 +230,8 @@ static int fsck_tree(struct tree *item, int strict, fsck_error error_func)
230 retval += error_func(&item->object, FSCK_WARN, "contains '.'");
231 if (has_dotdot)
232 retval += error_func(&item->object, FSCK_WARN, "contains '..'");
233 + if (has_dotgit)
234 + retval += error_func(&item->object, FSCK_WARN, "contains '.git'");
235 if (has_zero_pad)
236 retval += error_func(&item->object, FSCK_WARN, "contains zero-padded file modes");
237 if (has_bad_modes)
t/t1450-fsck.sh
+15
@@ -253,4 +253,19 @@ test_expect_success 'fsck notices "." and ".." in trees' '
253 )
254 '
255
256 +test_expect_success 'fsck notices ".git" in trees' '
257 + (
258 + git init dotgit &&
259 + cd dotgit &&
260 + blob=$(echo foo | git hash-object -w --stdin) &&
261 + tab=$(printf "\\t") &&
262 + git mktree <<-EOF &&
263 + 100644 blob $blob$tab.git
264 + EOF
265 + git fsck 2>out &&
266 + cat out &&
267 + grep "warning.*\\.git" out
268 + )
269 +'
270 +
271 test_done