Skip to content

Commit e224f26

Browse files
committed
Merge branch 'tb/collect-pack-filenames-fix'
Avoid breakage of "git pack-objects --cruft" due to inconsistency between the way the code enumerates packfiles in the repository. * tb/collect-pack-filenames-fix: builtin/repack.c: only collect fully-formed packs
2 parents 8d5c5a0 + 73320e4 commit e224f26

File tree

2 files changed

+33
-4
lines changed

2 files changed

+33
-4
lines changed

builtin/repack.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,8 @@ static int repack_config(const char *var, const char *value, void *cb)
9595
}
9696

9797
/*
98-
* Adds all packs hex strings to either fname_nonkept_list or
99-
* fname_kept_list based on whether each pack has a corresponding
98+
* Adds all packs hex strings (pack-$HASH) to either fname_nonkept_list
99+
* or fname_kept_list based on whether each pack has a corresponding
100100
* .keep file or not. Packs without a .keep file are not to be kept
101101
* if we are going to pack everything into one file.
102102
*/
@@ -107,6 +107,7 @@ static void collect_pack_filenames(struct string_list *fname_nonkept_list,
107107
DIR *dir;
108108
struct dirent *e;
109109
char *fname;
110+
struct strbuf buf = STRBUF_INIT;
110111

111112
if (!(dir = opendir(packdir)))
112113
return;
@@ -115,11 +116,15 @@ static void collect_pack_filenames(struct string_list *fname_nonkept_list,
115116
size_t len;
116117
int i;
117118

118-
if (!strip_suffix(e->d_name, ".pack", &len))
119+
if (!strip_suffix(e->d_name, ".idx", &len))
119120
continue;
120121

122+
strbuf_reset(&buf);
123+
strbuf_add(&buf, e->d_name, len);
124+
strbuf_addstr(&buf, ".pack");
125+
121126
for (i = 0; i < extra_keep->nr; i++)
122-
if (!fspathcmp(e->d_name, extra_keep->items[i].string))
127+
if (!fspathcmp(buf.buf, extra_keep->items[i].string))
123128
break;
124129

125130
fname = xmemdupz(e->d_name, len);
@@ -136,6 +141,7 @@ static void collect_pack_filenames(struct string_list *fname_nonkept_list,
136141
}
137142
}
138143
closedir(dir);
144+
strbuf_release(&buf);
139145

140146
string_list_sort(fname_kept_list);
141147
}

t/t7700-repack.sh

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ test_description='git repack works correctly'
1010
commit_and_pack () {
1111
test_commit "$@" 1>&2 &&
1212
incrpackid=$(git pack-objects --all --unpacked --incremental .git/objects/pack/pack </dev/null) &&
13+
# Remove any loose object(s) created by test_commit, since they have
14+
# already been packed. Leaving these around can create subtly different
15+
# packs with `pack-objects`'s `--unpacked` option.
16+
git prune-packed 1>&2 &&
1317
echo pack-${incrpackid}.pack
1418
}
1519

@@ -209,6 +213,8 @@ test_expect_success 'repack --keep-pack' '
209213
test_create_repo keep-pack &&
210214
(
211215
cd keep-pack &&
216+
# avoid producing difference packs to delta/base choices
217+
git config pack.window 0 &&
212218
P1=$(commit_and_pack 1) &&
213219
P2=$(commit_and_pack 2) &&
214220
P3=$(commit_and_pack 3) &&
@@ -220,6 +226,23 @@ test_expect_success 'repack --keep-pack' '
220226
grep -q $P1 new-counts &&
221227
grep -q $P4 new-counts &&
222228
test_line_count = 3 new-counts &&
229+
git fsck &&
230+
231+
P5=$(commit_and_pack --no-tag 5) &&
232+
git reset --hard HEAD^ &&
233+
git reflog expire --all --expire=all &&
234+
rm -f ".git/objects/pack/${P5%.pack}.idx" &&
235+
rm -f ".git/objects/info/commit-graph" &&
236+
for from in $(find .git/objects/pack -type f -name "${P5%.pack}.*")
237+
do
238+
to="$(dirname "$from")/.tmp-1234-$(basename "$from")" &&
239+
mv "$from" "$to" || return 1
240+
done &&
241+
242+
git repack --cruft -d --keep-pack $P1 --keep-pack $P4 &&
243+
244+
ls .git/objects/pack/*.pack >newer-counts &&
245+
test_cmp new-counts newer-counts &&
223246
git fsck
224247
)
225248
'

0 commit comments

Comments
 (0)