Skip to content

Commit 9a800d0

Browse files
committed
Use helpers in detectDefaultBranch and add more stdio debug to git helpers
1 parent 581bf55 commit 9a800d0

File tree

1 file changed

+69
-46
lines changed

1 file changed

+69
-46
lines changed

src/utils/git.mts

Lines changed: 69 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -91,20 +91,42 @@ export async function getRepoOwner(
9191

9292
export async function gitBranch(cwd = process.cwd()): Promise<string | null> {
9393
const stdioPipeOptions: SpawnOptions = { cwd }
94+
let quotedCmd = '`git symbolic-ref --short HEAD`'
95+
debugFn('stdio', `spawn: ${quotedCmd}`)
9496
// Try symbolic-ref first which returns the branch name or fails in a
9597
// detached HEAD state.
9698
try {
97-
return (
98-
await spawn('git', ['symbolic-ref', '--short', 'HEAD'], stdioPipeOptions)
99-
).stdout
100-
} catch {}
99+
const gitSymbolicRefResult = await spawn(
100+
'git',
101+
['symbolic-ref', '--short', 'HEAD'],
102+
stdioPipeOptions,
103+
)
104+
debugDir('stdio', { gitSymbolicRefResult })
105+
return gitSymbolicRefResult.stdout
106+
} catch (e) {
107+
if (isDebug('stdio')) {
108+
debugFn('error', `caught: ${quotedCmd} failed`)
109+
debugDir('inspect', { error: e })
110+
}
111+
}
101112
// Fallback to using rev-parse to get the short commit hash in a
102113
// detached HEAD state.
114+
quotedCmd = '`git rev-parse --short HEAD`'
115+
debugFn('stdio', `spawn: ${quotedCmd}`)
103116
try {
104-
return (
105-
await spawn('git', ['rev-parse', '--short', 'HEAD'], stdioPipeOptions)
106-
).stdout
107-
} catch {}
117+
const gitRevParseResult = await spawn(
118+
'git',
119+
['rev-parse', '--short', 'HEAD'],
120+
stdioPipeOptions,
121+
)
122+
debugDir('stdio', { gitRevParseResult })
123+
return gitRevParseResult.stdout
124+
} catch (e) {
125+
if (isDebug('stdio')) {
126+
debugFn('error', `caught: ${quotedCmd} failed`)
127+
debugDir('inspect', { error: e })
128+
}
129+
}
108130
return null
109131
}
110132

@@ -115,32 +137,19 @@ export async function gitBranch(cwd = process.cwd()): Promise<string | null> {
115137
export async function detectDefaultBranch(
116138
cwd = process.cwd(),
117139
): Promise<string> {
118-
const stdioIgnoreOptions: SpawnOptions = {
119-
cwd,
120-
stdio: isDebug('stdio') ? 'inherit' : 'ignore',
121-
}
122-
140+
// First pass: check all local branches
123141
for (const branch of COMMON_DEFAULT_BRANCH_NAMES) {
124-
// Try to check if local branch exists locally.
125-
try {
126-
// eslint-disable-next-line no-await-in-loop
127-
await spawn(
128-
'git',
129-
['show-ref', '--verify', '--quiet', `refs/heads/${branch}`],
130-
stdioIgnoreOptions,
131-
)
142+
// eslint-disable-next-line no-await-in-loop
143+
if (await gitLocalBranchExists(branch, cwd)) {
132144
return branch
133-
} catch {}
134-
// Try for the origin branch if the local branch doesn't exist.
135-
try {
136-
// eslint-disable-next-line no-await-in-loop
137-
await spawn(
138-
'git',
139-
['show-ref', '--verify', '--quiet', `refs/remotes/origin/${branch}`],
140-
stdioIgnoreOptions,
141-
)
145+
}
146+
}
147+
// Second pass: check remote branches only if no local branch found
148+
for (const branch of COMMON_DEFAULT_BRANCH_NAMES) {
149+
// eslint-disable-next-line no-await-in-loop
150+
if (await gitRemoteBranchExists(branch, cwd)) {
142151
return branch
143-
} catch {}
152+
}
144153
}
145154
// Lazily access constants.SOCKET_DEFAULT_BRANCH.
146155
return constants.SOCKET_DEFAULT_BRANCH
@@ -327,9 +336,13 @@ export async function gitEnsureIdentity(
327336
debugFn('stdio', `spawn: ${quotedCmd}`)
328337
try {
329338
// Will throw with exit code 1 if the config property is not set.
330-
configValue = (
331-
await spawn('git', ['config', '--get', prop], stdioPipeOptions)
332-
).stdout
339+
const gitConfigResult = await spawn(
340+
'git',
341+
['config', '--get', prop],
342+
stdioPipeOptions,
343+
)
344+
debugDir('stdio', { gitConfigResult })
345+
configValue = gitConfigResult.stdout
333346
} catch (e) {
334347
if (isDebug('stdio')) {
335348
debugFn('error', `caught: ${quotedCmd} failed`)
@@ -389,17 +402,22 @@ export async function gitRemoteBranchExists(
389402
cwd = process.cwd(),
390403
): Promise<boolean> {
391404
const stdioPipeOptions: SpawnOptions = { cwd }
405+
const quotedCmd = `\`git ls-remote --heads origin ${branch}\``
406+
debugFn('stdio', `spawn: ${quotedCmd}`)
392407
try {
393-
return (
394-
(
395-
await spawn(
396-
'git',
397-
['ls-remote', '--heads', 'origin', branch],
398-
stdioPipeOptions,
399-
)
400-
).stdout.length > 0
408+
const lsRemoteResult = await spawn(
409+
'git',
410+
['ls-remote', '--heads', 'origin', branch],
411+
stdioPipeOptions,
401412
)
402-
} catch {}
413+
debugDir('stdio', { lsRemoteResult })
414+
return lsRemoteResult.stdout.length > 0
415+
} catch (e) {
416+
if (isDebug('stdio')) {
417+
debugFn('error', `caught: ${quotedCmd} failed`)
418+
debugDir('inspect', { error: e })
419+
}
420+
}
403421
return false
404422
}
405423

@@ -438,10 +456,15 @@ export async function gitUnstagedModifiedFiles(
438456
): Promise<CResult<string[]>> {
439457
const stdioPipeOptions: SpawnOptions = { cwd }
440458
const quotedCmd = `\`git diff --name-only\``
459+
debugFn('stdio', `spawn: ${quotedCmd}`)
441460
try {
442-
const changedFilesDetails = (
443-
await spawn('git', ['diff', '--name-only'], stdioPipeOptions)
444-
).stdout
461+
const gitDiffResult = await spawn(
462+
'git',
463+
['diff', '--name-only'],
464+
stdioPipeOptions,
465+
)
466+
debugDir('stdio', { gitDiffResult })
467+
const changedFilesDetails = gitDiffResult.stdout
445468
const relPaths = changedFilesDetails.split('\n')
446469
return {
447470
ok: true,

0 commit comments

Comments
 (0)