import { execaCommand } from 'execa' import { cwd } from 'process' async function addFileToStage(filePath: string, cmdPath = cwd()) { try { await execaCommand(`git add ${filePath}`, { stdio: 'ignore', cwd: cmdPath }) } catch (error) { throw new Error(`Git add failed: ${error}`) } } async function checkUnstaged(path = cwd()) { try { const res = await execaCommand('git status -s', { cwd: path }) return res.stdout === '' ? false : res.stdout } catch (error) { throw new Error(`Git status failed: ${error}`) } } async function commitMessage(message: string, path = cwd()) { try { // execaCommand 会自动编译 -m 后的命令,使用 `\\ ` 表示空格 const escapeMessage = message?.replace(/\s/g, `\\ `) await execaCommand(`git commit --allow-empty -m ${escapeMessage}`, { stdio: 'ignore', cwd: path, }) } catch (error) { throw new Error(`Git commit failed: ${error}`) } } async function isInGitRepository(path = cwd()) { try { await execaCommand('git rev-parse --is-inside-work-tree', { stdio: 'ignore', cwd: path }) return true } catch (e) { return false } } async function checkIsInstalledGit(path = cwd()) { try { await execaCommand('git --version', { stdio: 'ignore', cwd: path }) } catch (error) { throw new Error(`No 'git' executable found, please install Git client first.`) } } async function tryGitInit(path = cwd()) { await checkIsInstalledGit(path) if (await isInGitRepository(path)) { throw new Error('Already in git repository.') } try { execaCommand('git init', { stdio: 'ignore', cwd: path }) return true } catch (error) { throw new Error("Couldn't run git init, you can do it manually.") } } async function getCurrentBranchName(path = cwd()) { await checkIsInstalledGit() const { stdout } = await execaCommand('git branch --show-current', { cwd: path, }) return stdout?.trim() } export { isInGitRepository, tryGitInit, getCurrentBranchName, addFileToStage, commitMessage, checkUnstaged, }