git

package
v0.20.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 29, 2026 License: MIT Imports: 10 Imported by: 0

Documentation

Overview

Package git wraps os/exec calls to the git binary and is the sole interface through which safegit interacts with git plumbing commands. All functions shell out to git and return structured results; no other package may invoke git directly.

Index

Constants

This section is empty.

Variables

View Source
var ErrDetachedHead = fmt.Errorf("HEAD is detached (not on a branch); check out a branch first or use --branch")

ErrDetachedHead is returned when HEAD is not on a branch.

Functions

func AddFile

func AddFile(ctx context.Context, indexPath, filePath string) error

AddFile stages a file into a custom index.

func CatFileBlob added in v0.14.0

func CatFileBlob(ctx context.Context, sha string) ([]byte, error)

CatFileBlob reads blob content by SHA via git cat-file -p.

func CommitMessage

func CommitMessage(ctx context.Context, rev string) (string, error)

CommitMessage returns the full commit message of the given revision.

func CommitTree

func CommitTree(ctx context.Context, treeSHA, parentSHA, message string) (string, error)

CommitTree creates a commit object from a tree SHA and parent, returns commit SHA. If parentSHA is empty, creates a root commit.

func CommitTreeWithAuthor added in v0.7.0

func CommitTreeWithAuthor(ctx context.Context, treeSHA string, parentSHAs []string, message string, author, committer AuthorInfo) (string, error)

CommitTreeWithAuthor creates a commit object with explicit author and committer identity, returning the new commit SHA.

func CommonGitDir added in v0.1.1

func CommonGitDir(ctx context.Context) (string, error)

CommonGitDir returns the path to the shared .git directory. For normal repos this equals GitDir(); for worktrees it returns the main .git dir that is shared across all worktrees. Lock files should live here so that worktrees committing to the same branch serialize correctly.

func ForEachRef added in v0.18.0

func ForEachRef(ctx context.Context, format string, prefixes ...string) ([]string, error)

ForEachRef runs git for-each-ref with the given format and optional ref prefixes (e.g. "refs/heads/", "refs/tags/"). Returns one line per ref.

func GitDir

func GitDir(ctx context.Context) (string, error)

GitDir returns the path to the .git directory.

func HashObject added in v0.11.0

func HashObject(ctx context.Context, path string) (string, error)

HashObject returns the blob SHA for a file without writing to the object store.

func HashObjectWrite added in v0.12.0

func HashObjectWrite(ctx context.Context, path string) (string, error)

HashObjectWrite hashes a file and writes the blob to the object store, returning the blob SHA.

func HashObjectWriteBytes added in v0.14.0

func HashObjectWriteBytes(ctx context.Context, data []byte) (string, error)

HashObjectWriteBytes writes in-memory bytes as a blob to the object store via git hash-object -w --stdin, returning the blob SHA.

func HeadRef

func HeadRef(ctx context.Context) (string, error)

HeadRef returns the current branch ref (e.g. "refs/heads/main"). Returns ErrDetachedHead if HEAD is not on a branch.

func IsAncestorOf added in v0.13.0

func IsAncestorOf(ctx context.Context, commitSHA, descendantSHA string) (bool, error)

IsAncestorOf checks whether commitSHA is an ancestor of (or equal to) descendantSHA. Uses git merge-base --is-ancestor which exits 0 if true, 1 if false, and other codes on error.

func IsIgnored

func IsIgnored(ctx context.Context, filePath string) (bool, error)

IsIgnored checks whether a file matches a gitignore rule.

func IsTracked

func IsTracked(ctx context.Context, filePath string) (bool, error)

IsTracked checks whether a file is tracked by git (present in HEAD tree). Uses cat-file instead of ls-files because safegit never writes to the main index -- files committed via safegit exist in HEAD but not in .git/index.

func ListSkipWorktreeFiles added in v0.9.0

func ListSkipWorktreeFiles(ctx context.Context) ([]string, error)

ListSkipWorktreeFiles returns the paths of all files with the skip-worktree flag set in the main index. It parses `git ls-files -v` output, selecting lines that start with "S " (the skip-worktree indicator).

func ListTrackedIgnoredFiles added in v0.17.1

func ListTrackedIgnoredFiles(ctx context.Context) ([]string, error)

