Skip to content

various tix improvements - #2938

Draft
Sebastian Thiel (Byron) wants to merge 62 commits into
mainfrom
tix-improvements
Draft

various tix improvements#2938
Sebastian Thiel (Byron) wants to merge 62 commits into
mainfrom
tix-improvements

Conversation

@Byron

Copy link
Copy Markdown
Member

Tasks

  • ensure all changes to non-tix are separately reviewed before merging

@Byron
Sebastian Thiel (Byron) force-pushed the tix-improvements branch 3 times, most recently from 32e3e43 to 129fafd Compare August 26, 2026 07:45
Codex (codex) and others added 27 commits August 27, 2026 14:06
History previously used the absence of view tips as a proxy for empty visible history. A newly created branch at, or behind, a hidden branch still has a view tip, so traversal and projection discarded every row and left no selection for creating the first stack commit or opening a rebase.

Keep current view tips as hidden boundaries when exclusion removes all visible commits, while retaining the hidden-tip fallback for unborn HEAD. Treat a boundary with zero visible descendants as an editable empty stack, and carry refs from the old base into an empty rebase-update so saving the unchanged todo advances the branch.
The history copy action always emitted the selected commit's object ID, even while the view showed its change ID.

Choose the clipboard effect from the effective ID display mode. Hidden and commit-ID modes retain object hashes, while change-ID mode writes the full reverse-hex change ID.
Review departure pins were indistinguishable from ordinary user pins. When a rewrite moved one onto a later checkout destination, normal time travel could consume it before the review finished and force detached fallback selection.

Give each review an explicitly owned pins/review/N return ref, keep generic travel and pin actions away from those refs, and consume the exact ref only when finishing or cancelling its review. Cover the squash-and-finish lifecycle and document the ownership contract.
Add a View Select command and v c shortcut that collect a displayed #N through the existing notice area. Resolve the number relative to the selected row's visual root so duplicate entry numbers in disconnected history trees cannot move the cursor across trees.

Keep invalid input editable, support pasted entry numbers, and document and test the interaction.
Ordinary pins at attached HEAD were filtered out together with the inactive HEAD return pin. When HEAD was displayed as an otherwise-empty hidden boundary, the missing decoration made the action menu call an existing pin "pin" instead of offering "unpin".

Keep ordinary pins applicable at attached HEAD while continuing to exclude the special HEAD pin. The existing tip deduplication prevents any traversal change, and a regression covers the hidden-boundary decoration that drives the unpin action.
Pending-rebase validation followed the parent of a checked-out review commit and mistook the review’s lazy base for a pending checkout path. Stop validation at the edited review boundary so staged changes can amend the active review while preserving ordinary pending-path protection.

Add regression coverage for a review commit whose parent carries tix-rebase-parent, and document the boundary behavior.
Checkout-path validation followed raw first-parent ancestry beyond the hidden base, so historical tix-rebase-parent markers could block edits in an otherwise final visible stack.

Limit pending validation to commits stored in the active history graph and give command-line HEAD edits the same inferred hidden base as the history view. Cover both reword and index-only amend against pending history below that boundary.
Pending checkout validation derived its boundary from commits cached or rendered in a HistoryGraph, while commands selected inconsistent graph loaders. This could reject edits because of hidden pending ancestry or skip checks for frozen rebase plans.

Track the active edit scope explicitly, share visible-boundary calculation with the UI, validate plans against their declared scope, and model pending HEAD finalization as an explicit policy.
Make J/K traverse every displayed parent and child edge. When a node has multiple destinations, keep the cursor at the source and let h/l choose the numbered destination before Enter confirms it or Escape cancels.

Use the same temporary choice interaction in the ref-tree, remove persistent child memory and lane emphasis, and discard choices whenever asynchronous lane computation replaces their indexed graph.
Prepare the review reference, return pin, and synthetic commit before attempting to activate the review checkout. Dirty worktrees can now proceed when Git accepts them, while a blocked checkout leaves the prepared review intact and reports its full commit ID.

Avoid forced rollback after checkout failures so local worktree changes cannot be discarded. Keep the finish-time cleanliness check and cover the partial-success path with a regression test.
Let active review commits use the same index-first, worktree-fallback amend behavior as ordinary HEAD commits. This makes a freshly started review amendable without requiring the reviewed delta to be staged first, including from a focused unstaged path.

Keep review identity, return ownership, pending-boundary handling, and index-only CLI behavior intact.
Make copy-insert available whenever move-insert is available, including when HEAD is an active review commit.

Strip review identity and return ownership from the copied occurrence so the retained source remains the sole owner of its review resources. Reuse the same identity removal when finishing reviews.
An active review can add a sibling stack at the same editable base as the reviewed branch. Updating that base rendered its mutable reference once per sibling section, so the parser rejected the unchanged generated todo as a duplicate placement.

Track external reference destinations while formatting and emit their reference line only for the first section. Cover the reported topology with a real active review and its symbolic return pin.
Make copy-insert and move-insert follow one source-first interaction: choose the commit, invoke the action, then choose its destination. Copy-insert now accepts any visible single-parent commit, while move-insert remains limited to HEAD.

Reuse the existing target-selection mask for navigation, cancellation, compressed history, and refresh invalidation. This removes the ambiguity that previously made a selected commit act as the target while an implicit HEAD acted as the source.
Replace the ordinary commit disc with the review diamond directly in full and compressed history graphs. HEAD and pending topological choices still override the diamond.

Remove the duplicate metadata marker while preserving pin and stash spacing, and style non-HEAD review diamonds like existing review decorations.
Shade a checked-out review from its first visible history gutter through its metadata with a purple background, leaving one normal cell before the title.

Apply the review band after ordinary selection styling so it remains stable while the selection continues to show everywhere outside it.
Use a uniform black foreground across the purple checked-out-review band so colored metadata remains legible. Keep the title margin and ordinary selection styling unchanged.
Let command-menu users search by the selected object instead of remembering each verb. Treat every available action and enrichment, plus commit message and changes information, as a commit search match while preserving existing group scopes.
Expose aP when the worktree HEAD pin names a local branch and resolve the push remote using Git configuration precedence. Run git push with the remote and branch as explicit arguments without blocking the TUI.

Show the active task in the footer, report completion with severity-aware notices, refresh references after success, and prevent normal exit while the task is running.
Add a general fetch action under the actions prefix using gix, including configured remote and refspec selection with phase-weighted progress in the message row.

Share the existing background network slot with push so only one operation can run at a time. Prefer the active branch fetch remote, then origin or the sole remote, including from detached review checkouts. Keep network actions behind the blocking client feature.
Resolve the nearest active review root for the current worktree HEAD and prefer that root and all of its descendants whenever topological ordering has a choice.

Keep the existing order for unrelated ambiguous review roots and share the nearest-root rule with time travel.
Require changes outside gix-tix to live in a separate Byron-authored commit and carry the tix TODO enrichment so their pending human review remains explicit.
Add transactional linked-worktree administration with rollback, then compose it in gix with existing reference, checkout, index, progress, and interruption machinery.

Support attached and detached worktrees from bare or non-bare repositories while rejecting occupied branches and destinations. Keep move, remove, repair, hooks, sparse checkout, and relative-link configuration out of scope.
Add a native worktree picker that streams dirty state, Tix-aware ahead/behind counts, and base diffstats while embedding the existing interactive history in at least half of the terminal.

Allow explicit local branches to reuse or create linked worktrees, and generate caller-directory wrappers for Bash, Zsh, Fish, Nushell, and PowerShell. Keep repository handles out of idle picker state, bound concurrent inspection, and leave forge integration and remote-branch creation out of scope.

# f0509d425e fix: dispatch repository-free gix tix commands before discovery

fix: dispatch repository-free gix tix commands before discovery

Run shell-integration generation before repository discovery and signal setup, and preserve the gix tix invocation identity for repository-backed commands. This lets worktrunk shell initialization run from any directory and makes its generated wrappers invoke gix tix.
Use the existing stacked-changes layout as the compact-history trigger. Keep gutters and graph through each commit node, then render only a Conventional Commit prefix-free title while preserving review and selection highlights.
Changing the highlighted worktree previously returned from the event loop immediately, so rebuilding the history hid the cursor move until repository loading finished. Queue the rebind until the urgent frame has painted the new selection, then restart the history against that worktree.
Replace the unstructured worktree rows with aligned worktree, status, base-diff, and commit-relation columns so streamed state remains scannable beside history. Keep the distinguishing end of long worktree names visible with display-width-aware left truncation, and distinguish current, main, and linked worktrees in the gutter.
Codex (codex) and others added 27 commits August 28, 2026 07:08
Add Git-style force levels to `tix wt remove`, hand the invoking shell back to the main worktree, and safely clean up merged associated branches with guarded reference deletion. Expose double-key removal in the picker through its existing background-task slot, with phased progress, non-interruptible worker lifetime, and post-removal reinventory.
Add `tix wt show` for scripts and quick inspection without entering the picker. It reuses the picker table renderer and parallel dirty-state workers while carrying one incremental history graph across all worktrees, then emits complete, unclipped plain output only after every row has loaded. A failed row aborts instead of presenting partial data as complete.
Keep using the persisted stacked changes layout while repeat navigation suppresses the change panes. This prevents history rows from briefly expanding until key release and protects the behavior with a rendering regression test.
Give the standalone `tix` binary a bounded `-t`/`--trace` counter with forest INFO, forest DEBUG, flat DEBUG, and flat TRACE modes. Keep the option outside the shared subcommand platform so `gix tix` can inherit tracing from `gix` without exposing a duplicate flag.

Buffer explicit traces independently until command and terminal-UI teardown, preserving tracing-forest output instead of mixing it into UI state. Include completed spans in flat modes so `-ttt` and `-tttt` expose the work performed rather than events alone.
Replace the old boolean trace switch with a bounded `-t`/`--trace` counter: forest INFO and DEBUG at one or two occurrences, then flat DEBUG and TRACE at three or four. Keep `--threads` long-only and route tracing independently of verbose and progress rendering, including commands with bespoke execution paths and corpus runs.

Initialize display tracing once before repository discovery, buffer it outside `prodash`, and emit it after command and progress teardown. Format forest and flat output with ANSI, then adapt the final stderr write so terminals get color while pipes and `NO_COLOR` remain plain.

Corpus worker subscribers share that sink while retaining their complete JSON trace storage, and flat modes include completed spans. `gix tix` remains delegated to Tix so it installs only one subscriber.
Full-screen progress required separate command and UI threads plus channel coordination, while line progress already covers long-running commands and works with independently buffered tracing.

Remove `--progress`, `--progress-keep-open`, and the `prodash-render-tui` feature. Keep synchronous line progress as the only progress UI.
A rewritten active branch previously left users with only a failed background push and no in-interface recovery path.

Run pushes in porcelain mode so local force-related rejections can be identified reliably. Keep the rejected request as a modal prompt, retry it once with force-with-lease on Enter, and let Escape cancel. Forced retries and unrelated failures remain final errors, with both porcelain and stderr diagnostics preserved.

Cover detached tix/HEAD pushes, successful guarded rewrites, stale leases, rejection classification, prompt reporting, and retry input, and document the behavior.
History detail previously followed the changes-pane layout and retained trailing graph padding, wasting horizontal space and making rapid navigation flip layouts.\n\nMeasure the drawable history width against visible title widths instead. Shorten conventional prefixes first, then reduce aligned rows to graph and title when needed, while preserving the horizontally scrollable unaligned view.
History alignment included rows covered by change panes and hidden boundary metadata, leaving large gaps in otherwise compact rows.

Limit alignment inputs to the unobscured viewport and render visible hidden boundaries with their natural unaligned spacing.
Adaptive compact rendering truncated every lane at its commit disc, hiding topology in merge-heavy histories.

Keep the complete trimmed graph and place the shortened title directly after it.
Reuse the existing arrow-key navigation behavior for Ctrl-P and Ctrl-N while the worktrunk search is active.
Render the contextual status and search row after the worktree table so it separates the picker from the embedded history.
The worktrunk table only needs ancestry for relation and diffstat calculations. Resolve and deduplicate every worktree head first, populate one shared graph without decorations, linked-worktree snapshots, or commit-row payloads, then reuse it for each row.

Keep a broken-tag regression fixture so unused decoration loading cannot creep back in.
A single wide visible prefix, such as paired local and tracking refs, could push the shared title column far enough right to minimize every history row even when natural per-row spacing had ample room.

