Merge pull request #915 from neilime/feat/handle-detached-head-error
fix: handle detached head error
This commit is contained in:
@@ -285,6 +285,33 @@ describe('ref', () => {
|
|||||||
expect(ref).toEqual('refs/heads/main');
|
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<ExecOutput> => {
|
||||||
|
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 () => {
|
it('infers ref from remote branch when no local branch contains HEAD', async () => {
|
||||||
jest.spyOn(Exec, 'getExecOutput').mockImplementation((cmd, args): Promise<ExecOutput> => {
|
jest.spyOn(Exec, 'getExecOutput').mockImplementation((cmd, args): Promise<ExecOutput> => {
|
||||||
const fullCmd = `${cmd} ${args?.join(' ')}`;
|
const fullCmd = `${cmd} ${args?.join(' ')}`;
|
||||||
|
|||||||
10
src/git.ts
10
src/git.ts
@@ -124,18 +124,20 @@ export class Git {
|
|||||||
const res = await Git.exec(['show', '-s', '--pretty=%D']);
|
const res = await Git.exec(['show', '-s', '--pretty=%D']);
|
||||||
core.debug(`detached HEAD ref: ${res}`);
|
core.debug(`detached HEAD ref: ${res}`);
|
||||||
|
|
||||||
if (res === 'HEAD') {
|
const normalizedRef = res.replace(/^grafted, /, '').trim();
|
||||||
|
|
||||||
|
if (normalizedRef === 'HEAD') {
|
||||||
return await Git.inferRefFromHead();
|
return await Git.inferRefFromHead();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Can be "HEAD, <tagname>" or "grafted, HEAD, <tagname>"
|
// Can be "HEAD, <tagname>" or "grafted, HEAD, <tagname>"
|
||||||
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}"`);
|
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: <tagname>"
|
// Tag refs are formatted as "tag: <tagname>"
|
||||||
if (ref.startsWith('tag: ')) {
|
if (ref.startsWith('tag: ')) {
|
||||||
|
|||||||
Reference in New Issue
Block a user