Skip to content

Branches & commits

functionlistBranches
listBranches(repo: Repo): Promise<Branch[]>

Returns: Promise<Branch[]>

Every branch with its tip commit — { name, commit, isDefault }[]. [] for an empty repository, not an error.

createBranchFrom(repo: Repo, name: string, startPoint: string): Promise<void>
ParameterTypeDescription
namestringThe new branch name.
startPointstringThe branch the new one starts from.

Creates name pointing at the tip of startPoint. No checkout — this package targets bare repositories.

deleteBranchByName(repo: Repo, name: string): Promise<void>
ParameterTypeDescription
namestringThe branch to delete.

Validated internally — git.deleteBranch has no built-in ref-format check the way git.branch does, so this validates name before it ever reaches isomorphic-git.

assertBranchExists(repo: Repo, name: string): Promise<void>
ParameterTypeDescription
namestringThe branch to check.

Throws (isomorphic-git’s NotFoundError) unless the branch resolves. Useful as a cheap existence guard before a more expensive operation.

authorNow builds a CommitAuthor stamped with the current time — the shape every commit-writing function below expects:

interface CommitAuthor {
name: string;
email: string;
timestamp: number;
timezoneOffset: number;
}
const author = authorNow('Ada', 'ada@example.com');
commitFilesToBare(repo: Repo, options: { branch, message, author, files }): Promise<string>
ParameterTypeDescription
branchstringThe branch to commit onto (created if it doesn't exist).
messagestringCommit message.
authorCommitAuthorFrom authorNow or your own.
filesArray<{ path, content }>content is string | Uint8Array.

Returns: Promise<string>

Writes a commit directly to the bare repo — no worktree, no checkout. Each blob is content-addressed and independent of the others, so all files in the batch are written in parallel.

deleteFileFromBare(repo: Repo, options: { branch, filePath, message, author }): Promise<string>
ParameterTypeDescription
branchstringThe branch to commit onto.
filePathstringThe path to remove.
messagestringCommit message.
authorCommitAuthor

Returns: Promise<string>

Commits the removal of one file. Throws if the branch is empty (nothing to remove).

writeCommitToBare(repo: Repo, options: { branch, message, author, buildTree }): Promise<string>
ParameterTypeDescription
branchstringThe branch to commit onto.
messagestringCommit message.
authorCommitAuthor
buildTree(parentTreeOid: string | undefined, writeRepo: Repo) => Promise<string>Receives the parent tree oid (undefined for an empty repo) and the repo to write through, returns the new root tree oid. Write every object via writeRepo — writes through the outer repo bypass the pack and land loose.

Returns: Promise<string>

The primitive commitFilesToBare/deleteFileFromBare are built on — reach for it directly when neither fits (a multi-step tree rewrite, a merge commit with a synthetic tree). Handles the parent-resolution, commit-object, and ref-update mechanics; you own tree construction via buildTree. Every object the commit creates is stored as one pack (see withPackedWrites below), written before the ref.

withPackedWrites<T>(repo: Repo, fn: (packedRepo: Repo) => Promise<T>): Promise<T>

Returns: Promise<T>

Runs fn with a view of repo whose new loose objects are buffered in memory and stored as a single pack — flushed (pack, then index) before any other file is written inside fn (so a ref never becomes visible before the objects it names), and once more when fn resolves. Wrap any plumbing that writes objects (writeBlob/writeTree/writeCommit, or a library like git-edge’s threeWayMerge) in it. Two PUTs per operation instead of one per object — and a repository that is never given loose objects keeps the loose-object hint correct across processes (see the production stack guide).

Paths passed to commitFilesToBare/deleteFileFromBare must satisfy isSafeTreePath: relative, no empty, . or .. segments, no .git segment in any case, no NUL. An updated file keeps its existing mode (executable bit, symlink). A path that names an existing directory, or runs through an existing file, is a GitInvalidRequestError; deleting a path that isn’t a file is a GitPathNotFoundError, and a directory a delete leaves empty is removed. createBranchFrom throws GitConflictError for a name that exists; deleteBranchByName refuses the branch HEAD names.

Serialize concurrent writers to the same repo externally (a per-repo lock) — the resolve-parent → write-commit → update-ref sequence is not atomic on object storage.