git

package
v0.14.0 Latest Latest
Warning

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

Go to latest
Published: Feb 5, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Overview

Package git provides git operations via shell commands.

All operations use os/exec.Command to call the git CLI directly rather than using Go git libraries. This approach is simpler, more reliable, and ensures compatibility with user configurations (SSH keys, credential helpers, aliases).

Worktree Operations

Core worktree management:

Repository Operations

Repository and branch queries:

Repository Discovery

Finding repositories by name or label:

Git worktrees have bidirectional links between the worktree's .git file and the main repo's .git/worktrees/ directory. These can break when repos are moved. Functions for diagnosis and repair:

Batching for Performance

ListWorktrees uses batched git calls to minimize subprocess overhead: one "git worktree list --porcelain" per repo instead of individual calls per worktree. For 10 worktrees across 2 repos, this reduces calls from ~40 to ~8 (or ~18 with dirty checks enabled).

Index

Constants

This section is empty.

Variables

View Source
var ErrGitNotFound = fmt.Errorf("git not found: please install git (https://git-scm.com)")

ErrGitNotFound indicates git is not installed or not in PATH

Functions

func AddLabel

func AddLabel(ctx context.Context, repoPath, label string) error

AddLabel adds a label to a repository (if not already present)

func BranchExists

func BranchExists(ctx context.Context, branch string) (bool, error)

BranchExists checks if a local branch exists

func CanRepairWorktree added in v0.4.0

func CanRepairWorktree(worktreePath string) bool

CanRepairWorktree checks if a worktree can potentially be repaired. Returns true if .git file exists but links are broken.

func CheckGit

func CheckGit() error

CheckGit verifies that git is available in PATH

func ClearBranchNote

func ClearBranchNote(ctx context.Context, repoPath, branch string) error

ClearBranchNote removes the note (description) from a branch

func ClearLabels

func ClearLabels(ctx context.Context, repoPath string) error

ClearLabels removes all labels from a repository

func CloneBareWithWorktreeSupport added in v0.13.0

func CloneBareWithWorktreeSupport(ctx context.Context, url, destPath string) error

CloneBareWithWorktreeSupport clones a repo as a bare repo inside the .git directory. This allows worktrees to be created as siblings while git commands work normally.

The directory structure will be:

destPath/
└── .git/     # bare git repo contents (HEAD, objects/, refs/, etc.)

func CreateWorktree added in v0.13.0

func CreateWorktree(ctx context.Context, gitDir, wtPath, branch string) error

CreateWorktree creates a worktree for an existing branch. gitDir is the .git directory (for regular repos) or the bare repo path. wtPath is the target worktree path. branch is the existing branch to checkout.

func CreateWorktreeNewBranch added in v0.13.0

func CreateWorktreeNewBranch(ctx context.Context, gitDir, wtPath, branch, baseRef string) error

CreateWorktreeNewBranch creates a worktree with a new branch. gitDir is the .git directory (for regular repos) or the bare repo path. wtPath is the target worktree path. branch is the new branch name. baseRef is the starting point (e.g., "origin/main").

func DeleteLocalBranch

func DeleteLocalBranch(ctx context.Context, repoPath, branch string, force bool) error

DeleteLocalBranch deletes a local branch

func ExtractRepoNameFromURL

func ExtractRepoNameFromURL(url string) string

ExtractRepoNameFromURL extracts the repository name from a git URL

func FetchBranch

func FetchBranch(ctx context.Context, repoPath, branch string) error

FetchBranch fetches a specific branch from origin

func FetchDefaultBranch

func FetchDefaultBranch(ctx context.Context, repoPath string) error

FetchDefaultBranch fetches the default branch (main/master) from origin

func FindAllRepos

func FindAllRepos(basePath string) ([]string, error)

FindAllRepos returns paths to all main git repositories in basePath (direct children only). Excludes worktrees (only includes repos where .git is a directory).

func FindRepoByName

func FindRepoByName(basePath, name string) (string, error)

FindRepoByName searches direct children of basePath for a git repo with the given folder name. Matches by folder name only (case-insensitive), excludes worktrees. Returns the full path if found, or an error if not found.

func FindRepoInDirs added in v0.6.0

func FindRepoInDirs(repoName string, searchDirs ...string) string

FindRepoInDirs searches for a repo with the given folder name across multiple directories. Returns the absolute path to the repo if found, empty string otherwise. Similar to FindRepoByName but checks multiple directories (stops at first match).

func FindReposByLabel

func FindReposByLabel(ctx context.Context, repoDir, label string) ([]string, error)

FindReposByLabel scans a directory for repos with the given label Returns paths to matching repositories

func FindSimilarRepos

func FindSimilarRepos(basePath, search string) []string

FindSimilarRepos returns repo names in basePath that contain the search string. Useful for providing suggestions when a repo is not found.

func GetAllBranchConfig

func GetAllBranchConfig(ctx context.Context, repoPath string) (notes map[string]string, upstreams map[string]bool)

GetAllBranchConfig returns branch notes and upstreams for a repository in one call. Uses: `git config --get-regexp 'branch\.'` Returns: notes map (branch -> note), upstreams map (branch -> upstream ref)

func GetBranchCreatedTime

func GetBranchCreatedTime(ctx context.Context, repoPath, branch string) (time.Time, error)

GetBranchCreatedTime returns when the branch was created (first commit on branch) Falls back to first commit time if reflog is unavailable

func GetBranchNote

func GetBranchNote(ctx context.Context, repoPath, branch string) (string, error)

GetBranchNote returns the note (description) for a branch Returns empty string if no note is set

func GetBranchWorktree

func GetBranchWorktree(ctx context.Context, branch string) (string, error)

GetBranchWorktree returns the worktree path if branch is checked out, empty string if not

func GetCommitCount

func GetCommitCount(ctx context.Context, repoPath, branch string) (int, error)

GetCommitCount returns number of commits ahead of the default branch

func GetCommitCountWithBase added in v0.12.0

func GetCommitCountWithBase(ctx context.Context, repoPath, branch, baseBranch string) (int, error)

GetCommitCountWithBase returns number of commits ahead of the given base branch. Use this when you already have the default branch to avoid redundant git calls.

func GetCommitsBehind

func GetCommitsBehind(ctx context.Context, repoPath, branch string) (int, error)

GetCommitsBehind returns number of commits behind the default branch

func GetCommitsBehindWithBase added in v0.12.0

func GetCommitsBehindWithBase(ctx context.Context, repoPath, branch, baseBranch string) (int, error)

GetCommitsBehindWithBase returns number of commits behind the given base branch. Use this when you already have the default branch to avoid redundant git calls.

func GetCurrentBranch

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

GetCurrentBranch returns the current branch name Returns "(detached)" for detached HEAD state

func GetCurrentRepoMainPath

func GetCurrentRepoMainPath(ctx context.Context) string

GetCurrentRepoMainPath returns the main repository path from cwd Works whether you're in the main repo or a worktree Returns empty string if not in a git repo

func GetCurrentRepoMainPathFrom added in v0.8.0

func GetCurrentRepoMainPathFrom(ctx context.Context, path string) string

GetCurrentRepoMainPathFrom returns the main repository path from the given path Works whether you're in the main repo or a worktree Returns empty string if not in a git repo

func GetDefaultBranch

func GetDefaultBranch(ctx context.Context, repoPath string) string

GetDefaultBranch returns the default branch name for the remote (e.g., "main" or "master")

func GetGitDir added in v0.13.0

func GetGitDir(repoPath string, repoType RepoType) string

GetGitDir returns the git directory for a repo

func GetGitDirForWorktree added in v0.13.0

func GetGitDirForWorktree(worktreePath string) (string, error)

GetGitDirForWorktree returns the shared git directory for a worktree or repo. Uses git rev-parse --git-common-dir instead of reading .git files directly.

func GetGitDirForWorktreeWithContext added in v0.13.0

func GetGitDirForWorktreeWithContext(ctx context.Context, worktreePath string) (string, error)

GetGitDirForWorktreeWithContext returns the shared git directory for a worktree or repo.

func GetLabels

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

GetLabels returns the labels for a repository Returns empty slice if no labels are set

func GetLastCommitRelative

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

GetLastCommitRelative returns relative time of last commit

func GetLastCommitTime added in v0.2.0

func GetLastCommitTime(ctx context.Context, path string) (time.Time, error)

GetLastCommitTime returns the unix timestamp of the last commit

func GetMainRepoPath

func GetMainRepoPath(worktreePath string) (string, error)

GetMainRepoPath returns the main repository path from a worktree path. Uses git commands rather than reading .git files directly.

func GetMainRepoPathWithContext added in v0.13.0

func GetMainRepoPathWithContext(ctx context.Context, worktreePath string) (string, error)

GetMainRepoPathWithContext returns the main repository path from a worktree path. Uses git rev-parse --git-common-dir to find the shared git directory.

func GetOriginURL

func GetOriginURL(ctx context.Context, repoPath string) (string, error)

