@hyperfrontend/versioning/git/operationsoperations
Typed wrappers around git shell commands — log, tag, commit, staging, status, and diff — returning structured data instead of raw text.
The commit family (commit, amendCommit, amendCommitNoEdit, createEmptyCommit) drives git commit with safe argument escaping (escapeFilePath, escapeAuthor). The tag family covers creation (createTag), querying (listTags), and lookup (getTag). Diff helpers (getChangedFilesBetween, getChangedFilesBetweenWithStatus, getCommitWithFiles) return typed FileChange[] and GitCommitWithFiles shapes. Status (getStatus, returning RepositoryStatus with FileStatusEntry[]) and staging (stage, discardChanges) round out the everyday git surface. GitOperationState captures retry/idempotency reasons for steps that can be safely re-run.
API Reference
ƒ Functions
Parameters
Returns
GitCommitExample
Amend the last commit with a new message
const commit = amendCommit('feat: improved feature')Parameters
| Name | Type | Description |
|---|---|---|
§options | Omit<CreateCommitOptions, "amend" | "noEdit"> | Configuration for the commit operation (default: {}) |
Returns
GitCommitExample
Add staged changes to last commit without changing message
stage(['extra-file.ts'])
amendCommitNoEdit() // adds staged files to last commitParameters
Returns
GitCommitExample
Create a new commit
const commit = createCommit('feat: add new feature')
const commit = createCommit('fix: resolve bug', { body: 'Detailed description' })Parameters
Returns
booleanExample
Check if a commit exists in the repository
if (commitExists('abc123def')) {
console.log('Commit found in repository')
}commitReachableFromHead(hash: string, options: Pick<GitLogOptions, "cwd" | "timeout">): boolean
A commit may exist in the repository but be orphaned (not in current branch history). This function verifies that the commit is actually in the history of the current HEAD.
Common use cases:
- Verify an external commit reference before using it for range queries
- Detect if history was rewritten (rebase/force push) after a reference was recorded
Parameters
Returns
booleanExample
Check if commit is reachable from HEAD
if (commitReachableFromHead(baseCommit)) {
// Safe to use for commit range queries
const commits = getCommitsSince(baseCommit)
} else {
// Commit not in current history, need fallback strategy
}createEmptyCommit(message: string, options: Omit<CreateCommitOptions, "allowEmpty">): GitCommit
Parameters
Returns
GitCommitExample
Create an empty commit for CI triggers
const commit = createEmptyCommit('chore: trigger CI')Parameters
Returns
GitTagExample
Create lightweight and annotated tags
// Create lightweight tag
const tag = createTag('v1.0.0')
// Create annotated tag
const tag = createTag('v1.0.0', { message: 'Release v1.0.0' })Parameters
Returns
booleanExample
Delete a tag by name
const deleted = deleteTag('v1.0.0')Combines
discardChanges() + unstage(['.']) for complete working tree reset. Warning: Destructive operation — discarded changes cannot be recovered.
Parameters
| Name | Type | Description |
|---|---|---|
§options | GitCommitOptions | Configuration for the operation (default: {}) |
Returns
booleanExample
Reset working directory to match HEAD
// Reset working directory to match HEAD
if (discardAllChanges()) {
console.log('Working tree reset to HEAD')
}Uses
git checkout -- <files> to restore files from HEAD. Returns true if successful, false otherwise (silent failure pattern). Warning: Destructive operation — discarded changes cannot be recovered.
Parameters
| Name | Type | Description |
|---|---|---|
§options | DiscardChangesOptions | Configuration including optional file list (default: {}) |
Returns
booleanExamples
Discard changes in tracked files
// Discard all changes
discardChanges()
// Discard specific files
discardChanges({ files: ['package.json', 'CHANGELOG.md'] })Typical rollback pattern
// Typical rollback pattern
if (hasUnstagedChanges()) {
discardChanges()
}
if (hasStagedChanges()) {
unstage(['.'])
}Parameters
| Name | Type | Description |
|---|---|---|
§author | string | Author to escape |
Returns
stringExample
Escape an author string for git commit
const safeAuthor = escapeAuthor('John Doe <john@example.com>')
// => 'John Doe <john@example.com>'Parameters
| Name | Type | Description |
|---|---|---|
§path | string | Path to escape |
Returns
stringExample
Escape a file path for git commands
const safePath = escapeFilePath('src/utils/helper.ts')
// => 'src/utils/helper.ts'
escapeFilePath('file$name.ts') // throws - '$' is invalidParameters
| Name | Type | Description |
|---|---|---|
§arg | string | Argument to escape |
Returns
stringExample
Escape a git argument for shell commands
escapeGitArg('John Doe <john@example.com>') // => 'John Doe <john@example.com>'Parameters
| Name | Type | Description |
|---|---|---|
§message | string | Message to escape |
Returns
stringExample
Escape a git commit message
const safeMessage = escapeGitMessage('Release v1.0.0 "stable"')
// => 'Release v1.0.0 \"stable\"'Parameters
| Name | Type | Description |
|---|---|---|
§path | string | Path to escape |
Returns
stringExample
Escape a file path for git commands
escapeGitPath('src/utils/helper.ts') // => 'src/utils/helper.ts'
escapeGitPath('path with spaces/file.ts') // => 'path with spaces/file.ts'Parameters
| Name | Type | Description |
|---|---|---|
§ref | string | Reference to escape |
Returns
stringExample
Escape a git reference for shell commands
escapeGitRef('refs/heads/main') // => 'refs/heads/main'
escapeGitRef('feature/test') // => 'feature/test'
escapeGitRef('ref$invalid') // throws - '$' is invalidParameters
| Name | Type | Description |
|---|---|---|
§pattern | string | Pattern to escape |
Returns
stringExample
Escape a tag pattern for git commands
const safePattern = escapeGitTagPattern('@scope/package@')
// => '@scope/package@'
escapeGitTagPattern('v1.0.*') // throws - '*' is invalidParameters
| Name | Type | Description |
|---|---|---|
§options | GitStatusOptions | Status options (default: {}) |
Returns
numberExample
Get commits ahead of upstream
const ahead = getAheadCount()
console.log(`${ahead} commits to push`)Parameters
| Name | Type | Description |
|---|---|---|
§options | GitStatusOptions | Status options (default: {}) |
Returns
numberExample
Get commits behind upstream
const behind = getBehindCount()
console.log(`${behind} commits to pull`)Uses
git diff --name-only base...head which computes the merge-base internally, giving files changed in head since diverging from base.Parameters
Returns
unknownExample
Get changed files between refs
// Files changed since diverging from main
const files = getChangedFilesBetween('origin/main')
// Files changed between two tags
const files = getChangedFilesBetween('v1.0.0', 'v2.0.0')getChangedFilesBetweenWithStatus(base: string, head: string, options: DiffOptions): unknown
Parameters
Returns
unknownExample
Get file changes with status information
const changes = getChangedFilesBetweenWithStatus('v1.0.0', 'v2.0.0')
const added = changes.filter(c => c.status === 'added')Parameters
Returns
GitCommitExample
Get a single commit by hash
const commit = getCommit('abc1234')Parameters
| Name | Type | Description |
|---|---|---|
§options | GitLogOptions | Configuration for retrieving the commit log (default: {}) |
Returns
unknownExample
Get commit log with options
const commits = getCommitLog({ maxCount: 10 })
const recentChanges = getCommitLog({ from: 'v1.0.0', to: 'HEAD' })getCommitsBetween(from: string, to: string, options: Omit<GitLogOptions, "from" | "to">): unknown
Parameters
Returns
unknownExample
Get commits between two references
const commits = getCommitsBetween('v1.0.0', 'v1.1.0')Parameters
Returns
unknownExample
Get commits since a tag
const commits = getCommitsSince('v1.0.0')Uses
git diff-tree to retrieve file changes for a single commit. More efficient than fetching files for all commits when only specific commits need file attribution.Parameters
Returns
GitCommitWithFilesExample
Get commit with its changed files
const commit = getCommitWithFiles('abc123')
if (commit) {
console.log(`${commit.subject} touched ${commit.files.length} files`)
}Parameters
| Name | Type | Description |
|---|---|---|
§options | GitCommitOptions | Configuration for the operation (default: {}) |
Returns
stringExample
Get the current branch name
const branch = getCurrentBranch()Parameters
| Name | Type | Description |
|---|---|---|
§options | GitCommitOptions | Git operation configuration (default: {}) |
Returns
stringExample
Get the current HEAD commit
const head = getHead()Parameters
| Name | Type | Description |
|---|---|---|
§options | GitStatusOptions | Status options (default: {}) |
Returns
stringExample
Get the current HEAD commit hash
const hash = getHeadHash()
// => 'abc123def456789012345678901234567890abcd'Parameters
| Name | Type | Description |
|---|---|---|
§options | GitStatusOptions | Status options (default: {}) |
Returns
stringExample
Get the short HEAD commit hash
const shortHash = getHeadShortHash()
// => 'abc123d'Parameters
| Name | Type | Description |
|---|---|---|
§options | ListTagsOptions | Tag options with optional pattern (default: {}) |
Returns
GitTagExample
Get the latest tag by creation date
const latest = getLatestTag()
const latestVersion = getLatestTag({ pattern: 'v' })Parameters
| Name | Type | Description |
|---|---|---|
§options | GitStatusOptions | Status options (default: {}) |
Returns
unknownExample
Get list of modified files
const modified = getModifiedFiles()
// => ['src/utils.ts', 'README.md']Uses filesystem checks on
.git/ state files rather than git commands. This is more reliable because file existence checks are atomic OS syscalls that work even when the git index is corrupted or git commands would hang. Handles worktrees, submodules, and
$GIT_DIR overrides via git rev-parse --git-dir.Parameters
| Name | Type | Description |
|---|---|---|
§options | GitCommitOptions | Configuration for the state check (default: {}) |
Returns
GitOperationStateExample
Detect if git is mid-operation
const state = getOperationState()
if (state.inProgress) {
console.warn(`Cannot proceed: git ${state.reason} in progress`)
}Parameters
| Name | Type | Description |
|---|---|---|
§options | GitStatusOptions | Status options (default: {}) |
Returns
stringExample
Get the repository root directory
const root = getRepositoryRoot()Parameters
| Name | Type | Description |
|---|---|---|
§options | GitStatusOptions | Status options (default: {}) |
Returns
unknownExample
Get list of staged files
const staged = getStagedFiles()
// => ['src/index.ts', 'package.json']Parameters
| Name | Type | Description |
|---|---|---|
§options | GitStatusOptions | Configuration for the status query (default: {}) |
Returns
RepositoryStatusExample
Get the full repository status
const status = getStatus()
if (!status.clean) {
console.log('Working tree has changes')
}Parameters
Returns
GitTagExample
Get detailed information about a specific tag
const tag = getTag('v1.0.0')Parameters
| Name | Type | Description |
|---|---|---|
§options | ListTagsOptions | Tag listing options (default: {}) |
Returns
unknownExample
Get all tags from the repository
const tags = getTags()
const versionTags = getTags({ pattern: 'v' })Parameters
Returns
unknownExample
Get tags matching a package name
const tags = getTagsForPackage('@scope/pkg')Parameters
| Name | Type | Description |
|---|---|---|
§options | GitStatusOptions | Status options (default: {}) |
Returns
unknownExample
Get list of untracked files
const untracked = getUntrackedFiles()
// => ['new-file.ts', 'temp.log']Parameters
| Name | Type | Description |
|---|---|---|
§options | GitStatusOptions | Status options (default: {}) |
Returns
booleanExample
Check for merge conflicts
if (hasConflicts()) {
console.log('Resolve merge conflicts before continuing')
}Parameters
| Name | Type | Description |
|---|---|---|
§options | GitCommitOptions | Configuration for the operation (default: {}) |
Returns
booleanExample
Check for staged changes before committing
if (hasStagedChanges()) { createCommit('...') }Parameters
| Name | Type | Description |
|---|---|---|
§options | GitCommitOptions | Configuration for the operation (default: {}) |
Returns
booleanExample
Check for unstaged changes before staging
if (hasUnstagedChanges()) { stage(['.']) }Parameters
| Name | Type | Description |
|---|---|---|
§options | GitCommitOptions | Configuration for the operation (default: {}) |
Returns
booleanExample
Check for untracked files
if (hasUntrackedFiles()) {
console.log('New files detected that are not tracked by git')
}Parameters
| Name | Type | Description |
|---|---|---|
§options | GitStatusOptions | Configuration for the status check (default: {}) |
Returns
booleanExample
Check if working tree is clean
if (!isClean()) {
throw new Error('Working tree has changes')
}Parameters
| Name | Type | Description |
|---|---|---|
§options | GitStatusOptions | Status options (default: {}) |
Returns
booleanExample
Check if directory is a git repository
if (!isGitRepository()) {
throw new Error('Not a git repository')
}Convenience wrapper around
getOperationState() for simple checks. Use getOperationState() directly when you need to know which operation is in progress.Parameters
| Name | Type | Description |
|---|---|---|
§options | GitCommitOptions | Configuration for the state check (default: {}) |
Returns
booleanExample
Check for incomplete operations
if (isOperationInProgress()) {
throw new Error('Complete or abort the current git operation first')
}Parameters
| Name | Type | Description |
|---|---|---|
§options | GitStatusOptions | Status options (default: {}) |
Returns
booleanExample
Check if repository needs to be pulled
if (needsPull()) {
console.log('Remote commits need to be pulled')
}Parameters
| Name | Type | Description |
|---|---|---|
§options | GitStatusOptions | Status options (default: {}) |
Returns
booleanExample
Check if repository needs to be pushed
if (needsPush()) {
console.log('Local commits need to be pushed')
}Parameters
Returns
booleanExample
Push a tag to remote
pushTag('v1.0.0')
pushTag('v1.0.0', 'upstream')Parameters
Returns
booleanExample
Stage files for commit
stage(['package.json', 'CHANGELOG.md'])
stage(['.'], { all: true })Parameters
| Name | Type | Description |
|---|---|---|
§options | GitCommitOptions | Configuration for the staging operation (default: {}) |
Returns
booleanExample
Stage all tracked and untracked changes
stageAll() // stages all tracked and untracked changesParameters
Returns
booleanExample
Check if a tag exists
if (tagExists('v1.0.0')) { ... }Parameters
Returns
booleanExample
Unstage files from the index
unstage(['package.json'])◈ Interfaces
Properties
Properties
Properties
Properties
Properties
readonly details:{ mergeHead: boolean; rebaseApply: boolean; rebaseMerge: boolean }— readonly reason:GitOperationStateReason— Properties
Properties
◆ Types
type FileChangeStatus = "added" | "modified" | "deleted" | "renamed" | "copied"type FileStatus = "modified" | "added" | "deleted" | "renamed" | "copied" | "untracked" | "ignored" | "unmerged"type GitOperationStateOptions = GitCommitOptionsThese correspond to state files that git creates during multi-step operations:
'rebase-interactive':.git/rebase-mergeexists (interactive rebase paused)'rebase-apply':.git/rebase-applyexists (mailbox-based rebase orgit am)'merge-in-progress':.git/MERGE_HEADexists (merge awaiting conflict resolution)
type GitOperationStateReason = "rebase-interactive" | "rebase-apply" | "merge-in-progress"