Skip to content

Commit 34402c6

Browse files
committed
Merge branch 'dk/gc-more-wo-pack' into pu
Follow-on to dk/gc-idx-wo-pack topic, to clean up stale .bitmap and .keep files. Has been waiting for a reroll for too long. cf. <[email protected]> * dk/gc-more-wo-pack: gc: clean garbage .bitmap files from pack dir t5304: ensure non-garbage files are not deleted t5304: test .bitmap garbage files prepare_packed_git(): find more garbage
2 parents e4a34c1 + b0a9d62 commit 34402c6

File tree

5 files changed

+89
-15
lines changed

5 files changed

+89
-15
lines changed

builtin/count-objects.c

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,15 @@ static off_t loose_size;
1717

1818
static const char *bits_to_msg(unsigned seen_bits)
1919
{
20-
switch (seen_bits) {
21-
case 0:
22-
return "no corresponding .idx or .pack";
23-
case PACKDIR_FILE_GARBAGE:
20+
if (seen_bits & PACKDIR_FILE_GARBAGE)
2421
return "garbage found";
25-
case PACKDIR_FILE_PACK:
22+
else if (seen_bits & PACKDIR_FILE_PACK && !(seen_bits & PACKDIR_FILE_IDX))
2623
return "no corresponding .idx";
27-
case PACKDIR_FILE_IDX:
24+
else if (seen_bits & PACKDIR_FILE_IDX && !(seen_bits & PACKDIR_FILE_PACK))
2825
return "no corresponding .pack";
29-
case PACKDIR_FILE_PACK|PACKDIR_FILE_IDX:
30-
default:
31-
return NULL;
32-
}
26+
else if (!(seen_bits & (PACKDIR_FILE_IDX|PACKDIR_FILE_PACK)))
27+
return "no corresponding .idx or .pack";
28+
return NULL;
3329
}
3430

3531
static void real_report_garbage(unsigned seen_bits, const char *path)

builtin/gc.c

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,41 @@ static void clean_pack_garbage(void)
5858

5959
static void report_pack_garbage(unsigned seen_bits, const char *path)
6060
{
61-
if (seen_bits == PACKDIR_FILE_IDX)
61+
/* We know these are useless without the matching .pack */
62+
if (ends_with(path, ".bitmap") || ends_with(path, ".idx")) {
6263
string_list_append(&pack_garbage, path);
64+
return;
65+
}
66+
67+
/*
68+
* A pack without other files cannot be used, but should be saved,
69+
* as this is a recoverable situation (we may even see it racily
70+
* as new packs come into existence).
71+
*/
72+
if (ends_with(path, ".pack"))
73+
return;
74+
75+
/*
76+
* A .keep file is useless without the matching pack, but it
77+
* _could_ contain information generated by the user. Let's keep it.
78+
* In the future, we may expand this to look for obvious leftover
79+
* receive-pack locks and drop them.
80+
*/
81+
if (ends_with(path, ".keep"))
82+
return;
83+
84+
/*
85+
* A totally unrelated garbage file should be kept, to err
86+
* on the conservative side.
87+
*/
88+
if (seen_bits & PACKDIR_FILE_GARBAGE)
89+
return;
90+
91+
/*
92+
* We have a file type that the garbage-reporting functions
93+
* know about but we don't. This function needs updating.
94+
*/
95+
die("BUG: report_pack_garbage confused");
6396
}
6497

6598
static void git_config_date_string(const char *key, const char **output)

cache.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1442,7 +1442,9 @@ extern struct packed_git *parse_pack_index(unsigned char *sha1, const char *idx_
14421442
/* A hook to report invalid files in pack directory */
14431443
#define PACKDIR_FILE_PACK 1
14441444
#define PACKDIR_FILE_IDX 2
1445-
#define PACKDIR_FILE_GARBAGE 4
1445+
#define PACKDIR_FILE_BITMAP 4
1446+
#define PACKDIR_FILE_KEEP 8
1447+
#define PACKDIR_FILE_GARBAGE 16
14461448
extern void (*report_garbage)(unsigned seen_bits, const char *path);
14471449

14481450
extern void prepare_packed_git(void);

sha1_file.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1274,7 +1274,9 @@ void (*report_garbage)(unsigned seen_bits, const char *path);
12741274
static void report_helper(const struct string_list *list,
12751275
int seen_bits, int first, int last)
12761276
{
1277-
if (seen_bits == (PACKDIR_FILE_PACK|PACKDIR_FILE_IDX))
1277+
static const int pack_and_index = PACKDIR_FILE_PACK|PACKDIR_FILE_IDX;
1278+
1279+
if ((seen_bits & pack_and_index) == pack_and_index)
12781280
return;
12791281

12801282
for (; first < last; first++)
@@ -1308,9 +1310,13 @@ static void report_pack_garbage(struct string_list *list)
13081310
first = i;
13091311
}
13101312
if (!strcmp(path + baselen, "pack"))
1311-
seen_bits |= 1;
1313+
seen_bits |= PACKDIR_FILE_PACK;
13121314
else if (!strcmp(path + baselen, "idx"))
1313-
seen_bits |= 2;
1315+
seen_bits |= PACKDIR_FILE_IDX;
1316+
else if (!strcmp(path + baselen, "bitmap"))
1317+
seen_bits |= PACKDIR_FILE_BITMAP;
1318+
else if (!strcmp(path + baselen, "keep"))
1319+
seen_bits |= PACKDIR_FILE_KEEP;
13141320
}
13151321
report_helper(list, seen_bits, first, list->nr);
13161322
}