Fall back to natural spacing before shortening titles or hiding metadata, and keep hidden boundary rows out of both aligned and natural width decisions.
Permit --quit-on-finish on the target-less worktrunk picker forms and carry it into the shared history event loop. Wait for every worktree status and graph-metadata update before retaining the final diagnostic frame, making the mode useful for deterministic inspection and performance measurement.
Load graph-derived data for every worktree in one background pass using the same shared graph path as `wt show`, instead of coupling that work to serial preview warming. Keep selected previews responsive, skip invisible warming in diagnostic mode, and poll active row workers at frame cadence so completion is not delayed by a coarse timer.
Route --quit-on-finish input through the focused worktree picker while preserving its read-only guarantee, and wait for each requested preview before replaying the next key. Keep graph-only metadata traversal from marking commits as delivered so later previews emit their history rows and keep the selected commit aligned with its change panes.
Expose the linked-worktree mutation APIs through the gix CLI so they can be exercised outside tests.

Resolve existing branches for attached worktrees and commit-ish values for detached ones. Match Git-style repeated --force behavior when removing dirty or locked worktrees, with journey coverage for both modes.
Forward curl and reqwest transport selection to gix while enabling Tix blocking network support. This makes fetch available in standalone tix builds with either HTTP backend.
The plain history renderer suppressed the textual HEAD decoration without replacing the graph node as the TUI does, which left detached HEAD invisible. Render HEAD as @ for ordinary rows and base separators while preserving existing branch labels.
Ref-tree pinning can create symbolic ordinary pins for remote, tag, or review references. Destination selection treated every symbolic pin as a local branch and failed time travel. Restrict checkout selection to direct pins and refs/heads targets so other pins remain retention-only.
Path-scoped spills invalidated an existing signature whenever unselected changes remained, making the directly edited HEAD appear pending even though neither its parent nor its remaining tree required replay.

Re-sign every non-review HEAD edit immediately while retaining lazy replay for rewritten descendants. Cover a signed two-file spill and prove that a follow-up edit succeeds.
Treat displayed hidden commits as immutable insertion anchors for copy, paste, move, and stack operations. Plans add the inserted commits as new children without replaying the target history or moving refs attached to that history.

When copying onto the checked-out hidden boundary, advance only the branch attached to HEAD and keep HEAD attached. Reject moves whose immutable target descends from the moved stack, since preserving that target would create a cycle.
Let history modes preempt worktree-picker input by limiting picker ownership to the history root. This keeps Escape routed to conflict cancellation instead of application quit handling.

Add a regression test covering the conflicted-rebase routing.
The history view copies full reverse-hex change IDs, but paste previously accepted only object hashes. Resolve pasted change IDs against the current Tix view so unique changes can be copy-inserted directly.

When a change ID has multiple siblings, show commit hashes, select the closest match, and direct the user to cycle siblings with x before copying the desired hash.
The metadata fill used Ratatui’s cached frame dimensions, then autoresized immediately before painting. Growing the terminal could therefore expose deferred commit skeletons as empty rows dated at the Unix epoch.

Refresh the terminal dimensions before selecting visible rows and paint that same frame size. Apply the ordering to time-travel animation too, document the invariant, and cover stale-frame growth with a regression test.
Opened shortcut groups could shadow top-level entry points: Actions interpreted `n` as `new-empty` and `p` as `split`, while the ref-tree used `p` for pinning. This made keyboard behavior depend on the currently open view.

Reserve `p`, `v`, `a`, `n`, and `?` ahead of scoped shortcuts. Move `new-empty` and `split` to `a Shift-N` and `a Shift-S`, retain ref-tree pinning on `<enter>`, and route command-palette opening ahead of ref-tree input.
Older commits can carry an author identity that differs from the one currently configured in Git, and re-entering the configured identity in the reword editor is unnecessary friction.

Show a commented `ConfiguredAuthor` beside a differing `Author`. Uncommenting it makes that identity authoritative while preserving `AuthorDate`; matching or unavailable configured identities remain omitted, and other commit editors stay unchanged.
Push alone placed its running label in the shared navigation footer, while fetch and worktree removal used the dedicated background row. This made identical background-task ownership look inconsistent and crowded the footer.

Use background progress as the single task state and render every running task in the existing row above the footer. Push remains a static status there, while fetch and removal continue updating progress; remove the footer-only rendering and anchor adjustment.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants