Skip to content

Commit 09c8173

Browse files
pks-tgitster
authored andcommitted
refs: fix format migration on Cygwin
It was reported that t1460-refs-migrate.sh fails when using Cygwin with errors like the following: error: could not link file '.git/ref_migration.sr9pEF/reftable' to '.git/reftable': Permission denied As some debugging surfaced, the root cause of this is that some files of the newly-initialized ref store are still open when the target format is the "reftable" format, and Cygwin refuses to rename open files. Fix this issue by closing the new ref store before renaming its files into place. This is a slight change in behaviour compared to before, where we kept the new ref store open and then updated the repository's ref store to point to it. While we could re-open the new ref store after we have moved files around, this is ultimately unnecessary. We know that the only user of `repo_migrate_ref_storage_format()` is the git-refs(1) command, and it won't access the ref store after it has been migrated anyway. So reinitializing the ref store would be a waste of time. Regardless of that it is still sensible to leave the repository in a consistent state. But instead of reinitializing the ref store, we can simply unset the repo's ref store altogether and let `get_main_ref_store()` lazily initialize the new ref store as required. Reported-by: Ramsay Jones <[email protected]> Helped-by: Jeff King <[email protected]> Signed-off-by: Patrick Steinhardt <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 25a0023 commit 09c8173

File tree

1 file changed

+18
-4
lines changed

1 file changed

+18
-4
lines changed

refs.c

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2827,6 +2827,14 @@ int repo_migrate_ref_storage_format(struct repository *repo,
28272827
goto done;
28282828
}
28292829

2830+
/*
2831+
* Release the new ref store such that any potentially-open files will
2832+
* be closed. This is required for platforms like Cygwin, where
2833+
* renaming an open file results in EPERM.
2834+
*/
2835+
ref_store_release(new_refs);
2836+
FREE_AND_NULL(new_refs);
2837+
28302838
/*
28312839
* Until now we were in the non-destructive phase, where we only
28322840
* populated the new ref store. From hereon though we are about
@@ -2858,10 +2866,14 @@ int repo_migrate_ref_storage_format(struct repository *repo,
28582866
*/
28592867
initialize_repository_version(hash_algo_by_ptr(repo->hash_algo), format, 1);
28602868

2861-
free(new_refs->gitdir);
2862-
new_refs->gitdir = xstrdup(old_refs->gitdir);
2863-
repo->refs_private = new_refs;
2869+
/*
2870+
* Unset the old ref store and release it. `get_main_ref_store()` will
2871+
* make sure to lazily re-initialize the repository's ref store with
2872+
* the new format.
2873+
*/
28642874
ref_store_release(old_refs);
2875+
FREE_AND_NULL(old_refs);
2876+
repo->refs_private = NULL;
28652877

28662878
ret = 0;
28672879

@@ -2872,8 +2884,10 @@ int repo_migrate_ref_storage_format(struct repository *repo,
28722884
new_gitdir.buf);
28732885
}
28742886

2875-
if (ret && new_refs)
2887+
if (new_refs) {
28762888
ref_store_release(new_refs);
2889+
free(new_refs);
2890+
}
28772891
ref_transaction_free(transaction);
28782892
strbuf_release(&new_gitdir);
28792893
return ret;

0 commit comments

Comments
 (0)