diff --git a/__tests__/git.test.ts b/__tests__/git.test.ts index 70659bd..da495bb 100644 --- a/__tests__/git.test.ts +++ b/__tests__/git.test.ts @@ -285,6 +285,33 @@ describe('ref', () => { expect(ref).toEqual('refs/heads/main'); }); + it('infers ref from local branch when detached HEAD returns only "grafted, HEAD"', async () => { + jest.spyOn(Exec, 'getExecOutput').mockImplementation((cmd, args): Promise => { + const fullCmd = `${cmd} ${args?.join(' ')}`; + let result = ''; + switch (fullCmd) { + case 'git branch --show-current': + result = ''; + break; + case 'git show -s --pretty=%D': + result = 'grafted, HEAD'; + break; + case 'git for-each-ref --format=%(refname) --contains HEAD --sort=-committerdate refs/heads/': + result = 'refs/heads/main\nrefs/heads/develop'; + break; + } + return Promise.resolve({ + stdout: result, + stderr: '', + exitCode: 0 + }); + }); + + const ref = await Git.ref(); + + expect(ref).toEqual('refs/heads/main'); + }); + it('infers ref from remote branch when no local branch contains HEAD', async () => { jest.spyOn(Exec, 'getExecOutput').mockImplementation((cmd, args): Promise => { const fullCmd = `${cmd} ${args?.join(' ')}`; diff --git a/src/git.ts b/src/git.ts index 0cf7109..c43af4d 100644 --- a/src/git.ts +++ b/src/git.ts @@ -124,18 +124,20 @@ export class Git { const res = await Git.exec(['show', '-s', '--pretty=%D']); core.debug(`detached HEAD ref: ${res}`); - if (res === 'HEAD') { + const normalizedRef = res.replace(/^grafted, /, '').trim(); + + if (normalizedRef === 'HEAD') { return await Git.inferRefFromHead(); } // Can be "HEAD, " or "grafted, HEAD, " - const refMatch = res.match(/^(grafted, )?HEAD, (.*)$/); + const refMatch = normalizedRef.match(/^HEAD, (.*)$/); - if (!refMatch || !refMatch[2]) { + if (!refMatch || !refMatch[1]) { throw new Error(`Cannot find detached HEAD ref in "${res}"`); } - const ref = refMatch[2].trim(); + const ref = refMatch[1].trim(); // Tag refs are formatted as "tag: " if (ref.startsWith('tag: ')) {