Skip to main content

Module worktree

Module worktree 

Source

Structs§

BranchStatus
Cheap snapshot of “where are we vs. clean / upstream”.
CommitRow
A commit row pulled from git log for the Recent Commits sidebar block. Mirrors lazygit’s columnar layout (hash + author + subject) so the renderer can lay out one commit per visual line. Hashes are parsed into binary OIDs once, then formatted on display to a fixed length (the COMMIT_HASH_DISPLAY_LEN constant in src/tui/ui.rs, currently 8 chars, matching lazygit’s Gui.CommitHashLength default). Not user-configurable today — change the constant to retune. parents.len() >= 2 flags a merge commit, which the renderer marks with instead of .
DiffLineStat
Insertion / deletion line counts of a branch versus its base trunk (issue #287). Populated from git diff --shortstat <base>...HEAD — the three-dot merge-base form, so the figures reflect only what the branch itself contributed (the GitHub-PR view), not divergence that landed on the trunk after the fork.
PrunableEntry
One prunable worktree entry as surfaced by gwm prune --dry-run (issue #31). The reason field is a human-readable rationale that is currently hard-coded to “working dir missing” — that is the only case is_prunable(None) flags today (working tree removed out from under the admin entry). Kept as a String rather than a literal in the CLI so future libgit2 versions can surface richer reasons (locked worktrees, broken HEAD, …) without breaking the CLI rendering contract.
StashEntry
One row of git stash list (issue #34). Surfaced by the sidebar in stashes mode. Kept deliberately minimal — ref_name so the user can copy stash@{N} to the status bar, subject so they can tell which stash is which. Per-file diff numbers (+/-) live in a follow-up — the v1 contract is just “name + subject”.
WorktreeInfo

Constants§

STATUS_SCAN_CAP
Hard cap on the number of NUL-terminated git status -z records read before the scan is abandoned (issue #300). --untracked-files=all makes git recurse into unignored generated/vendor directories; streaming the output and stopping here bounds both git’s directory walk (the child is killed once the cap is hit) and our own parse / allocation, so a pathological worktree can’t stall the TUI. Set well above any realistic change set; the file tree itself renders at most crate::tui::wt_tree::WT_TREE_MAX_FILES.

Functions§

add
Create a new worktree off of HEAD, attaching it either to a freshly created branch (the default) or — when reuse_branch is true — to a pre-existing local branch of the same name.
branch_age
Time elapsed since the oldest commit on branch that’s not also on a known trunk (main / master / dev). Returns None when no such commit exists — i.e. the branch is the trunk itself, has no divergence yet, or branch cannot be resolved. The “oldest commit” rule mirrors the lazygit branch-age semantics (pkg/utils/date.go::UnixToTimeAgo on the branch’s founding commit) and is more meaningful for a worktree-manager than git log -1: it answers “how long has this branch been alive?” rather than “when did someone last touch it?”.
discover_repo
Find the main repository starting from CWD, walking upwards.
find_fuzzy
Resolve a worktree by exact name first, then by substring (case-insensitive) within the dir name.
format_relative_duration
Render a Duration as a lazygit-style compact relative label (2d, 3w, 1M, 5y). Mirrors pkg/utils/date.go::formatSecondsAgo from lazygit: single-character suffix, no plural, capital M to disambiguate from minutes. Bounded at 4 chars for two-digit values in each unit, which is enough for any realistic branch age.
git_diff_stat_between
Shell out to git diff --stat <base>..<head> inside path. The output is truncated to max_lines lines so a sprawling diff stat doesn’t blow up the PR body (issue #84: 30-line cap by convention).
git_diff_stat_vs_base
Committed diff size of the worktree’s current branch versus its base trunk (issue #287), via git diff --shortstat <base>...HEAD. Returns Ok(None) when the path is not a readable repo, when HEAD is itself a trunk (no meaningful base to diff against — see is_trunk_branch), or when no base trunk resolves locally. trunks is the configured trunk-priority list (config.doctor.trunks) so the figure matches the base gwm pr would target — resolve_trunk walks it before falling back to the common defaults.
git_log_oneline
Shell out to git log --oneline -n <n> inside path and return raw stdout. Used by the TUI sidebar to preview recent commits of the selected worktree.
git_log_subject_between
Shell out to git log --pretty=- %s <base>..<head> inside path and return raw stdout. Used by gwm pr to fill the {commits} placeholder in PR templates (issue #84) — each commit becomes a Markdown bullet so a list of commit subjects drops straight into a PR body without extra formatting.
git_log_with_author
Return recent commits for the sidebar using libgit2. This is the uncached compatibility entry point; the TUI should call recent_commits_cached so repeated sidebar rebuilds for the same branch tip are a hash lookup.
git_stash_list
Parse the worktree’s stash list (issue #34). Returns up to limit entries in git stash list order (LIFO — stash@{0} is the most recent push).
git_status_short
Stream git status --porcelain -z --untracked-files=all inside path and return raw stdout, capped at STATUS_SCAN_CAP records. Used by the TUI sidebar to preview the working-tree state.
git_status_short_capped
Cap-injectable core of git_status_short. Spawns git with a piped stdout, reads NUL-terminated records until cap is reached (then kills the child so git stops walking the tree), and returns (bytes, truncated) — the raw stdout gathered so far plus whether the cap was hit (so the caller reports a lower bound rather than an exact total). Exposed so integration tests can exercise truncation with a small cap instead of creating thousands of files.
is_dirty
True when the worktree at repo carries staged, unstaged, or untracked changes (ignored files excluded). Shares its StatusOptions shape with [compute_status] so the status column and gwm sync’s dirty-tree refusal (issue #24) agree on what “dirty” means.
is_trunk_branch
True when branch is itself a trunk — present in the configured trunk list or in the [COMMON_TRUNKS] defaults. Used to suppress the Status pane’s diff row on trunk worktrees regardless of which trunk resolve_trunk would pick as the base (issue #287).
list
parse_diff_shortstat
Parse a git diff --shortstat summary line into a DiffLineStat (issue #287). The line looks like 3 files changed, 12 insertions(+), 4 deletions(-), but either the insertions or the deletions clause can be absent — an all-additions or all-deletions diff omits the empty side, and an empty diff yields an empty string. Any clause that’s missing counts as zero; the singular 1 insertion(+) / 1 deletion(-) forms are handled too.
prunable_worktrees
Compute (without mutating) the list of worktree admin entries that gwm prune would drop. Used by gwm prune --dry-run (issue #31) and consumed by prune so the dry-run preview and the destructive pass can never drift on what “prunable” means. Output is sorted by name for deterministic stdout — scripted callers diff across runs.
prune
Prune stale worktree admin entries (gwq cleanup equivalent). Consumes prunable_worktrees so what --dry-run shows is exactly what this destructive pass acts on — the two surfaces share the scanner, by construction.
recent_commits_cached
Return recent commits for one worktree, memoised by branch-tip OID and limit. WorktreeInfo.head is populated by list, so normal TUI sidebar refreshes can hit the cache without reopening the repo. Fixtures and older callers with head = None fall back to opening the worktree once.
remove
Remove a worktree directory and prune its admin files. Optionally delete the branch.
remove_dry_run
Read-only check that name resolves to a removable worktree — the libgit2 half of gwm remove --dry-run (issue #31). Errors on the same “worktree not found” path as remove so the dry-run surface and the destructive surface share an error contract; returns Ok(()) when the worktree exists. The caller (the CLI) is responsible for rendering the plan; this function intentionally touches no filesystem state and emits no output.
rename_worktree
Rename a worktree’s branch (local + remote) and move its directory on disk (c in the TUI, #290).
repo_name
Name of the repo derived from the working dir path.
resolve_trunk
Pick a base ref for gwm pr by walking the configured trunks list first, then the common defaults (main, master, dev, develop, trunk) so a repo whose local trunk is master and which hasn’t customised [doctor] doesn’t fall back to a non-existent "main". Returns None only if none of the candidates resolve to a local branch — the caller then uses "main" as a last resort so the downstream gh pr create --base main produces a clean error message instead of a panic.
run_git
Run git -C <dir> <args>, returning stdout verbatim on success or a GwmError::CommandFailed carrying the verb and git’s stderr on a non-zero exit (or the spawn error if git could not be launched).
run_git_logged
Like run_git but records the call on the process-global command log so it surfaces in the Command Logs modal (#290). Used for gwm sync’s mutating steps (fetch / rebase / merge / --abort), which are user-triggered operations the user expects to find in the transcript — unlike the read-only previews that go through run_git.