various tix improvements - #2938
Draft
Sebastian Thiel (Byron) wants to merge 141 commits into
Draft
Sebastian Thiel (Byron) wants to merge 141 commits into
Sebastian Thiel (Byron) wants to merge 141 commits into
Conversation
Sebastian Thiel (Byron)
force-pushed
the
tix-improvements
branch
7 times, most recently
from
August 28, 2026 09:37
9435460 to
6b0ae90
Compare
Sebastian Thiel (Byron)
force-pushed
the
tix-improvements
branch
12 times, most recently
from
September 8, 2026 05:48
9fa9982 to
8b529d1
Compare
Sebastian Thiel (Byron)
force-pushed
the
tix-improvements
branch
2 times, most recently
from
September 12, 2026 15:22
fdce03f to
4e0ce09
Compare
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.
The prefix popups expose shortcuts but require knowing what a verb does before running it. Make `a`, `v`, `n`, and `?` useful for exploration: a 300 ms hold selects the first displayed command and shows contextual help. Navigate the wrapped popup with `hjkl` or arrows, release the prefix or press Enter to run the selection once, and press Escape to cancel. Taps and fast shortcuts retain their existing behavior; terminals without key-release reporting keep toggles. Reuse the command catalog, actual popup geometry, and normal action validation. Cancel browsing when focus, input ownership, or the visible command changes. Handle shifted question-mark releases and native Windows repeated key-downs, read queued taps before promoting a hold, and clear held keys before handing input to editors or diff viewers. Keep contextual help separate from notices. Validation: 744 isolated library tests passed, with the eight gesture tests rerun after test-only Clippy cleanup. Formatting and SHA-1 all-target Clippy passed. A disposable `gix-testtools` repository passed enhanced and legacy PTY smoke checks. The network-enabled all-target build check passed; Clippy with that feature encounters the existing `drop_non_drop` lint in `gix-protocol/src/fetch/function.rs:144`.
When there are no local changes, advertising both `2 stash & travel` and `@ with worktree` suggests a distinction that does not affect the checkout. Show only `@ travel` for a current clean worktree status, or `@ return` at a pinned destination. Preserve both hints for dirty or unknown status, including untracked-only changes and unwatched or failed status snapshots. Key bindings remain unchanged. Build the travel shortcut spans once and reuse their width for prefix-popup positioning so the Information popup remains attached after the footer shrinks. Extend the existing rendering regression for clean, dirty, and unknown status, return destinations, shortcut underlining, and popup alignment. Validation: all 70 UI tests passed from an isolated source copy; formatting and SHA-1 all-target Clippy passed.
Push displayed a separate line above the footer before putting a force-push prompt in the ordinary message area. Use that same message area for push, fetch, and worktree-removal progress so their status has a consistent place and does not reserve an extra row beside foreground feedback. Keep background task state independent from notices. Held-command help takes priority, followed by prompts and ordinary notices; the latest progress resumes when they clear. Preserve the completion fill, wrap long progress text, and move it above prefix popups like other messages. Validation: all 71 UI tests passed from an isolated source copy, including priority, resumption, completion fill, and popup layout. Formatting and SHA-1 all-target Clippy passed.
An external remover can delete a linked worktree's `HEAD`, `commondir`, or `gitdir` before its checkout and administration directories disappear. The lifecycle check only noticed missing directories, so reference refreshes and view loads could exit while reopening that incomplete repository. Treat missing administration files as worktree loss and enter the normalized common repository. Explicitly clear its in-memory worktree path: overriding `core.bare` alone could retain the main checkout. Recovery leaves that checkout's `HEAD` and index untouched. Retry interrupted renders and snapshots through the existing lifecycle boundary. Keep refresh graphs and distinguish worker requests made before recovery so late failures reload the surviving history. A disappearing picker preview becomes unavailable instead of closing the UI. Requests against the recovered repository still propagate errors normally. Validation: the new partial-removal regression fails on the previous code. All 747 library tests, SHA-1 all-target Clippy, and formatting checks passed from an isolated source copy. Regression fixtures use `gix-testtools` and isolated child processes for working-directory changes. Live PTY checks also stayed interactive through ordinary external removal, HEAD-first and commondir-first partial removal, and deletion during picker preview. Recovery cleared the Worktree pane and explicit exit still worked.
Finishing a review should record the approval that the operation represents. Automatically add the sparkle enrichment to the resulting review commit's current patch, including an empty patch. Target that commit even when the recorded return checkout selects one of its descendants. Prepare approval alongside review completion so history, review resources, and enrichment publish in the same ref/worktree transaction. Cancelling a suspended finish publishes no approval; accepting a conflicting return checkout still approves the completed review. Finalize its replay markers and patch identity before preparing the enrichment. Validation: all 268 edit tests passed from an isolated source copy, including empty and changed reviews, descendant return targets, a pending review root, and conflict cancellation and acceptance. SHA-1 all-target Clippy and formatting checks passed. All regression repositories use `gix-testtools`.
Local edits sometimes belong before the current commit. Creating a child and moving it afterward requires extra history operations and can encounter a conflict only after the new commit has already been published. Add `a Shift-W` (`neW-below`) using the usual staged-first, tracked-worktree fallback. Prepare the local patch against HEAD's parent and replay HEAD above it entirely in memory, requiring the combined tree to match the selected candidate. Conflicts and editor cancellation leave the checkout unchanged. Keep HEAD's identity and notes on the rewritten upper commit and select the new lower commit, leaving siblings untouched and descendants lazily rebased. Consume the selected changes through the active index without checking out worktree files. Other affected worktrees retain their normal checkout safety and staged changes. Support ordinary commits and roots, reject unfinished HEAD or immediate parents, and preserve older pending ancestry. The Linux `test-fast` jobs passed their tests but failed the generated-archive cleanliness check because `create_below.tar` had not been committed. Include the archive produced by the existing fixture helper. Regenerated it from a fresh cache and validated all seven `new_below` tests. The full CI job also requires fixture scripts with a shebang to be executable. Track `create_below.sh` as mode `100755`; the repository mode check passes with this correction staged.
Every palette keystroke marked the full view dirty, formatting and measuring all changed paths even when only the query and matching commands changed. Large dirty worktrees therefore made ordinary typing noticeably slow. Retain one terminal-sized background buffer while a command or AutoMerge input menu is open and reuse it for menu-only redraws. Process these redraws after normal repository lifecycle and watcher handling. Pending background changes, resizes, and menu dismissal still redraw the full view, and menu input leaves the background frame deadline intact so it cannot postpone streaming updates. Regression coverage compares cached and complete frames across filtering, expansion, cursor placement, resizing, and updated worktree contents. In a debug build, eight palette edits over 20,000 changed paths dropped from about 350 ms to 10 ms. Update `spec.md` with the redraw and detached-buffer lifetime rules. Validation: `cargo test -p gix-tix --features sha1`, crate formatting, and Clippy for all crate targets with `sha1` and warnings denied. Tests use `GIX_TEST_IGNORE_ARCHIVES=1`; macOS filesystem notifications require running outside the sandbox.
Large untracked build trees expanded into individual worktree rows and file diffs. Use `UntrackedFiles::Collapsed` for the display so directories such as `target/` occupy one added row without reading every file for line counts. Refresh untracked child events from their top-level scope so cached directory rows match a full status, including newly created and removed directories. Keep precise scopes for tracked files and explicit file enumeration for commit creation, whole-commit amend, and split so directory contents are retained. Represent directory diffs as unavailable. Discard validates the collapsed row and uses Git's existing literal-path cleanup, preserving ignored contents. Single-path amend requires staging the directory's files first; hide that action for directory rows and reject it before changing repository state. Update `spec.md` and cover Git-compatible collapsing, incremental refresh, directory actions, and retained commit contents. All 759 library tests pass, along with binary and documentation test targets, crate formatting, and Clippy for all targets with `sha1`. Tests use `GIX_TEST_IGNORE_ARCHIVES=1`; the native macOS reference-watcher test runs outside the sandbox.
Finishing a review replaced its parent with the reviewed tip and transplanted only the review and its descendants. Independent commits inserted below the review disappeared from the resulting history, even though the review's exact tree retained their changes. Find the ordinary ancestor chain exclusive to the review and replay each patch onto the reviewed tip before attaching the finished review. Preserve change IDs, authors, messages, Git notes, and references, and reparent affected side history. The review keeps its exact tree and remains the only newly approved patch. Reject hidden, pending, nonlinear, or conflicting additions without publishing changes. A shared merge base remains valid. Cover single and multiple inserted parents, review and original successors, notes, distinct patches, and atomic failure, and document the completion behavior. Validation: all 762 `gix-tix` tests with `sha1`, workspace formatting checks, and crate Clippy with warnings denied passed. The filesystem-watcher test needs normal macOS notification access; its sandboxed run times out.
Finishing explicitly cleared undo history, and accepted review-return conflicts suppressed recording through resolution. Even recording a successful finish was insufficient for redo: undo restored an active review, whose blanket guard hid the queue again. Record the complete finish transaction using the normal undo machinery, including its checkout, review resources, return pin, and patch approval. Recognize review-ending entries by the review-reference deletion they already contain, so they remain reversible across active reviews without a new queue format. Remove the UI veto and the special conflict-recording suppression. Keep ordinary edits during active reviews unrecorded and discard stale redo after those edits. Empty transactions, including cancelled unpublished previews, leave the queue alone. Cover attached and detached returns, repository reopens, another active review, edit-and-retry, and grouped return-conflict resolution. Update the review specification with the undo and redo contract. Validation: all 764 `gix-tix` tests with `sha1`, workspace formatting checks, and crate Clippy with warnings denied passed. Tests used normal macOS filesystem-notification access for the watcher test.
Undo and redo were available only in the terminal UI even though CLI edits already recorded the same worktree-local operation queue. Expose one-step undo and redo alongside a plain operation log, with bare `tix op` showing the log and marking the current position among applied and undone entries. Move `tix admin clear-undo` to `tix op clear` so all queue operations share one command family. Keep history data on stdout and recovery feedback on stderr. Reuse checked reference and worktree updates, and reject unresolved index conflicts before applying an undo or redo. Validation: all 768 `gix-tix` tests pass, including the operation-command round trips, output separation, conflict safety, and existing review and linked-worktree coverage. Formatting and Clippy checks pass. Both `tix` and `gix tix` build and expose the new command family in their CLI help.
Branch and Git-hash travel loaded history without the normal hidden boundary. Old pending markers in merged ancestry could replay hundreds of commits, changing identities and metadata even when their file contents stayed intact. The shared replay engine also reparented siblings and later descendants that were unrelated to the requested checkout. Limit travel to editable commits in `HEAD..destination`, plus the destination itself. This permits refreshing a pending `HEAD` or backward destination while preserving older shared ancestry, siblings, and commits beyond the destination. The limit applies even without hidden history and when an explicit view omits HEAD. Branch and hash resolution now infer the usual hidden boundary, and hidden or shallow destinations remain exact checkouts. Keep AutoMerge dependency replay inside the original route, preserving the bounded change-ID lookup window and treating outside inputs as snapshots. Collapsing a merge cannot widen later replay passes. Pending boundary parents remain unchanged, including when accepting and resolving a travel conflict. Cover CLI resolution, endpoint replay, omitted HEAD, shallow boundaries, both ordinary merge sides, off-path identities, AutoMerge collapse, local changes, and conflict recovery in disposable repository regressions.
Accepted rebase and transplant conflicts previously kept their continuation in an exported todo or in TUI memory. Restarting Tix or changing interfaces lost the operation context, and the TUI could not identify a CLI-created pause. Save accepted pauses in worktree-local Git metadata using the existing todo and undo formats, retaining their required objects through Git GC. Add `tix rebase status [--porcelain]`, `continue`, and `stop`. Continuation consumes the staged index without launching an editor or staging files. Initial and later conflicts require explicit acceptance; refusal preserves the prior state. Plain `rebase todo` exports the saved plan, and matching edited-file application remains supported. Bare `--materialize-conflicts` now saves internally; exporting requires `=FILE` or `=-` for stdout. Optional filenames never consume a positional todo. Restore the TUI's persistent `REBASE PAUSED` notice on startup and refresh, including operation, remaining work, readiness, and blocked-state guidance. Enter continues, subsequent conflicts require acceptance, Escape stops at a saved pause, and quitting preserves it. Inspection and resolution amendments remain available while unrelated mutations are blocked. Check captured HEAD identity and reference expectations before continuing. Publish session transitions with checked history updates, serialize checkout and stop, and restore staged resolutions on failed publication. Completion or stop records one grouped undo entry without resurrecting session metadata on undo. Stop preserves partial commits, index, and worktree contents. Ordinary lazy replay, travel conflicts, and native Git rebases stay outside this continuation workflow. Validation: 785 Tix tests pass, including CLI/TUI handoff, repeated conflicts, stale state, worktree isolation, GC, rollback, and grouped undo. Tix Clippy passes with SHA-1, SHA-256, and blocking-network-client enabled; both `tix` and `gix tix` build with the small configuration and Tix enabled.
Interactive history already inferred local default branches from remote HEADs, but required `Shift+H` to hide their history after launch. Add `-X` / `--auto-hide` to `tix` and `gix tix` so the initial traversal applies those exclusions. Combine inferred exclusions with explicit `-x` revisions and retain the existing history toggle and revision diagnostics. Plain `tix` still opens with full history, and `-x` alone keeps its explicit-only scope. Reject the new history-view option alongside subcommands so it cannot be ignored. The public `gix_tix::Options` struct gains the default-false `auto_hide` field. Exhaustive initializers must supply it or use `..Options::default()`. Validation: - All 786 `gix-tix` tests pass with `sha1` and `GIX_TEST_IGNORE_ARCHIVES=1`. macOS filesystem-watcher coverage passes outside the sandbox. - `cargo clippy --locked -p gix-tix --features sha1 --all-targets -- -D warnings` passes; the workspace reports its existing removed-lint warning. - Seven isolated terminal checks cover plain startup, both flag spellings, the `Shift+H` round trip, `gix tix -X`, and missing inferred defaults.
The interactive ref-tree previously expanded the loaded history only with worktree tips. A remote-tracking branch outside that history could therefore be absent even though its reference existed and `tix ref-tree` displayed it. Expand the overview's cached graph with commit tips under `refs/remotes/` when entering it and whenever references refresh while it remains open. Reuse the graph's extra expansion inputs so ordinary history, hidden boundaries, and editing scope remain unchanged. Ignore stale symbolic references and non-commit targets using the existing reference iteration and peeling behavior. Cover remote branches from multiple remotes, moved tips, optional invalid references, rendered labels, and preserved history scope in a regression test. Keep the behavior documented in `spec.md`. Validation: all 787 Tix tests passed, as did Clippy with `-D warnings` and terminal checks for packed refs, live additions/moves/deletions, ordinary history, and `tix -X`.
`gix-command` prepares background helpers with `CREATE_NO_WINDOW`. Even with inherited standard streams, that flag gives Windows editors a separate hidden console. Vim and Nano can exit unsuccessfully, while Helix can wait invisibly for input that never reaches it. Clear the creation flags when launching Tix's configured editor so both direct commands and shell commands share Tix's console. The common launch path covers editing from the TUI and command-line operations without changing editor selection or the handling of the edited document. Add an isolated Windows regression that runs in a hidden test console and checks that the editor shares its caller's console before editing the file. Checking console process membership matters: opening `CONIN$` alone also works in the separate hidden console. Document the console-inheritance guarantee in `spec.md`. Verified interactive launches with Vim, Nano, and Helix, including returning from Vim and Helix to the TUI. The regression fails before the fix and passes afterward. The combined editor and command checks pass 75 tests; the remaining bare-clone test fails identically with the original implementation on Windows.
Restricting travel to its destination route also removed later descendants from the rewrite graph. Visiting a pending middle commit finalized it while the branch above it still reached its old pending version, leaving two versions of the same change visible in the TUI. Keep the loaded edit graph for descendant rewrites and pass the original travel route separately to the replay engine. Only the destination route and its eligible AutoMerge inputs replay content. Affected descendants follow rewritten parents lazily, retaining their trees and original replay bases; their references and notes move in the same existing transaction. Pending commits whose parents did not change remain untouched. Remap the replay route independently across subsequent passes so AutoMerge collapse cannot widen it. Shared ancestry and unpinned history outside the loaded view retain their previous boundaries. Add a regression for a pending middle commit, its retained descendant, and onward travel. Update the sibling, merge, and backward-travel assertions to require connected parent links while preserving content replay boundaries. Validation: all 788 Tix tests passed, as did Clippy with `-D warnings` and isolated CLI, undo, and TUI keyboard smoke checks. The debug `tix` binary was rebuilt with the fix.
The new-commit editor always started with a `what` title and a `why` body, so users could not choose a reusable initial message for their workflow. Read literal multiline text from `tix.new.message` through Git's existing configuration resolution. Keep the original text when unset and allow an empty value to start with a blank message area. Shared preparation applies the setting to ordinary, empty, root, below-HEAD, CLI, and split creation. Use the configured message when detecting existing attribution trailers, and keep appended editor comments on separate lines. Show the source of `tix.new.message` alongside the existing `tix.trailer.*` editor hints so users can discover the key and the winning configuration. Share their formatter for configuration files, non-file overrides, and the built-in default. Show the hint for blank messages and messages that already include both attribution trailers. Explicit messages still override the initial text, and leaving the editor unchanged still creates nothing. Document the setting and global/local configuration examples beside the existing Tix configuration documentation. Extend isolated tests for defaults, multiline text, missing final newlines, blank messages, configuration sources, trailer suggestions, explicit inputs, and cancellation. Validation: 50 focused tests for creation, rewording, splitting, and CLI messages passed. Crate formatting and Clippy with `-D warnings` also passed; Clippy emitted the workspace's existing removed-lint warning. The Windows fixture job failed the initial-message source assertion because its expected path joined `.git/config` with mixed separators. Build that path one component at a time, matching the configuration reader. The targeted test and workspace formatting pass locally.
The `? e` information shortcut cycles through Tree + Worktree, Tree only, and hidden, so hiding both panes requires several keys. Add `Shift-C` as a direct visibility toggle while preserving the existing cycle. One press hides either visible mode and returns focus to history. The next shows both panes, or Tree alone in a bare repository. Reuse the existing pane reset, diff-worker cleanup, and worktree-watcher refresh paths. Keep the toggle available during tree selection and rebase inspection, accept both terminal encodings of shifted letters, and advertise it in the information popup and keyboard documentation. The new regression failed before the binding existed. All 791 Tix tests pass with `sha1`, including focus, bare-repository, keyboard, and rendered help coverage. Run the full suite outside the sandbox for native filesystem notifications. Crate formatting and Clippy with `-D warnings` pass; Clippy retains the workspace's existing removed-lint warning.
Scoped status walks can enter an ignored directory when a pathspec matches. If a deeper directory matches a negated rule such as `!out/`, the ignore stack previously stopped at that nearer match and exposed its contents as untracked. Tix uses scoped walks for filesystem refreshes, so ignored Cargo output appeared after unrelated worktree events and disappeared after a full refresh. Continue through negated directory matches to check excluded ancestors. Keep the nearest negation as the fallback when no ancestor excludes the path, and preserve the precedence of positive directory matches, including precious-file handling. Extend the Git-reference fixture below a negated child directory and refresh both hash archives. The extended fixture fails with the previous matcher. All directory-walk, status, and worktree tests pass, as do the SHA-256 ignore baseline, formatting, and Clippy with `-D warnings`. Clippy retains the workspace's existing removed-lint warning. Assisted-by: Codex <codex@openai.com>
A filesystem event for an untracked child refreshes its top-level scope. The shared ignore matcher could let a broad `!out/` exception expose Cargo output beneath an ignored target directory during this scoped walk, while startup and explicit full refreshes still looked correct. Exercise event-to-scope conversion and incremental cache replacement in an isolated repository with the reported nested project layout. Cover an untracked child, its containing directory, an ignored directory, and a tracked file; require the resulting status to match a full refresh. Document that negated descendant patterns cannot bypass ignored parents. The preceding `gix-worktree` change supplies the shared matcher fix. Validation: the regression failed before the matcher fix. All 792 Tix tests pass, including native filesystem watcher tests outside the macOS sandbox. Crate formatting and Clippy with `-D warnings` pass; Clippy retains the workspace's existing removed-lint warning.
… Tix Long-running clients need more than raw `notify` events: bounded intake, explicit coverage loss, replaceable subscriptions, recovery deadlines, and repository-aware invalidation. Move these responsibilities out of Tix into Git-independent `gix-notify` and `gix::notify::RepositoryMonitor`, adopting both in Tix in the same change. Keep metadata and ignore-aware worktree subscriptions independent. Observe configuration roots and active includes even while missing, as well as ignore and attribute dependencies. Canonicalize native registrations, preserve raw Git path bytes, reconcile subscription differences, bound diagnostic samples, and rediscover coverage after failure or the configurable 60-second safety interval. Monitors retain no repository while idle. The compatibility backend uses upstream `notify` on every platform and explicitly reports that delivery synchronization is unsupported. A separate change will own macOS notification delivery. Preserve Tix's nested-ignore status regression and move watcher tests alongside their implementation. Validation: 788 Tix tests, 19 repository-monitor tests, 13 generic-monitor tests, 206 configuration tests, 48 repository-configuration tests, and six new dependency-source tests passed. Native tests ran outside the sandbox: macOS refuses FSEvents stream startup inside it, which upstream `notify` does not report. Targeted clippy and formatting pass; documentation builds with one pre-existing unrelated intra-doc-link warning. Co-authored-by: Codex <codex@openai.com>
Use an owned FSEvents backend on macOS while retaining the `notify` adapter on other platforms. Own the control thread, serial callback queue, native stream, and shutdown order; report refused startup, preserve filesystem path bytes, and turn dropped or unknown events into explicit coverage loss. A delivery boundary must cover completed filesystem writes, not only native events already queued by the service. Immediate-write tests demonstrated that `FSEventStreamFlushSync` alone does not provide that boundary even on a warmed stream. Add `synchronize_at()` with a caller-supplied administrative marker directory, completing only after the entire marker-containing callback has been published. No-anchor synchronization stays explicitly unsupported. Check root identities and local mount coverage before certifying a fence. Timeouts cannot cancel native operations, late markers cannot satisfy a new request, and destruction joins the control worker after callbacks are drained. The generic API remains independent of Git; Tix automatically uses this backend without creating synchronization markers. Validation: 20 notification tests and all 788 Tix tests passed outside the macOS sandbox, including repeated immediate writes across two native roots, loss/overflow, byte paths, marker timeout isolation, and root replacement. All-target clippy and Linux compatibility cross-check passed. Co-authored-by: Codex <codex@openai.com>
Sebastian Thiel (Byron)
force-pushed
the
tix-improvements
branch
from
September 21, 2026 17:49
5f04233 to
973b63b
Compare
Long-running applications need an owned status snapshot without retaining a repository or detached producer threads while idle. Add optional `status-monitor` support with synchronous `Platform::into_vec()` collection, incremental staged and worktree replacement, cancellation, retry deadlines, and live recursive monitoring of initialized, configured submodules. Install subscriptions before collecting the baseline, preserve pending events and the previous snapshot across failures, and conservatively widen scopes for collapsed untracked directories, rewrites, and aliased submodules. Return the coverage refreshed even when status items compare equal so content-derived caches cannot mistake another edit for unchanged content. Adopt the shared monitor in Tix in this same change. Keep line counts for unaffected rows, refresh covered rows, and retain the last display on errors. Separate native-service deadlines from snapshot deadlines so hidden panes, the ref-tree overview, initial loading, and presentation retries cannot spin the event loop. Clear watch diagnostics only after verified recovery. Malformed-index recovery exposed a checksum subtraction panic for truncated files. Validate the existing header before locating its checksum so status can report the error and retry instead of panicking. Resolve existing watch ancestors to their native case and Unicode spelling while preserving missing dependency suffixes, and use physical identities for nested submodules. Validation: 790 Tix tests; 20 repository-monitor and 16 status-monitor tests; five synchronous-collection tests in serial and parallel configurations; existing submodule tests; all 91 index integration tests. Targeted strict Clippy, minimal-feature checks, formatting, and documentation pass (one pre-existing clone rustdoc warning). Native watcher tests ran outside the macOS sandbox. Windows CI exposed two nonportable fixtures. A filename containing `*` is invalid there; retain bracket metacharacters for literal-scope coverage instead. For submodule initialization and deinitialization, absorb its Git directory and toggle the checkout's `.git` backlink. This keeps monitoring live without renaming a directory containing open native metadata watches, which Windows can deny. The inventory still exercises inactive, active, and inactive states. All 16 native macOS monitor tests, the Windows ARM64 test cross-check, and workspace formatting pass. The full CI test job's final `it check-mode` step requires every fixture script with a shebang to be executable. Track `make_status_monitor_submodules.sh` as mode `100755`; the repository mode check passes with the correction staged. Windows archive-backed CI exposed unnecessary writable copies in two status collection tests. These tests never persist index or worktree changes, so reuse the read-only status fixture, avoiding copies of unrelated Unix-specific entries. All five collection tests pass with that change. Two native Windows monitor tests intermittently failed to finish. Record their setup, refresh, Git, and teardown phases on captured stderr, and bound only the monitor test group to two minutes in nextest so a recurrence yields diagnostics instead of blocking the entire job. All 16 native macOS monitor tests pass, and nextest accepts the scoped timeout configuration. Co-authored-by: Codex <codex@openai.com>
Provide a standalone daemon for Git's hook v2 and native Simple IPC protocols. Applications can configure the hook for automatic startup or explicitly start the daemon before using `core.fsmonitor=true`. Support foreground operation, start, stop, status, flush, and raw queries without retaining a repository between operations. Keep complete worktree coverage independent of ignore rules and the client's index. A bounded, non-destructive journal serves multiple token baselines, using random instance epochs and full invalidation for expired, malformed, foreign, future, or interrupted histories. macOS replies synchronize native delivery through an administrative marker; compatibility backends on Linux and Windows conservatively request a full scan until they can fence events. No synchronization files are created among worktree user files. Match Git's Unix endpoint and temporary startup-lock protocol, support long socket paths, and implement its Windows named-pipe transport. Bound client exchanges and recovery, preserve replacement endpoints during cleanup, and close obsolete daemons after root loss. Resolve existing roots to their native spelling so Unicode and case aliases cannot silently hide delivered changes. Validation: 14 daemon unit tests and 10 native integration tests pass, covering hook/native interoperability with Git in both directions, daemon replacement, linked worktrees, ignored forced-tracked files, alternate indexes, immediate writes, Unicode aliases, root removal, and isolated long socket paths. All 21 `gix-notify` tests pass. Workspace strict Clippy, formatting, documentation, and Linux/Windows cross-compilation including tests pass. Windows runtime and cross-elevation access remain outside the validated scope; the README states the current limits. Windows CI failed all six daemon interoperability tests because an idle connected named pipe was reported as EOF. Rust's `File::read` converts `ERROR_NO_DATA` to zero bytes. Read with Win32 `ReadFile` to preserve that condition for the existing bounded retry, while retaining real broken-pipe EOF. A deterministic Windows regression distinguishes idle timeouts from EOF, exchanges request and response bytes, and verifies peer closure and finish. All 24 native macOS daemon tests, Windows ARM64 test compilation, and workspace formatting pass; native Windows runtime validation is delegated to CI. The Windows autostart test then hung because a background child created through Rust's `Command` inherited capture-pipe handles even with its stdio redirected. Use `CreateProcessW` with handle inheritance disabled for the Windows daemon, retaining only its owned process handle during startup. Pass the executable and verified working directory separately so paths need no command-line quoting. Bound daemon tests to two minutes in nextest so future stalls produce failures. The existing autostart test covers hook output completion while the daemon lives. All 24 macOS daemon tests pass, along with Windows ARM64 test compilation and strict Clippy, formatting, and nextest timeout-configuration validation. Co-authored-by: Codex <codex@openai.com>
The PR's advisory check reports `rustls 0.23.41`, which accepts TLS 1.3 handshake messages at the wrong encryption level. Reuse the lockfile update already applied on `main` in `fb988090a5843e43c84e3faf0cf07ecab3208e06`: `rustls 0.23.45` and its required `rustls-webpki`, `aws-lc-rs`, and `aws-lc-sys` updates. This vulnerability predates the branch's changes. The locked `gix-transport` build with the Rustls HTTP client passes. `cargo deny --locked check advisories` no longer reports the TLS vulnerability; the separate `ansi_term` maintenance advisory remains visible in the optional advisory job because `tracing-forest` has no released replacement for it. Assisted-by: Codex
Sebastian Thiel (Byron)
force-pushed
the
tix-improvements
branch
from
September 21, 2026 18:20
973b63b to
3334273
Compare
Creating the first visible commit reused the hidden parent-to-child rewrite map for every mutable ref at that base. This advanced unrelated branches and direct pins, and could reset an unrelated worktree index. Use explicit ref destinations for hidden-base insertion so only the ref selected by `HEAD` advances, or detached `HEAD` itself. Apply those destinations to AutoMerge inputs and worktree updates as well. Preserve ordinary visible-descendant replay and the existing behavior when creating an unborn branch. Cover ordinary and empty creation, inferred hidden bases in `tix new`, detached heads, late refs, linked worktree staging, descendant replay, AutoMerge inputs, and undo/redo. Update `spec.md` with the same behavior. Validation: all 793 `gix-tix` tests pass with `CI=1 GIX_TEST_IGNORE_ARCHIVES=1 cargo test -p gix-tix --features sha1 --offline --locked --quiet`. Workspace formatting and scoped Clippy checks pass; Clippy reports only the existing removed-lint configuration warning.
Ancestor pins add traversal tips, so tied committer timestamps can emit a pinned ancestor before its descendants. CLI todo preparation used that raw order to discover hidden-base descendants, exporting only the oldest commit from otherwise complete stacks and leaving `HEAD` outside the editable scope. Finalize loaded history with the TUI's existing topological lane computation before deriving the scope. This fixes ordinary todos, `--update-base`, and the shared `--edit-and-apply` preparation path. Cover a pinned ancestor with three equal-timestamp commits, asserting the complete scope, replay order, and checkout tip for both base modes. Record the scope invariant in `spec.md`. Validation: all 794 `gix-tix` tests pass with `sha1`, as do scoped Clippy and formatting checks. The rebuilt CLI exports all 15 commits from the reported stack with `tix rebase todo --update-base`.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Tasks