ListTrackedIgnoredFiles returns the paths of all files that are tracked in the index but ignored by .gitignore rules. These are files that were once committed and later gitignored -- read-tree --reset -u would overwrite them, destroying local modifications (e.g., config files with secrets).

func LsRemoteBulk added in v0.18.0

func LsRemoteBulk(ctx context.Context, remote, pattern string) (map[string]string, error)

LsRemoteBulk runs git ls-remote against a remote with a pattern and returns a map of refname to SHA. The output format of git ls-remote is "<SHA>\t<refname>" per line; the map key is the refname.

func MkTree added in v0.12.0

func MkTree(ctx context.Context, entries []TreeEntry) (string, error)

MkTree creates a tree object from a slice of TreeEntry values and returns the tree SHA. Each entry must have Mode, ObjectType, SHA, and Path populated. Input is piped to `git mktree` as "<mode> <type> <sha>\t<name>\n".

func ReadTree

func ReadTree(ctx context.Context, indexPath, treeish string) error

ReadTree populates a temporary index from a treeish (commit/tree SHA or ref).

func RepoRoot

func RepoRoot(ctx context.Context) (string, error)

RepoRoot returns the absolute path to the repository root.

func RevParse

func RevParse(ctx context.Context, rev string) (string, error)

RevParse resolves a revision to a full SHA.

func RmCached

func RmCached(ctx context.Context, indexPath, filePath string) error

RmCached removes a file or directory from a custom index without touching the working tree.

func Run

func Run(ctx context.Context, args ...string) (stdout, stderr string, err error)

Run executes a git command and returns stdout, stderr, and any error.

func RunPassthrough added in v0.1.1

func RunPassthrough(ctx context.Context, args ...string) error

RunPassthrough executes a git command with stdin/stdout/stderr wired to the terminal (os.Stdin, os.Stdout, os.Stderr). It prepends --no-optional-locks like Run, but does not capture output -- suitable for interactive/pager commands.

func RunWithEnv

func RunWithEnv(ctx context.Context, env []string, args ...string) (stdout, stderr string, err error)

RunWithEnv executes a git command with additional environment variables.

func RunWithEnvStdin

func RunWithEnvStdin(ctx context.Context, env []string, stdin []byte, args ...string) (stdout, stderr string, err error)

RunWithEnvStdin executes a git command with environment variables and stdin data.

func RunWithGitDir added in v0.15.0

func RunWithGitDir(ctx context.Context, gitDir string, workTree string, args ...string) (stdout, stderr string, err error)

RunWithGitDir executes a git command against a specific git directory and work tree, rather than relying on cwd-based discovery. Sets GIT_DIR, GIT_WORK_TREE, and cmd.Dir so both git and cwd-relative paths resolve against the target repo.

func SplitNonEmpty added in v0.18.2

func SplitNonEmpty(s string) []string

SplitNonEmpty splits s by newlines and returns only non-empty lines.

func SyncMainIndex

func SyncMainIndex(ctx context.Context, treeish string) error

SyncMainIndex updates the main .git/index to match the given treeish. This makes git status/diff reflect the committed state after safegit commits. Skip-worktree flags are preserved across the read-tree rebuild.

func SyncMainIndexWithWorktree added in v0.16.0

func SyncMainIndexWithWorktree(ctx context.Context, treeish string) ([]string, error)

SyncMainIndexWithWorktree updates the main .git/index AND the working tree to match the given treeish. Uses --reset -u, so the working tree must be clean before calling. Needed after history rewrites (scrub) where committed blobs have changed and the working tree must reflect the new content.

Tracked+gitignored files (committed then later gitignored, e.g., config files with secrets) are protected: skip-worktree is set before read-tree so --reset -u does not overwrite them. Pre-existing skip-worktree flags are also preserved.

Returns the list of protected tracked+gitignored paths (empty if none).

func UpdateRef

func UpdateRef(ctx context.Context, ref, newSHA, oldSHA string) error

UpdateRef atomically updates a ref using compare-and-swap. oldSHA is the expected current value; if empty, the ref must not exist.

func WithDir added in v0.20.0

func WithDir(ctx context.Context, gitDir, workTree string) context.Context

WithDir returns a context that carries git directory overrides. All git functions that receive this context will automatically set GIT_DIR, GIT_WORK_TREE, and cmd.Dir on the subprocess, targeting the specified repo regardless of the process's current working directory.