t/t5304-prune.sh

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,12 @@ test_expect_success 'garbage report in count-objects -v' '
230230
: >.git/objects/pack/fake.idx &&
231231
: >.git/objects/pack/fake2.keep &&
232232
: >.git/objects/pack/fake3.idx &&
233+
: >.git/objects/pack/fake4.bitmap &&
234+
: >.git/objects/pack/fake5.bitmap &&
235+
: >.git/objects/pack/fake5.idx &&
236+
: >.git/objects/pack/fake6.keep &&
237+
: >.git/objects/pack/fake6.bitmap &&
238+
: >.git/objects/pack/fake6.idx &&
233239
git count-objects -v 2>stderr &&
234240
grep "index file .git/objects/pack/fake.idx is too small" stderr &&
235241
grep "^warning:" stderr | sort >actual &&
@@ -238,9 +244,15 @@ warning: garbage found: .git/objects/pack/fake.bar
238244
warning: garbage found: .git/objects/pack/foo
239245
warning: garbage found: .git/objects/pack/foo.bar
240246
warning: no corresponding .idx or .pack: .git/objects/pack/fake2.keep
247+
warning: no corresponding .idx or .pack: .git/objects/pack/fake4.bitmap
241248
warning: no corresponding .idx: .git/objects/pack/foo.keep
242249
warning: no corresponding .idx: .git/objects/pack/foo.pack
243250
warning: no corresponding .pack: .git/objects/pack/fake3.idx
251+
warning: no corresponding .pack: .git/objects/pack/fake5.bitmap
252+
warning: no corresponding .pack: .git/objects/pack/fake5.idx
253+
warning: no corresponding .pack: .git/objects/pack/fake6.bitmap
254+
warning: no corresponding .pack: .git/objects/pack/fake6.idx
255+
warning: no corresponding .pack: .git/objects/pack/fake6.keep
244256
EOF
245257
test_cmp expected actual
246258
'
@@ -254,17 +266,42 @@ test_expect_success 'clean pack garbage with gc' '
254266
: >.git/objects/pack/fake2.keep &&
255267
: >.git/objects/pack/fake2.idx &&
256268
: >.git/objects/pack/fake3.keep &&
269+
: >.git/objects/pack/fake4.bitmap &&
270+
: >.git/objects/pack/fake5.bitmap &&
271+
: >.git/objects/pack/fake5.idx &&
272+
: >.git/objects/pack/fake6.keep &&
273+
: >.git/objects/pack/fake6.bitmap &&
274+
: >.git/objects/pack/fake6.idx &&
257275
git gc &&
258276
git count-objects -v 2>stderr &&
259277
grep "^warning:" stderr | sort >actual &&
260278
cat >expected <<\EOF &&
279+
warning: no corresponding .idx or .pack: .git/objects/pack/fake2.keep
261280
warning: no corresponding .idx or .pack: .git/objects/pack/fake3.keep
281+
warning: no corresponding .idx or .pack: .git/objects/pack/fake6.keep
262282
warning: no corresponding .idx: .git/objects/pack/foo.keep
263283
warning: no corresponding .idx: .git/objects/pack/foo.pack
264284
EOF
265285
test_cmp expected actual
266286
'
267287

288+
test_expect_success 'ensure unknown garbage kept with gc' '
289+
test_when_finished "rm -f .git/objects/pack/fake*" &&
290+
test_when_finished "rm -f .git/objects/pack/foo*" &&
291+
: >.git/objects/pack/foo.keep &&
292+
: >.git/objects/pack/fake.pack &&
293+
: >.git/objects/pack/fake2.foo &&
294+
git gc &&
295+
git count-objects -v 2>stderr &&
296+
grep "^warning:" stderr | sort >actual &&
297+
cat >expected <<\EOF &&
298+
warning: garbage found: .git/objects/pack/fake2.foo
299+
warning: no corresponding .idx or .pack: .git/objects/pack/foo.keep
300+
warning: no corresponding .idx: .git/objects/pack/fake.pack
301+
EOF
302+
test_cmp expected actual
303+
'
304+
268305
test_expect_success 'prune .git/shallow' '
269306
SHA1=$(echo hi|git commit-tree HEAD^{tree}) &&
270307
echo $SHA1 >.git/shallow &&

0 commit comments

Comments
 (0)