Re: v2.46.0-rc0 test failures on cygwin

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Jul 16, 2024 at 08:45:48PM +0100, Ramsay Jones wrote:

>   error: could not link file '.git/ref_migration.sr9pEF/reftable' to '.git/reftable': Permission denied
>   migrated refs can be found at '.git/ref_migration.sr9pEF'
> [...]
> Now try to finish the migration by hand:
> 
>   $ mv .git/ref_migration.sr9pEF/reftable .git/reftable
> 
> Hmm, note no error; of course, the mv command may well do much more than
> the rename() library function, so they are not necessarily equivalent.

This is a shot in the dark, but: could the problem be an open file that
cannot be moved? If I run a "ref migrate" on my Linux system in the
debugger and stop at move_files(), checking /proc/<pid>/fd shows an open
descriptor for .git/ref_migration.WnJ8TS/reftable/tables.list.

Does the patch below fix things for you? I'm not too familiar with the
code, so this is what I cobbled together.  The best response will be
from Patrick, but I think he's offline for another week or so. In the
meantime, this at least doesn't crash for me. ;) And I confirmed that
the tables.list file is closed during the move_files() call.

-Peff

---
diff --git a/refs.c b/refs.c
index bb90a18875..06a0fc5099 100644
--- a/refs.c
+++ b/refs.c
@@ -2843,6 +2843,12 @@ int repo_migrate_ref_storage_format(struct repository *repo,
 		goto done;
 	}
 
+	/*
+	 * Close the new ref store to avoid holding on to any open files
+	 * which could interfere with moving things behind the scenes.
+	 */
+	ref_store_release(new_refs);
+
 	/*
 	 * Until now we were in the non-destructive phase, where we only
 	 * populated the new ref store. From hereon though we are about
@@ -2874,8 +2880,13 @@ int repo_migrate_ref_storage_format(struct repository *repo,
 	 */
 	initialize_repository_version(hash_algo_by_ptr(repo->hash_algo), format, 1);
 
-	free(new_refs->gitdir);
-	new_refs->gitdir = xstrdup(old_refs->gitdir);
+	/*
+	 * Re-open the now-migrated ref store. I'm not sure if this is strictly
+	 * needed or not. Perhaps it would also be a good time to check that
+	 * we correctly opened it, it's in the expected format, etc?
+	 */
+	new_refs = ref_store_init(repo, format, old_refs->gitdir,
+				  REF_STORE_ALL_CAPS);
 	repo->refs_private = new_refs;
 	ref_store_release(old_refs);
 




[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux