From e59197f91babb250583f997b89e8230af4019925 Mon Sep 17 00:00:00 2001 From: Michal Dorner Date: Thu, 25 Mar 2021 23:34:50 +0100 Subject: [PATCH] Fix change detection when base is tag --- src/git.ts | 53 ++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 44 insertions(+), 9 deletions(-) diff --git a/src/git.ts b/src/git.ts index 531c301f..4d07d769 100644 --- a/src/git.ts +++ b/src/git.ts @@ -55,17 +55,28 @@ export async function getChangesOnHead(): Promise { } export async function getChangesSinceMergeBase(base: string, ref: string, initialFetchDepth: number): Promise { - const baseRef = `remotes/origin/${base}` - + let baseRef: string | undefined async function hasMergeBase(): Promise { - return (await exec('git', ['merge-base', baseRef, ref], {ignoreReturnCode: true})).code === 0 + return baseRef !== undefined && (await exec('git', ['merge-base', baseRef, ref], {ignoreReturnCode: true})).code === 0 } let noMergeBase = false core.startGroup(`Searching for merge-base ${baseRef}...${ref}`) try { + baseRef = await getFullRef(base) if (!(await hasMergeBase())) { - await exec('git', ['fetch', `--depth=${initialFetchDepth}`, 'origin', base, ref]) + await exec('git', ['fetch', '--no-tags', `--depth=${initialFetchDepth}`, 'origin', base, ref]) + if (baseRef === undefined) { + baseRef = await getFullRef(base) + if (baseRef === undefined) { + await exec('git', ['fetch', '--tags', `--depth=1`, 'origin', base, ref]) + baseRef = await getFullRef(base) + if (baseRef === undefined) { + throw new Error(`Could not determine what is ${base} - fetch works but it's not a branch or tag`) + } + } + } + let depth = initialFetchDepth let lastCommitCount = await getCommitCount() while (!(await hasMergeBase())) { @@ -88,17 +99,18 @@ export async function getChangesSinceMergeBase(base: string, ref: string, initia core.endGroup() } + let diffArg = `${baseRef}...${ref}` if (noMergeBase) { - core.warning('No merge base found - all files will be listed as added') - return await listAllFilesAsAdded() + core.warning('No merge base found - change detection will use direct .. comparison') + diffArg = `${baseRef}..${ref}` } - // Get changes introduced on HEAD compared to ref - core.startGroup(`Change detection ${baseRef}...${ref}`) + // Get changes introduced on ref compared to base + core.startGroup(`Change detection ${diffArg}`) let output = '' try { // Three dots '...' change detection - finds merge-base and compares against it - output = (await exec('git', ['diff', '--no-renames', '--name-status', '-z', `${baseRef}...${ref}`])).stdout + output = (await exec('git', ['diff', '--no-renames', '--name-status', '-z', diffArg])).stdout } finally { fixStdOutNullTermination() core.endGroup() @@ -188,6 +200,29 @@ async function getCommitCount(): Promise { return isNaN(count) ? 0 : count } +async function getFullRef(shortName: string) { + if(isGitSha(shortName)) { + return shortName + } + + const remoteRef = `refs/remotes/origin/${shortName}` + const tagRef = `refs/tags/${shortName}` + const headRef = `refs/heads/${shortName}` + if (await verifyRef(remoteRef)) { + return remoteRef + } else if (await verifyRef(tagRef)) { + return tagRef + } else if (await verifyRef(headRef)) { + return headRef + } + + return undefined +} + +async function verifyRef(ref: string): Promise { + return (await exec('git', ['show-ref', '--verify', ref], {ignoreReturnCode: true})).code === 0 +} + function fixStdOutNullTermination(): void { // Previous command uses NULL as delimiters and output is printed to stdout. // We have to make sure next thing written to stdout will start on new line.