summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--builtin/gc.c35
-rwxr-xr-xt/t5304-prune.sh2
2 files changed, 35 insertions, 2 deletions
diff --git a/builtin/gc.c b/builtin/gc.c
index c583aad6ec..79e9886cd9 100644
--- a/builtin/gc.c
+++ b/builtin/gc.c
@@ -58,8 +58,41 @@ static void clean_pack_garbage(void)
static void report_pack_garbage(unsigned seen_bits, const char *path)
{
- if (seen_bits == PACKDIR_FILE_IDX)
+ /* We know these are useless without the matching .pack */
+ if (ends_with(path, ".bitmap") || ends_with(path, ".idx")) {
string_list_append(&pack_garbage, path);
+ return;
+ }
+
+ /*
+ * A pack without other files cannot be used, but should be saved,
+ * as this is a recoverable situation (we may even see it racily
+ * as new packs come into existence).
+ */
+ if (ends_with(path, ".pack"))
+ return;
+
+ /*
+ * A .keep file is useless without the matching pack, but it
+ * _could_ contain information generated by the user. Let's keep it.
+ * In the future, we may expand this to look for obvious leftover
+ * receive-pack locks and drop them.
+ */
+ if (ends_with(path, ".keep"))
+ return;
+
+ /*
+ * A totally unrelated garbage file should be kept, to err
+ * on the conservative side.
+ */
+ if (seen_bits & PACKDIR_FILE_GARBAGE)
+ return;
+
+ /*
+ * We have a file type that the garbage-reporting functions
+ * know about but we don't. This function needs updating.
+ */
+ die("BUG: report_pack_garbage confused");
}
static void git_config_date_string(const char *key, const char **output)
diff --git a/t/t5304-prune.sh b/t/t5304-prune.sh
index f7c380c5cf..cbcc0c0e68 100755
--- a/t/t5304-prune.sh
+++ b/t/t5304-prune.sh
@@ -257,7 +257,7 @@ EOF
test_cmp expected actual
'
-test_expect_failure 'clean pack garbage with gc' '
+test_expect_success 'clean pack garbage with gc' '
test_when_finished "rm -f .git/objects/pack/fake*" &&
test_when_finished "rm -f .git/objects/pack/foo*" &&
: >.git/objects/pack/foo.keep &&