From 61c9a894a423fdd81139a508c48ca30e22fedd49 Mon Sep 17 00:00:00 2001 From: azizur100389 Date: Mon, 12 Oct 2026 06:54:14 +0100 Subject: [PATCH] fix(storage): preserve explicit registry name after shared publish (#3560) --- gitnexus/src/core/run-analyze.ts | 5 ++- gitnexus/src/core/shared-store-analyze.ts | 7 ++- .../integration/shared-store-analyze.test.ts | 43 +++++++++++++++++++ 3 files changed, 53 insertions(+), 2 deletions(-) diff --git a/gitnexus/src/core/run-analyze.ts b/gitnexus/src/core/run-analyze.ts index d2c019e49..5621602e5 100644 --- a/gitnexus/src/core/run-analyze.ts +++ b/gitnexus/src/core/run-analyze.ts @@ -1363,7 +1363,10 @@ export async function runFullAnalysis( runnerIdentityAtBootstrap, ); if (flatShared) { - await publishSharedGraph(flatShared, repoPath, writeTarget.currentCommit, log); + await publishSharedGraph(flatShared, repoPath, writeTarget.currentCommit, log, { + name: options.registryName, + allowDuplicateName: options.allowDuplicateName, + }); } else if (!writeTarget.sharedStore) { // Also for a `--branch` run routed to a local branch sub-slot: the // checkout still leaves the store. diff --git a/gitnexus/src/core/shared-store-analyze.ts b/gitnexus/src/core/shared-store-analyze.ts index 1754cc338..57412ebf7 100644 --- a/gitnexus/src/core/shared-store-analyze.ts +++ b/gitnexus/src/core/shared-store-analyze.ts @@ -372,6 +372,7 @@ export const publishSharedGraph = async ( repoPath: string, currentCommit: string, log: Log, + registryOptions: { name?: string; allowDuplicateName?: boolean } = {}, ): Promise => { const slot = layout.checkoutSlot; const meta = await loadMeta(slot); @@ -493,7 +494,11 @@ export const publishSharedGraph = async ( const moved = previous !== undefined && !registryPathEquals(canonicalizePath(previous.storagePath), canonicalizePath(slot)); - await registerRepo(repoPath, meta, { storagePath: slot, dropBranches: moved }); + await registerRepo(repoPath, meta, { + ...registryOptions, + storagePath: slot, + dropBranches: moved, + }); await writeSharedStorePointer(repoPath, layout); }; diff --git a/gitnexus/test/integration/shared-store-analyze.test.ts b/gitnexus/test/integration/shared-store-analyze.test.ts index 55062266a..fdebdb832 100644 --- a/gitnexus/test/integration/shared-store-analyze.test.ts +++ b/gitnexus/test/integration/shared-store-analyze.test.ts @@ -20,6 +20,7 @@ import { getStoragePaths, listRegisteredRepos, loadMeta, + registerRepo, saveMeta, } from '../../src/storage/repo-manager.js'; import type { RepoMeta } from '../../src/storage/repo-meta.js'; @@ -321,6 +322,48 @@ describe('publishSharedGraph race (#3352)', () => { return { checkouts: [main, wt], head }; }; + it.each(['main', 'custom-alias'])( + 'preserves explicit registry name %s after shared-store registration', + async (registryName) => { + const { checkouts, head } = await setup(); + const [main] = checkouts; + const layout = layoutOf(main); + const meta = await loadMeta(layout.checkoutSlot); + if (!meta) throw new Error('Shared-store fixture is missing metadata'); + git(main, 'remote', 'add', 'origin', 'https://example.com/team/remote-name.git'); + await registerRepo(main, meta, { name: registryName, storagePath: layout.checkoutSlot }); + + await publishSharedGraph(layout, main, head, () => {}, { name: registryName }); + + const entry = (await listRegisteredRepos()).find((repo) => repo.path === main); + expect(entry?.name).toBe(registryName); + expect(entry?.storagePath).toBe(layout.checkoutSlot); + }, + ); + + it('keeps an explicitly permitted duplicate name through shared publication', async () => { + const { checkouts, head } = await setup(); + for (const checkout of checkouts) { + const slot = layoutOf(checkout).checkoutSlot; + const meta = await loadMeta(slot); + if (!meta) throw new Error('Shared-store fixture is missing metadata'); + await registerRepo(checkout, meta, { + name: 'shared-alias', + allowDuplicateName: true, + storagePath: slot, + }); + } + + const checkout = checkouts[1]; + await publishSharedGraph(layoutOf(checkout), checkout, head, () => {}, { + name: 'shared-alias', + allowDuplicateName: true, + }); + + const entry = (await listRegisteredRepos()).find((repo) => repo.path === checkout); + expect(entry?.name).toBe('shared-alias'); + }); + it('Covers AE6: two checkouts publishing one new commit produce exactly one graph', async () => { const { checkouts } = await setup(); await Promise.all(