maintenance(geometric): do release the `.idx` files before repacking
As is done for all the other maintenance tasks, let's release the ODB also before starting the geometric repacking. That way, the `.idx` files won't be `mmap()`ed when they are to be deleted (which does not work on Windows because you cannot delete files on that platform as long as they are kept open by a process). This regression was introduced bymain9bc151850c(builtin/maintenance: introduce "geometric-repack" task, 2025-10-24), but was only noticed once geometric repacking was made the default in452b12c2e0(builtin/ maintenance: use "geometric" strategy by default, 2026-02-24). The fix recapitulates my work from df76ee7b77f0 (run-command: offer to close the object store before running, 2021-09-09) & friends. To guard against future regressions of this kind, add a check to `run_and_verify_geometric_pack()` in `t7900` that detects orphaned `.idx` files left behind after repacking. Contrary to interactive calls, the `git maintenance` call in that test case would _not_ block on Windows, asking whether to retry deleting that file, which is the reason why this bug was not caught earlier. Furthermore, since the default behavior of `DeleteFileW()` was changed at some point between Windows 10 Build 17134.1304 and Build 18363.657 to use POSIX semantics (see https://stackoverflow.com/a/60512798), the added orphaned-`.idx` check would be insufficient to catch this regression on modern Windows without emulating legacy delete semantics via `GIT_TEST_LEGACY_DELETE=1`. This fixes https://github.com/git-for-windows/git/issues/6210. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
parent
69ed0e35a7
commit
4bb086cfa2
|
|
@ -1590,6 +1590,7 @@ static int maintenance_task_geometric_repack(struct maintenance_run_opts *opts,
|
|||
pack_geometry_split(&geometry);
|
||||
|
||||
child.git_cmd = 1;
|
||||
child.odb_to_close = the_repository->objects;
|
||||
|
||||
strvec_pushl(&child.args, "repack", "-d", "-l", NULL);
|
||||
if (geometry.split < geometry.pack_nr)
|
||||
|
|
|
|||
|
|
@ -532,7 +532,16 @@ run_and_verify_geometric_pack () {
|
|||
|
||||
# And verify that there are no loose objects anymore.
|
||||
git count-objects -v >count &&
|
||||
test_grep '^count: 0$' count
|
||||
test_grep '^count: 0$' count &&
|
||||
|
||||
# Verify that no orphaned .idx files were left behind. On
|
||||
# Windows, a missing odb_to_close causes the parent to hold
|
||||
# mmap handles on .idx files, silently preventing their
|
||||
# deletion by the child git-repack process.
|
||||
ls .git/objects/pack/pack-*.idx .git/objects/pack/pack-*.pack |
|
||||
sed "s/\.pack$/.idx/" |
|
||||
sort | uniq -u >orphaned-idx &&
|
||||
test_must_be_empty orphaned-idx
|
||||
}
|
||||
|
||||
test_expect_success 'geometric repacking task' '
|
||||
|
|
@ -580,8 +589,19 @@ test_expect_success 'geometric repacking task' '
|
|||
|
||||
# And these two small packs should now be merged via the
|
||||
# geometric repack. The large packfile should remain intact.
|
||||
cp -R .git/objects .git/objects.save &&
|
||||
run_and_verify_geometric_pack 2 &&
|
||||
|
||||
# On Windows, verify the same with legacy delete semantics
|
||||
# that reject deletion of mmap-held .idx files.
|
||||
if test_have_prereq MINGW
|
||||
then
|
||||
rm -rf .git/objects &&
|
||||
mv .git/objects.save .git/objects &&
|
||||
test_env GIT_TEST_LEGACY_DELETE=1 \
|
||||
run_and_verify_geometric_pack 2
|
||||
fi &&
|
||||
|
||||
# If we now add two more objects and repack twice we should
|
||||
# then see another all-into-one repack. This time around
|
||||
# though, as we have unreachable objects, we should also see a
|
||||
|
|
|
|||
Loading…
Reference in New Issue