feat: add git branch name to footer (#589)

This commit is contained in:
Brandon Keiji
2025-05-28 23:30:05 +00:00
committed by GitHub
parent 0d99398689
commit fd6f6b02ea
6 changed files with 424 additions and 7 deletions

View File

@@ -0,0 +1,66 @@
/**
* @license
* Copyright 2025 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import { useState, useEffect, useCallback } from 'react';
import { exec } from 'node:child_process';
import fs from 'node:fs';
import fsPromises from 'node:fs/promises';
import path from 'path';
export function useGitBranchName(cwd: string): string | undefined {
const [branchName, setBranchName] = useState<string | undefined>(undefined);
const fetchBranchName = useCallback(
() =>
exec(
'git rev-parse --abbrev-ref HEAD',
{ cwd },
(error, stdout, _stderr) => {
if (error) {
setBranchName(undefined);
return;
}
const branch = stdout.toString().trim();
if (branch && branch !== 'HEAD') {
setBranchName(branch);
} else {
setBranchName(undefined);
}
},
),
[cwd, setBranchName],
);
useEffect(() => {
fetchBranchName(); // Initial fetch
const gitHeadPath = path.join(cwd, '.git', 'HEAD');
let watcher: fs.FSWatcher | undefined;
const setupWatcher = async () => {
try {
await fsPromises.access(gitHeadPath, fs.constants.F_OK);
watcher = fs.watch(gitHeadPath, (eventType) => {
if (eventType === 'change') {
fetchBranchName();
}
});
} catch (_watchError) {
// Silently ignore watcher errors (e.g. permissions or file not existing),
// similar to how exec errors are handled.
// The branch name will simply not update automatically.
}
};
setupWatcher();
return () => {
watcher?.close();
};
}, [cwd, fetchBranchName]);
return branchName;
}