Skip to content

Commit

Permalink
fix(git): handle detached ref in shallow clone context
Browse files Browse the repository at this point in the history
Signed-off-by: Emilien Escalle <emilien.escalle@escemi.com>
  • Loading branch information
neilime committed Dec 3, 2023
1 parent ddc0499 commit 7d829c4
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 3 deletions.
46 changes: 46 additions & 0 deletions __tests__/git.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,52 @@ describe('ref', () => {
expect(ref).toEqual('refs/tags/8.0.0');
});

it('returns mocked detached tag ref (shallow clone)', 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, tag: 8.0.0';
break;
}
return Promise.resolve({
stdout: result,
stderr: '',
exitCode: 0
});
});

const ref = await Git.ref();

expect(ref).toEqual('refs/tags/8.0.0');
});

it('should throws an error when detached HEAD ref is not supported', 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 = 'wrong, HEAD, tag: 8.0.0';
break;
}
return Promise.resolve({
stdout: result,
stderr: '',
exitCode: 0
});
});

await expect(Git.ref()).rejects.toThrow('Cannot find detached HEAD ref in "wrong, HEAD, tag: 8.0.0"');
});

it('returns mocked detached branch ref', async () => {
jest.spyOn(Exec, 'getExecOutput').mockImplementation((cmd, args): Promise<ExecOutput> => {
const fullCmd = `${cmd} ${args?.join(' ')}`;
Expand Down
7 changes: 4 additions & 3 deletions src/git.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,13 +123,14 @@ export class Git {
private static async getDetachedRef(): Promise<string> {
const res = await Git.exec(['show', '-s', '--pretty=%D']);

const refMatch = res.match(/^HEAD, (.*)$/);
// Can be "HEAD, <tagname>" or "grafted, HEAD, <tagname>"
const refMatch = res.match(/^(grafted, )?HEAD, (.*)$/);

if (!refMatch) {
if (!refMatch || !refMatch[2]) {
throw new Error(`Cannot find detached HEAD ref in "${res}"`);
}

const ref = refMatch[1].trim();
const ref = refMatch[2].trim();

// Tag refs are formatted as "tag: <tagname>"
if (ref.startsWith('tag: ')) {
Expand Down

0 comments on commit 7d829c4

Please sign in to comment.