GetOriginURL gets the origin URL for a repository

func GetRepoDisplayName added in v0.4.0

func GetRepoDisplayName(repoPath string) string

GetRepoDisplayName returns the folder name of the repository.

func GetRepoFolderName

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

GetRepoFolderName returns the actual folder name of the git repo on disk Uses git rev-parse --show-toplevel to get the root directory. If inside a worktree, resolves to the main repo folder name.

func GetRepoName

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

GetRepoName extracts the repository name from the origin URL

func GetRepoNameFrom

func GetRepoNameFrom(ctx context.Context, repoPath string) (string, error)

GetRepoNameFrom extracts the repository name from the origin URL of a repo at the given path

func GetRepoNameFromWorktree added in v0.6.0

func GetRepoNameFromWorktree(worktreePath string) string

GetRepoNameFromWorktree extracts the expected repo name from a worktree. Returns the folder name of the main repository.

func GetShortCommitHash

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

GetShortCommitHash returns the short (7 char) commit hash for HEAD in a worktree

func GetUpstreamBranch

func GetUpstreamBranch(ctx context.Context, repoPath, branch string) string

GetUpstreamBranch returns the remote branch name for a local branch. Returns empty string if no upstream is configured.

func GetWorktreeBranches added in v0.8.0

func GetWorktreeBranches(ctx context.Context, repoPath string) map[string]bool

GetWorktreeBranches returns a set of branch names that are currently checked out in worktrees. Useful for filtering out branches that can't be checked out again.

func GroupWorktreesByRepo

func GroupWorktreesByRepo(worktrees []Worktree) map[string][]Worktree

GroupWorktreesByRepo groups worktrees by their main repository

func HasLabel

func HasLabel(ctx context.Context, repoPath, label string) (bool, error)

HasLabel checks if a repository has a specific label

func HasRemote added in v0.12.0

func HasRemote(ctx context.Context, repoPath, remoteName string) bool

HasRemote checks if a remote with the given name exists

func IsDirty

func IsDirty(ctx context.Context, path string) bool

IsDirty returns true if the worktree has uncommitted changes or untracked files

func IsInsideRepo

func IsInsideRepo(ctx context.Context) bool

IsInsideRepo returns true if the current working directory is inside a git repository

func IsInsideRepoPath added in v0.8.0

func IsInsideRepoPath(ctx context.Context, path string) bool

IsInsideRepoPath returns true if the given path is inside a git repository

func IsMainRepo added in v0.10.0

func IsMainRepo(path string) bool

IsMainRepo checks if path is a main git repository (not a worktree). Main repos have .git as a directory; worktrees have .git as a file.

func IsWorktree

func IsWorktree(path string) bool

IsWorktree returns true if path is a git worktree (not main repo) Worktrees have .git as a file pointing to the main repo, while main repos have .git as a directory.

func IsWorktreeLinkValid added in v0.4.0

func IsWorktreeLinkValid(worktreePath string) bool

IsWorktreeLinkValid checks if a worktree's bidirectional link is valid. Returns true if both the .git file in worktree and gitdir in main repo exist and match.

func ListLocalBranches added in v0.8.0

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

ListLocalBranches returns all local branch names for a repository.

func ListPrunableWorktrees added in v0.4.0

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

ListPrunableWorktrees returns worktree paths that git considers stale. Uses `git worktree prune --dry-run` and parses the output.

func ListRemoteBranches added in v0.8.0

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

ListRemoteBranches returns all remote branch names (without origin/ prefix) for a repository.

func MoveWorktree

func MoveWorktree(ctx context.Context, worktree Worktree, newPath string, force bool) error

MoveWorktree moves a git worktree to a new path

func ParseRepoArg

func ParseRepoArg(repo string) (org, name string)

ParseRepoArg splits a repo argument into org and name components. "org/repo" returns ("org", "repo") "repo" returns ("", "repo")

func PruneWorktrees

func PruneWorktrees(ctx context.Context, repoPath string) error

PruneWorktrees prunes stale worktree references

func PushBranch added in v0.14.0

func PushBranch(ctx context.Context, repoPath, branch string) error

PushBranch pushes a branch to origin.

func RemoteBranchExists added in v0.14.0

func RemoteBranchExists(ctx context.Context, repoPath, branch string) bool

RemoteBranchExists checks if a remote tracking branch exists.

func RemoveLabel

func RemoveLabel(ctx context.Context, repoPath, label string) error

RemoveLabel removes a label from a repository

func RemoveWorktree

func RemoveWorktree(ctx context.Context, worktree Worktree, force bool) error

RemoveWorktree removes a git worktree

func RepairWorktree added in v0.4.0

func RepairWorktree(ctx context.Context, repoPath, worktreePath string) error

RepairWorktree attempts to repair broken links for a single worktree. Uses `git worktree repair <path>` from the main repo.

func RepairWorktreesFromRepo added in v0.4.0

func RepairWorktreesFromRepo(ctx context.Context, repoPath string) error

RepairWorktreesFromRepo repairs all worktrees for a repository. Uses `git worktree repair` without arguments to repair all.

func RunGitCommand added in v0.13.0

func RunGitCommand(ctx context.Context, dir string, args ...string) error

RunGitCommand executes a git command with context support and verbose logging. This is the exported version of runGit for use by commands.

func SetBranchNote

func SetBranchNote(ctx context.Context, repoPath, branch, note string) error

SetBranchNote sets a note (description) on a branch

func SetLabels

func SetLabels(ctx context.Context, repoPath string, labels []string) error

SetLabels sets the labels for a repository (replaces existing)

func SetUpstreamBranch added in v0.14.0

func SetUpstreamBranch(ctx context.Context, repoPath, localBranch, upstream string) error

SetUpstreamBranch sets the upstream tracking branch for a local branch. upstream should be "origin/<branch>" or just "<branch>" (will prepend origin/).

func Stash added in v0.10.0

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

Stash creates a stash entry with a specific message. Includes untracked files (-u) to capture all uncommitted changes. Returns nil if successful.

func StashPop added in v0.10.0

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

StashPop applies and removes the most recent stash entry. Returns nil if successful.

func StripRepoPrefix added in v0.13.0

func StripRepoPrefix(repoName, wtName string) string

StripRepoPrefix removes the "repo-" prefix from worktree names if present. For example, if repoName is "myapp" and wtName is "myapp-feature", returns "feature".

Types

type CreateWorktreeResult

type CreateWorktreeResult struct {
	Path          string
	AlreadyExists bool
}

CreateWorktreeResult contains the result of creating a worktree

func AddWorktree

func AddWorktree(ctx context.Context, basePath, branch, worktreeFmt string, createNew bool, baseRef string) (*CreateWorktreeResult, error)

AddWorktree creates a git worktree at basePath/<formatted-name> If createNew is true, creates a new branch (-b flag); otherwise checks out existing branch baseRef is the starting point for new branches (e.g., "origin/main")

func CreateWorktreeFrom

func CreateWorktreeFrom(ctx context.Context, repoPath, basePath, branch, worktreeFmt, baseRef string) (*CreateWorktreeResult, error)

CreateWorktreeFrom creates a worktree from a specified repository path Used when working with a repo that isn't the current working directory baseRef is the starting point for the new branch (e.g., "origin/main", or empty for HEAD)

func OpenWorktreeFrom

func OpenWorktreeFrom(ctx context.Context, absRepoPath, basePath, branch, worktreeFmt string) (*CreateWorktreeResult, error)

OpenWorktreeFrom creates a worktree for an existing branch in a specified repo

type DiffStats

type DiffStats struct {
	Additions int
	Deletions int
	Files     int
}

DiffStats contains diff statistics

func GetDiffStats

func GetDiffStats(ctx context.Context, repoPath, branch string) (DiffStats, error)

GetDiffStats returns additions, deletions, and files changed vs default branch

func GetDiffStatsWithBase added in v0.12.0

func GetDiffStatsWithBase(ctx context.Context, repoPath, branch, baseBranch string) (DiffStats, error)

GetDiffStatsWithBase returns additions, deletions, and files changed vs the given base branch. Use this when you already have the default branch to avoid redundant git calls.

type LastCommitInfo added in v0.12.0

type LastCommitInfo struct {
	Relative string    // Human-readable relative time (e.g., "2 days ago")
	Time     time.Time // Absolute timestamp
}

LastCommitInfo contains both relative and absolute time of the last commit

func GetLastCommitInfo added in v0.12.0

func GetLastCommitInfo(ctx context.Context, path string) (LastCommitInfo, error)

GetLastCommitInfo returns both relative time and absolute timestamp in a single git call. Use this instead of calling GetLastCommitRelative and GetLastCommitTime separately.

type MigrateToBareResult added in v0.13.0

type MigrateToBareResult struct {
	MainWorktreePath string // Path to the new main worktree (e.g., repo/main)
	GitDir           string // Path to the .git directory
}

MigrateToBareResult contains the result of a successful migration