func WriteTree

func WriteTree(ctx context.Context, indexPath string) (string, error)

WriteTree writes the index content as a tree object, returns the tree SHA.

Types

type AuthorInfo added in v0.7.0

type AuthorInfo struct {
	Name  string
	Email string
	Date  string // raw git date format: "1234567890 +0200"
}

AuthorInfo holds the name, email, and raw git date for an author or committer.

type CommitInfo added in v0.7.0

type CommitInfo struct {
	Tree      string
	Parents   []string
	Author    AuthorInfo
	Committer AuthorInfo
	Message   string
}

CommitInfo holds the parsed contents of a git commit object.

func ParseCommit added in v0.7.0

func ParseCommit(ctx context.Context, sha string) (CommitInfo, error)

ParseCommit reads and parses a commit object by SHA using git cat-file.

type ObjectEntry added in v0.14.0

type ObjectEntry struct {
	SHA     string
	Type    string // "blob", "commit", or "tag" (trees are skipped)
	Size    int
	Content []byte
}

ObjectEntry holds one object read from a git cat-file --batch stream.

type ObjectIterator added in v0.14.0

type ObjectIterator struct {
	// contains filtered or unexported fields
}

ObjectIterator streams objects from a long-running git cat-file process.

func CatFileBatchAll added in v0.14.0

func CatFileBatchAll(ctx context.Context) (*ObjectIterator, error)

CatFileBatchAll starts a git cat-file --batch-all-objects --batch subprocess and returns an ObjectIterator for streaming the results. The caller must call Close() when done. Respects WithDir context overrides.

func CatFileBatchAllWithDir added in v0.15.0

func CatFileBatchAllWithDir(ctx context.Context, gitDir string) (*ObjectIterator, error)

CatFileBatchAllWithDir starts a git cat-file --batch-all-objects --batch subprocess targeting a specific git directory. Returns an ObjectIterator for streaming the results. The caller must call Close() when done.

func CatFileBatchSHAs added in v0.18.2

func CatFileBatchSHAs(ctx context.Context, shas []string) (*ObjectIterator, error)

CatFileBatchSHAs starts a git cat-file --batch subprocess that reads only the specified SHAs, and returns an ObjectIterator for streaming the results. Unlike CatFileBatchAll (which enumerates all objects), this feeds specific SHAs via stdin using bytes.NewReader to avoid pipe deadlock: if output exceeds the OS pipe buffer (~64KB), git blocks on stdout write while the caller is still writing to stdin. With bytes.NewReader, git reads stdin from memory at its own pace. The caller must call Close() when done.

func CatFileBatchSHAsWithDir added in v0.18.3

func CatFileBatchSHAsWithDir(ctx context.Context, gitDir string, shas []string) (*ObjectIterator, error)

CatFileBatchSHAsWithDir starts a git cat-file --batch subprocess targeting a specific git directory, reading only the specified SHAs. Sets GIT_DIR so git resolves objects from the target repo rather than the cwd repo. The caller must call Close() when done.

func (*ObjectIterator) Close added in v0.14.0

func (it *ObjectIterator) Close() error

Close kills the subprocess if it is still running and waits for it to exit.

func (*ObjectIterator) Next added in v0.14.0

func (it *ObjectIterator) Next() (*ObjectEntry, error)

Next reads the next non-tree object from the stream. Trees are silently skipped. Returns io.EOF when the stream ends.

type TreeEntry added in v0.11.0

type TreeEntry struct {
	SHA        string // SHA of the object (blob or tree)
	Path       string // repo-relative path (full path for recursive, basename for non-recursive)
	Mode       string // file mode (e.g. "100644", "040000")
	ObjectType string // object type (e.g. "blob", "tree")
}

TreeEntry represents an entry from git ls-tree (blob, tree, or other object).

func LsTree added in v0.12.0

func LsTree(ctx context.Context, treeish string) ([]TreeEntry, error)

LsTree returns all entries (blobs and subtrees) at one level of the given treeish, without recursing into subtrees. Each entry includes Mode and ObjectType so callers can distinguish blobs from trees.

func LsTreeAll added in v0.11.0

func LsTreeAll(ctx context.Context, treeish string) ([]TreeEntry, error)

LsTreeAll returns all blob entries in the given treeish, recursively. Empty trees return an empty slice, not an error.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL