sequencer: release the ODB before spawning git commit
As ofmain4557f1add2(rebase--helper: add a builtin helper for interactive rebases, 2017-02-09), continuing an interactive rebase uses the builtin sequencer, which spawns `git commit`. The child may trigger auto-maintenance, which may need to replace files for which the sequencer still holds resources. See https://github.com/git-for-windows/git/issues/6315: on Windows, this produces unlink retry prompts that cannot succeed while the sequencer waits for the child. Resources such as file handles or memory mappings must be released before spawning a command that may run auto-maintenance, as established by28d04e1ec1(run-command: offer to close the object store before running, 2021-09-09): release the ODB file handles and memory mappings, so that auto-gc can repack (potentially deleting existing packfiles in the process); If the sequencer needs to access the ODB afterwards, it will gracefully (re-)open the ODB. Release the sequencer's ODB before spawning `git commit`. The regression test uses the legacy-delete trick introduced by69ed0e35a7(mingw: optionally use legacy (non-POSIX) delete semantics, 2026-05-07) to trigger the failure on modern Windows. Assisted-by: GPT-5.6 Sol Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
parent
11c6700f10
commit
65cda10d5b
|
|
@ -1127,6 +1127,7 @@ static int run_git_commit(const char *defmsg,
|
|||
struct child_process cmd = CHILD_PROCESS_INIT;
|
||||
|
||||
cmd.git_cmd = 1;
|
||||
cmd.odb_to_close = the_repository->objects;
|
||||
|
||||
if (is_rebase_i(opts) &&
|
||||
((opts->committer_date_is_author_date && !opts->ignore_date) ||
|
||||
|
|
|
|||
|
|
@ -65,6 +65,24 @@ test_expect_success 'setup' '
|
|||
test_commit P fileP
|
||||
'
|
||||
|
||||
test_expect_success MINGW 'rebase releases object database before committing' '
|
||||
test_when_finished "rm -f .git/hooks/post-commit repacked packs" &&
|
||||
git switch -C repack-rewrite primary &&
|
||||
git repack -ad &&
|
||||
write_script .git/hooks/post-commit <<-\EOF &&
|
||||
git repack -ad &&
|
||||
>repacked
|
||||
EOF
|
||||
(
|
||||
set_fake_editor &&
|
||||
FAKE_LINES="reword 1" GIT_TEST_LEGACY_DELETE=1 \
|
||||
git -c core.commitGraph=false rebase -i HEAD^
|
||||
) &&
|
||||
test_path_is_file repacked &&
|
||||
ls .git/objects/pack/*.pack >packs &&
|
||||
test_line_count = 1 packs
|
||||
'
|
||||
|
||||
# "exec" commands are run with the user shell by default, but this may
|
||||
# be non-POSIX. For example, if SHELL=zsh then ">file" doesn't work
|
||||
# to create a file. Unsetting SHELL avoids such non-portable behavior
|
||||
|
|
|
|||
Loading…
Reference in New Issue