func MigrateToBare added in v0.13.0

func MigrateToBare(ctx context.Context, plan *MigrationPlan) (*MigrateToBareResult, error)

MigrateToBare converts a regular repo to bare-in-.git format. This preserves all working tree files including uncommitted changes.

type MigrationOptions added in v0.14.0

type MigrationOptions struct {
	WorktreeFormat string // Format string for worktree paths (e.g., "{branch}", "../{repo}-{branch}")
	RepoName       string // Repository name for path resolution
}

MigrationOptions configures how the migration computes worktree paths

type MigrationPlan added in v0.13.0

type MigrationPlan struct {
	RepoPath           string // Original repo path
	GitDir             string // Current .git directory path
	CurrentBranch      string // Branch to use for main worktree
	MainBranchUpstream string // Upstream for the main branch (e.g., "main" for origin/main)
	MainWorktreePath   string // Computed path for the main worktree
	WorktreesToFix     []WorktreeMigration
	HasSubmodules      bool
}

MigrationPlan describes what will be done during migration

func ValidateMigration added in v0.13.0

func ValidateMigration(ctx context.Context, repoPath string, opts MigrationOptions) (*MigrationPlan, error)

ValidateMigration checks if a repo can be migrated and returns the migration plan. The opts parameter configures how worktree paths are computed.

type RepoType added in v0.13.0

type RepoType int

RepoType indicates whether a repo is bare or regular

const (
	RepoTypeRegular RepoType = iota
	RepoTypeBare
)

func DetectRepoType added in v0.13.0

func DetectRepoType(path string) (RepoType, error)

DetectRepoType determines if a path is a bare or regular git repository

type Worktree

type Worktree struct {
	Path           string    `json:"path"`
	Branch         string    `json:"branch"`
	MainRepo       string    `json:"main_repo"`
	RepoName       string    `json:"repo_name"`
	OriginURL      string    `json:"origin_url"`
	IsMerged       bool      `json:"is_merged"`
	CommitCount    int       `json:"commit_count"`
	IsDirty        bool      `json:"is_dirty"` // only populated when includeDirty=true
	HasUpstream    bool      `json:"has_upstream"`
	LastCommit     string    `json:"last_commit"`
	LastCommitTime time.Time `json:"last_commit_time"` // for sorting by commit date
	Note           string    `json:"note,omitempty"`
}

Worktree represents a git worktree with its status

func FilterWorktreesByRepo added in v0.10.0

func FilterWorktreesByRepo(worktrees []Worktree, mainRepoPath string) []Worktree

FilterWorktreesByRepo returns worktrees that belong to the given main repo path.

func GetWorktreeInfo

func GetWorktreeInfo(ctx context.Context, path string) (*Worktree, error)

GetWorktreeInfo returns info for a single worktree at the given path

func ListWorktrees

func ListWorktrees(ctx context.Context, worktreeDir string, includeDirty bool) ([]Worktree, error)

ListWorktrees scans a directory for git worktrees with batched git calls per repo. If includeDirty is true, checks each worktree for dirty status (adds subprocess calls). For 10 worktrees across 2 repos: ~8 calls (list) or ~18 calls with dirty checks (prune).

func (*Worktree) Status added in v0.8.0

func (w *Worktree) Status() string

Status returns a human-readable status string for the worktree. Priority: dirty > merged/prunable > commits ahead > clean

type WorktreeInfo

type WorktreeInfo struct {
	Path       string
	Branch     string
	CommitHash string // Full hash from git, caller can truncate
}

WorktreeInfo contains basic worktree information from git worktree list.

func ListWorktreesFromRepo

func ListWorktreesFromRepo(ctx context.Context, repoPath string) ([]WorktreeInfo, error)

ListWorktreesFromRepo returns all worktrees for a repository using git worktree list --porcelain -z. Uses NUL-separated output for robust parsing of paths with special characters. Skips bare worktrees (e.g., .bare directory in bare repo layouts).

type WorktreeMigration added in v0.13.0

type WorktreeMigration struct {
	OldPath   string // Current worktree path
	NewPath   string // New path after migration (may be same)
	Branch    string
	Upstream  string // Upstream branch (e.g., "feature" for origin/feature)
	OldName   string // Name in .git/worktrees/
	NewName   string // Name after migration (may be same)
	NeedsMove bool   // Whether the worktree folder needs to be moved
	IsOutside bool   // Whether worktree is outside the repo directory
}

WorktreeMigration describes a worktree that needs to be updated

Jump to

Keyboard shortcuts

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