fix(gix-tix): fetch promised blobs on demand - #3018
Johannes Schindelin (dscho) wants to merge 140 commits into
Conversation
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. CI validation: Windows `cargo nextest run --workspace` exposed assertions that compared native backslash paths with Git's slash-separated linking files and worktree listing. Normalize expected Git paths with `gix-path` without changing native filesystem paths. All seven plumbing creation tests and five repository creation tests pass locally. Assisted-by: Codex
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.
Open an inline fuzzy search from the worktrunk picker so large worktree inventories can be narrowed without leaving the combined history view. Reuse the command menu Unicode-safe editing and fuzzy matching, map filtered positions back to stable inventory rows, and defer each preview rebind until the selected row has painted. Arrow and page keys navigate matches, Enter promotes the match, and Escape restores the selection that opened the search. Page movement uses the visible table body rather than counting its header.
Add --new-branch NAME as a branch-only alternative to the positional switch target. Create a missing local branch at the logical Tix HEAD, including the remembered branch while physically detached, then reuse the existing worktree resolution and creation path. Existing branches are never moved, already-claimed branches reuse their worktree, and --path remains available for either switch form.
Reuse one append-only history graph across worktree previews so selecting another worktree only traverses ancestry that is not already cached. Derive ahead/behind and base diffstats from that shared graph instead of repeating independent walks. Keep picker input responsive while graph and lane work runs, activate only the latest selected preview, and leave the previous history visible but read-only until then. Preview mode avoids filesystem watchers and refreshes worktree-specific diff state on activation. Render ahead/addition counts in green and behind/removal counts in light red. Preserve graph and selection correctness across hidden-frontier changes, stale completions, invalidation, and failed refresh retries.
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>
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
Blobless partial clones made Tix abort when visible line counts or file, commit, or editor-summary diffs needed blobs that were promised but absent locally. This prevented normal use even when configured promisor remotes could supply the objects. Fetch only the missing blob and symlink objects required by the current operation, batching requests per promisor remote and retrying unresolved objects across subsequent remotes. Preserve `GIT_NO_LAZY_FETCH`, exclude submodule commits and unrelated objects, and rebuild active line-diff workers so they observe newly fetched packs. Gitoxide does not yet provide native promisor-object fetching. Delegating Git's established multi-OID `fetch --stdin` protocol at this boundary avoids introducing a second partial-clone transport while allowing regression coverage to fetch four absent blobs into a single promisor pack. Assisted-by: GPT-5.6 Sol <gpt-5.6-sol@openai.com> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
|
That's cool, thanks :)! One thought: could extra work only be performed if an object not found error is caught? Also, I suggest we reframe this as your slop-fork for experimentation, and we see what we merge once you have tried it a bit longer. Generally, open to merge anything as long as it's in It's also a playground to try new APIs and bring them to |
|
Here is the result of a codex review, I don't know if they make sense, it's just FYI:
|
|
Ooops... Sebastian Thiel (@Byron) I had not looked over these changes myself yet, I just had the time to start to test it... but in my partial clone of I really need to find the time (after the Git for Windows v2.56.0 on Monday and the fall-out thereof) to look over these changes, and to see how much it would take to avoid that ugly, ugly |
25dad29 to
d963061
Compare
Blobless partial clones made Tix abort when visible line counts or file, commit, or editor-summary diffs needed blobs that were promised but absent locally. This prevented normal use even when configured promisor remotes could supply the objects.
Fetch only the missing blob and symlink objects required by the current operation, batching requests per promisor remote and retrying unresolved objects across subsequent remotes. Preserve
GIT_NO_LAZY_FETCH, exclude submodule commits and unrelated objects, and rebuild active line-diff workers so they observe newly fetched packs.Gitoxide does not yet provide native promisor-object fetching. Delegating Git's established multi-OID
fetch --stdinprotocol at this boundary avoids introducing a second partial-clone transport while allowing regression coverage to fetch four absent blobs into a single promisor pack.