scanner

package
v1.4.0 Latest Latest
Warning

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

Go to latest
Published: Jun 11, 2026 License: BSD-2-Clause Imports: 23 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Walk

func Walk(ctx context.Context, config *Config, results chan string, onRepoFound func(string)) error

Walk finds all git repositories in the directories specified in config. onRepoFound is invoked once per discovered repository (from walker goroutines); nil is safe.

Types

type BranchLocation added in v1.0.0

type BranchLocation struct {
	// Either "local" or the name of a configured remote.
	Name string

	// Exists is true when this location's ref (refs/heads/<branch> for "local",
	// refs/remotes/<remote>/<branch> otherwise) exists and resolves to a commit;
	// false when the ref is missing.
	Exists bool

	// TipHash is the full hex object name of this ref's tip commit when Exists;
	// empty when not Exists.
	TipHash string
	// TipUnix is the tip commit's committer date in Unix seconds (from git show);
	// zero when not Exists.
	TipUnix int64
	// UniqueCount is commits reachable from this ref but not from any other
	// Exists location for the same branch (local plus each remote in the scan).
	// Zero when not Exists.
	UniqueCount int
	// Incoming/Outgoing compare this ref to the local branch ref only (remote
	// rows). Incoming is commits reachable from this remote but not local (+N);
	// Outgoing is commits on local not reachable from this remote (UI: -M).
	Incoming int
	Outgoing int
	// HistoriesUnrelated means git found no merge base between local and this
	// remote tip; the UI shows "differs" instead of numeric deltas.
	HistoriesUnrelated bool
}

BranchLocation is one side of a local branch compared to same-named remotes: either the local ref (Name "local") or a configured remote's refs/remotes/<Name>/<branch>. Populated by branch status scanning; stored in LocalBranchRef.Locations. The UI and helpers use it for tip hashes, ahead/behind counts (Incoming/Outgoing vs local), and mismatch detection.

type Config

type Config struct {
	ScanDirs struct {
		Include []string `yaml:"include"`
		Exclude []string `yaml:"exclude"`
	} `yaml:"scandirs"`
	GitIgnore struct {
		FileGlob []string `yaml:"fileglob"`
		DirGlob  []string `yaml:"dirglob"`
	} `yaml:"gitignore"`
	FollowSymlinks bool `yaml:"followsymlinks"`
	Branches       struct {
		HideLocalOnly struct {
			Regex []string `yaml:"regex"`
		} `yaml:"hidelocalonly"`
		// Default lists branch short names always shown in the branch pane when
		// present as a local ref, even when tips match every remote.
		Default []string `yaml:"default"`
	} `yaml:"branches"`
	// Edit holds argv for opening a repository from the UI (key "e").
	Edit struct {
		// Command is the program and arguments passed to exec (no shell).
		// Use the literal substring "{repo}" in any element to substitute the
		// absolute repository path. If no element contains "{repo}", the path
		// is appended as the final argument. Empty means ["code", <repo>].
		Command []string `yaml:"command"`
	} `yaml:"edit"`
	// contains filtered or unexported fields
}

func ParseConfigFile

func ParseConfigFile(filename, defaultConfig string) (*Config, error)

func (*Config) EditArgv added in v1.0.0

func (c *Config) EditArgv(absRepo string) ([]string, error)

EditArgv returns the argv for opening absRepo in an external editor or IDE. See Config.Edit.Command for placeholder and default behavior.

func (*Config) ShouldHideLocalOnlyBranch added in v1.0.0

func (c *Config) ShouldHideLocalOnlyBranch(lb LocalBranchRef) bool

ShouldHideLocalOnlyBranch returns true when lb is local-only (see LocalBranchRef.IsLocalOnly) and its short branch name matches any pattern in branches.hidelocalonly.regex.

type Excluder

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

func NewExcluder

func NewExcluder(files, dirs []string) Excluder

func (Excluder) FilterPorcelainStatus added in v1.0.0

func (e Excluder) FilterPorcelainStatus(st PorcelainStatus) PorcelainStatus

func (Excluder) IsExcluded

func (e Excluder) IsExcluded(path string) bool

type LocalBranchRef added in v1.0.0

type LocalBranchRef struct {
	// Name is the short branch name (the refs/heads/* ref without the prefix).
	Name string
	// TipHash is the full object name of the local ref tip; TipUnix is the tip
	// commit's committer date in Unix seconds (from branch listing / git show).
	TipHash string
	TipUnix int64
	// Current is true when this row is the checked-out branch.
	Current bool
	// Locations compares this local branch to same-named refs on each configured
	// remote; see [BranchLocation]. Empty when detached or before branch scan fills it.
	Locations []BranchLocation
}

LocalBranchRef is one local branch tip (refs/heads/*). Locations holds local vs same-named remote refs (refs/remotes/<remote>/<name>); it is empty when detached or before GitBranchStatus fills it.

func GitBranchStatus added in v1.0.0

func GitBranchStatus(dir string) (branch string, detached bool, locals []LocalBranchRef, err error)

func (*LocalBranchRef) DisplayName added in v1.4.0

func (lb *LocalBranchRef) DisplayName() string

func (*LocalBranchRef) HasUnpushedChanges added in v1.4.0

func (lb *LocalBranchRef) HasUnpushedChanges() bool

HasUnpushedChanges reports whether the local branch has any commits not on any of the remotes,

func (LocalBranchRef) IsLocalOnly added in v1.0.0

func (lb LocalBranchRef) IsLocalOnly() bool

IsLocalOnly reports whether no configured remote has a same-named branch ref (refs/remotes/<remote>/<name> missing for every remote). Repositories with no remotes still populate only the local slot, which counts as local-only here. Empty Locations (e.g. some detached listings) yields false so branches are not classified without remote comparison data.

type MultiGitStatus

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

MultiGitStatus holds per-repository scan results. The zero value is usable: reads treat a nil receiver as empty; the first AddResult or Set allocates the inner map. Do not copy a non-zero MultiGitStatus (it contains a sync.RWMutex).

func NewMultiGitStatus added in v1.3.1

func NewMultiGitStatus() *MultiGitStatus

NewMultiGitStatus returns an empty result set ready for concurrent AddResult calls.

func Scan

func Scan(ctx context.Context, config *Config) (*MultiGitStatus, error)

Scan finds all "dirty" git repositories specified by config.

func ScanWithProgress added in v1.0.0

func ScanWithProgress(ctx context.Context, config *Config, onProgress func(ScanProgress)) (*MultiGitStatus, error)

ScanWithProgress runs the same scan as Scan and invokes onProgress from concurrent discovery and the status loop. Callbacks should be non-blocking (e.g. small channel send).

func (*MultiGitStatus) AddResult added in v1.3.1

func (m *MultiGitStatus) AddResult(path string, rs RepoStatus)

AddResult records a dirty or diverged repository; safe for concurrent use.

func (*MultiGitStatus) Delete added in v1.3.1

func (m *MultiGitStatus) Delete(path string)

Delete removes path from the set.

func (*MultiGitStatus) Get added in v1.3.1

func (m *MultiGitStatus) Get(path string) (RepoStatus, bool)

Get returns status for path, if present.

func (*MultiGitStatus) Len added in v1.3.1

func (m *MultiGitStatus) Len() int

Len returns the number of repositories recorded.

func (*MultiGitStatus) SortedRepoPaths added in v1.3.1

func (m *MultiGitStatus) SortedRepoPaths() []string

SortedRepoPaths returns repository paths in stable alphabetical order.

type PorcelainEntry added in v1.0.0

type PorcelainEntry struct {
	// Staging and Worktree are the two status columns (index vs working tree).
	Staging  git.StatusCode
	Worktree git.StatusCode
	// Path is the file path, or the new path for a rename.
	Path string
	// OriginalPath is the old path for a rename; empty when not a rename.
	OriginalPath string
}

PorcelainEntry is one parsed line of git status --porcelain (short format).

type PorcelainStatus added in v1.0.0

type PorcelainStatus struct {
	Entries []PorcelainEntry
}

PorcelainStatus is the full porcelain parse for one repo (entry order matches git output).

func GitStatus

func GitStatus(d string) (PorcelainStatus, error)

GitStatus invokes git to return porcelain status for a directory.

func ParsePorcelainStatus added in v1.0.0

func ParsePorcelainStatus(r io.Reader) (PorcelainStatus, error)

ParsePorcelainStatus parses NUL-delimited output from git status --porcelain -z. Rename/copy entries (staging code 'R' or 'C') consume an extra NUL-delimited token for the original path; all other entries are single-token records.

func (PorcelainStatus) ToGitStatus added in v1.0.0

func (p PorcelainStatus) ToGitStatus() git.Status

type RepoStatus

type RepoStatus struct {
	// Branch is the checked-out branch short name, or when Detached the short
	// HEAD object name (see git rev-parse --short HEAD).
	Branch string

	// Detached is true when HEAD is not on a branch (detached HEAD).
	Detached bool

	// Porcelain is the parsed git status --porcelain output.
	Porcelain PorcelainStatus

	// Full list of local branches with remote comparison data (Branches)
	Branches []LocalBranchRef

	// FilteredBranches is the subset of Branches that pass config filtering
	// (e.g. hide local-only branches matching config patterns). It drives the
	// UI branch pane display and report inclusion decisions. HasUnpushedChanges
	// iterates Branches directly with inline config filtering, so it does not
	// use FilteredBranches. It is always a subset of Branches with the same order.
	FilteredBranches []LocalBranchRef
}

RepoStatus aggregates one repository's working tree and branch metadata: parsed git status --porcelain (Porcelain), HEAD and local-branch layout with remote tips (Branches), and an embedded git.Status rebuilt from Porcelain for code that expects go-git's map form.

func StatusForRepo added in v1.0.0

func StatusForRepo(config *Config, dir string) (RepoStatus, bool, error)

StatusForRepo returns fresh status for a single repository directory using the same porcelain filtering and branch metadata as ScanWithProgress. The bool is whether this repo should appear in the dirty list (!clean or remote mismatch).

func (*RepoStatus) CurrentBranchLocations added in v1.4.0

func (rs *RepoStatus) CurrentBranchLocations() []BranchLocation

CurrentBranchLocations returns local vs same-named remote rows for the checked-out branch (the LocalBranchRef with Current: true). Returns nil when detached or when no current row exists.

func (*RepoStatus) Filter added in v1.4.0

func (rs *RepoStatus) Filter(c *Config) []LocalBranchRef

Filter filters out local-only branches that Config.ShouldHideLocalOnlyBranch matches. The checked-out branch is never removed so HEAD remote comparison stays available.

func (*RepoStatus) HasUnpushedChanges added in v1.4.0

func (rs *RepoStatus) HasUnpushedChanges(c *Config) bool

func (*RepoStatus) LocalRemoteMismatchReason added in v1.4.0

func (rs *RepoStatus) LocalRemoteMismatchReason() (reason string, ok bool)

LocalRemoteMismatchReason returns a human-readable explanation of why the current branch diverges from its remotes, and whether a mismatch was found.

type ScanProgress added in v1.0.0

type ScanProgress struct {
	// ReposFound is how many git repositories have been discovered so far.
	ReposFound int
	// ReposChecked is how many of those have finished StatusForRepo (porcelain,
	// branch metadata, and config filtering), not git status alone.
	ReposChecked int
	// CurrentPath is the path currently being processed (for status display).
	CurrentPath string
}

ScanProgress reports coarse scan activity for UIs (discovery vs per-repo work). ReposFound may increase while ReposChecked catches up; both match the final total when complete.

Jump to

Keyboard shortcuts

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