diff --git a/packages/docusaurus-utils/src/vcs/__tests__/gitUtils.test.ts b/packages/docusaurus-utils/src/vcs/__tests__/gitUtils.test.ts index 6a58c7d95b90..00b939c2b071 100644 --- a/packages/docusaurus-utils/src/vcs/__tests__/gitUtils.test.ts +++ b/packages/docusaurus-utils/src/vcs/__tests__/gitUtils.test.ts @@ -808,6 +808,23 @@ describe('VSC strategies', () => { }); }); + it('can read repo file info from a site-relative path', async () => { + const {vcs} = await initVsc(); + + // RouteMetadata.sourceFilePath is documented as relative to the site dir, + // and the sitemap plugin forwards it here unchanged. The map is keyed by + // absolute paths, so a relative path used to miss and silently return + // null, dropping from the sitemap. + await expect(vcs.getFileLastUpdateInfo('rootFile.md')).resolves.toEqual({ + author: 'Seb', + timestamp: new Date('2020-06-19').getTime(), + }); + await expect(vcs.getFileCreationInfo('rootFile.md')).resolves.toEqual({ + author: 'Seb', + timestamp: new Date('2020-06-19').getTime(), + }); + }); + it('can read submodule file', async () => { const {vcs, repoDir} = await initVsc(); diff --git a/packages/docusaurus-utils/src/vcs/vcsGitEager.ts b/packages/docusaurus-utils/src/vcs/vcsGitEager.ts index c250877808c7..a505b485c1f9 100644 --- a/packages/docusaurus-utils/src/vcs/vcsGitEager.ts +++ b/packages/docusaurus-utils/src/vcs/vcsGitEager.ts @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import {resolve, basename} from 'node:path'; +import {resolve, basename, isAbsolute} from 'node:path'; import logger, {PerfLogger} from '@docusaurus/logger'; import { getGitAllRepoRoots, @@ -82,11 +82,22 @@ async function initialize({ export function createVcsGitEagerConfig(): VcsConfig { let initPromise: Promise | null = null; + let initSiteDir: string | null = null; async function getGitFileInfo(filePath: string): Promise { const init = (await initPromise)!; if (init.type === 'success') { - return init.filesMap.get(filePath) ?? null; + // The map is keyed by absolute paths, but callers may pass a path + // relative to the site dir. RouteMetadata.sourceFilePath in particular + // "is expected to be relative to the site directory", which is what the + // sitemap plugin forwards here. The ad-hoc strategy tolerates both + // because it shells out to `git log`, so a relative path silently + // returned null here instead. + const key = + isAbsolute(filePath) || !initSiteDir + ? filePath + : resolve(initSiteDir, filePath); + return init.filesMap.get(key) ?? null; } else if (init.reason === 'not-in-worktree') { throw new Error( `This Docusaurus site is outside any Git worktree. @@ -114,6 +125,7 @@ Unable to read Git info for file ${logger.path(filePath)} `, return; } + initSiteDir = siteDir; initPromise = PerfLogger.async('Git Eager VCS init', () => initialize({siteDir}), );