Skip to content

Commit 7d829c4

Browse files
committed
fix(git): handle detached ref in shallow clone context
Signed-off-by: Emilien Escalle <[email protected]>
1 parent ddc0499 commit 7d829c4

File tree

2 files changed

+50
-3
lines changed

2 files changed

+50
-3
lines changed

__tests__/git.test.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,52 @@ describe('ref', () => {
141141
expect(ref).toEqual('refs/tags/8.0.0');
142142
});
143143

144+
it('returns mocked detached tag ref (shallow clone)', async () => {
145+
jest.spyOn(Exec, 'getExecOutput').mockImplementation((cmd, args): Promise<ExecOutput> => {
146+
const fullCmd = `${cmd} ${args?.join(' ')}`;
147+
let result = '';
148+
switch (fullCmd) {
149+
case 'git branch --show-current':
150+
result = '';
151+
break;
152+
case 'git show -s --pretty=%D':
153+
result = 'grafted, HEAD, tag: 8.0.0';
154+
break;
155+
}
156+
return Promise.resolve({
157+
stdout: result,
158+
stderr: '',
159+
exitCode: 0
160+
});
161+
});
162+
163+
const ref = await Git.ref();
164+
165+
expect(ref).toEqual('refs/tags/8.0.0');
166+
});
167+
168+
it('should throws an error when detached HEAD ref is not supported', async () => {
169+
jest.spyOn(Exec, 'getExecOutput').mockImplementation((cmd, args): Promise<ExecOutput> => {
170+
const fullCmd = `${cmd} ${args?.join(' ')}`;
171+
let result = '';
172+
switch (fullCmd) {
173+
case 'git branch --show-current':
174+
result = '';
175+
break;
176+
case 'git show -s --pretty=%D':
177+
result = 'wrong, HEAD, tag: 8.0.0';
178+
break;
179+
}
180+
return Promise.resolve({
181+
stdout: result,
182+
stderr: '',
183+
exitCode: 0
184+
});
185+
});
186+
187+
await expect(Git.ref()).rejects.toThrow('Cannot find detached HEAD ref in "wrong, HEAD, tag: 8.0.0"');
188+
});
189+
144190
it('returns mocked detached branch ref', async () => {
145191
jest.spyOn(Exec, 'getExecOutput').mockImplementation((cmd, args): Promise<ExecOutput> => {
146192
const fullCmd = `${cmd} ${args?.join(' ')}`;

src/git.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -123,13 +123,14 @@ export class Git {
123123
private static async getDetachedRef(): Promise<string> {
124124
const res = await Git.exec(['show', '-s', '--pretty=%D']);
125125

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

128-
if (!refMatch) {
129+
if (!refMatch || !refMatch[2]) {
129130
throw new Error(`Cannot find detached HEAD ref in "${res}"`);
130131
}
131132

132-
const ref = refMatch[1].trim();
133+
const ref = refMatch[2].trim();
133134

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

0 commit comments

Comments
 (0)