(fs: MemFS, branches: string[])
| 12 | * with no matching branch. |
| 13 | */ |
| 14 | export async function resolveHeadSymref(fs: MemFS, branches: string[]): Promise<string | null> { |
| 15 | try { |
| 16 | const headContent = String(await fs.readFile('.git/HEAD', { encoding: 'utf8' })).trim(); |
| 17 | |
| 18 | // Symbolic ref: "ref: refs/heads/main" |
| 19 | if (headContent.startsWith('ref: ')) { |
| 20 | return headContent.slice('ref: '.length); |
| 21 | } |
| 22 | |
| 23 | // Raw OID (legacy repo): find a branch whose OID matches HEAD |
| 24 | const headOid = headContent; |
| 25 | |
| 26 | // Prefer main > master > first match |
| 27 | const preferred = ['main', 'master']; |
| 28 | for (const name of preferred) { |
| 29 | if (!branches.includes(name)) continue; |
| 30 | try { |
| 31 | const branchOid = String( |
| 32 | await fs.readFile(`.git/refs/heads/${name}`, { encoding: 'utf8' }) |
| 33 | ).trim(); |
| 34 | if (branchOid === headOid) return `refs/heads/${name}`; |
| 35 | } catch { |
| 36 | // branch file missing |
| 37 | } |
| 38 | } |
| 39 | |
| 40 | for (const name of branches) { |
| 41 | if (preferred.includes(name)) continue; |
| 42 | try { |
| 43 | const branchOid = String( |
| 44 | await fs.readFile(`.git/refs/heads/${name}`, { encoding: 'utf8' }) |
| 45 | ).trim(); |
| 46 | if (branchOid === headOid) return `refs/heads/${name}`; |
| 47 | } catch { |
| 48 | // branch file missing |
| 49 | } |
| 50 | } |
| 51 | |
| 52 | return null; |
| 53 | } catch { |
| 54 | return null; |
| 55 | } |
| 56 | } |
| 57 | |
| 58 | /** |
| 59 | * Format git packet line (4-byte hex length prefix + data). |
no test coverage detected