Skip to content

tix signature verification - #2842

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

tix signature verification#2842
Sebastian Thiel (Byron) wants to merge 24 commits into
mainfrom
tix-improvements

Conversation

@Byron

@Byron Sebastian Thiel (Byron) commented Jul 26, 2026

Copy link
Copy Markdown
Member

It's useful to validate that signatures are correctly set, and to validate them as well.

Consider merging after each task, as more of them keep piling up.

Tasks

  • refackiew gix::Commit::verify_signature()
  • refackiew external diff program handling
  • refackiew gix-note

Comment thread gix-tix/src/lib.rs Fixed
@Byron
Sebastian Thiel (Byron) force-pushed the tix-improvements branch 5 times, most recently from afdaef0 to 6b2dcd1 Compare July 28, 2026 14:40
Comment thread gix-tix/src/lib.rs
Some(*entry_mode),
),
};
let display_path = |path: Option<&gix::bstr::BStr>, prefix: &str| -> BString {
@Byron
Sebastian Thiel (Byron) force-pushed the tix-improvements branch 6 times, most recently from 80dff91 to 546c26d Compare August 4, 2026 15:31
Sebastian Thiel (Byron) and others added 7 commits August 5, 2026 07:03
Move signature verification from the gix commit verify command into gix::Commit so library users can verify commits without reproducing porcelain-only process handling.

Recognize OpenPGP, X.509, and SSH signatures and invoke the corresponding Git-compatible verifier. Honor configured verifier programs, minimum trust, SSH allowed-signers and revocation files, repository-relative paths, and the commit time used by Git for SSH verification.

Expose a structured outcome containing validity, status, trust, signer, key and fingerprint information, while retaining both human-readable and machine-readable verifier output. Unsigned commits remain distinguishable from failed verification.

Keep the API behind the command feature because verification executes external programs, and cover signature-format detection and verifier-output parsing.
Replace the command-specific GPG invocation with gix::Commit::verify_signature so the CLI and library share one implementation and one interpretation of repository configuration.

This extends the command from hard-coded OpenPGP verification to the OpenPGP, X.509, and SSH formats supported by Git, including configured programs and trust policy. Preserve verifier diagnostics on stderr and fail when a signature is invalid or insufficiently trusted.

Enable the gix command feature in gitoxide-core to make the shared verification API available.
Treat configured external diff commands as shell command lines instead of executable paths that require manual argument splitting.

Git diff drivers may contain a program followed by arguments. Passing such values through the shell-aware gix-command preparation path preserves that configuration while still appending Git diff arguments and environment variables in the established platform code.

Add coverage for a configured command containing an argument so custom diff drivers and text-conversion commands are launched as configured.
Establish the minimal plumbing API needed to query notes efficiently for many objects, such as every commit visible in a history view.

Resolve note blobs through Git notes progressive two-hex-digit fanout trees and use Git tree ordering for direct entry lookup. Load only trees along the requested object path and retain decoded trees in a caller-owned cache that can be reused across lookups and notes roots.

Ignore entries that do not form valid notes instead of mistaking arbitrary tree contents for mappings. Use gix-error for contextual failures and add tests for fanout lookup, cache reuse, and malformed leaf entries.
Add plumbing operations to insert, replace, and remove note mappings while returning the rewritten root tree and the previous note id.

Rebuild notes using the same dynamic fanout rule as Git so growing and shrinking collections remain compatible with existing notes trees. Preserve unrelated entries during rewriting, reject mixed object-hash kinds, report duplicate mappings, and leave the tree unchanged when removing a missing note.

Keep object persistence delegated through Find and Write traits, allowing callers to decide how commits and refs are updated. Test fanout expansion and collapse, replacement and removal results, and preservation of non-note entries.
Add the notes feature and Repository::notes as the porcelain layer over gix-note for repeated queries and mutations.

Select the default notes ref from core.notesRef, including the GIT_NOTES_REF environment override represented in config::tree, and fall back to refs/notes/commits. Discover additional display refs from notes.displayRef or GIT_NOTES_DISPLAY_REF, expand glob patterns, preserve display order, and avoid duplicates.

Retain lazily resolved notes roots and the shared decoded-tree cache so querying all visible commits does not repeatedly traverse the same trees. Return attached note blobs together with their source refs and allow callers to replace the displayed ref set.

For mutations, accept conventional short notes-ref names, write note blobs and notes commits, and update refs with compare-and-swap expectations so concurrent changes are not silently overwritten. Keep cached roots coherent after edits and cover configured-ref lookup, replacement, and removal through the repository API.
Consolidates:
- feat: verify visible commit signatures in tix
- fix: color commit selections by signature status
@Byron
Sebastian Thiel (Byron) force-pushed the tix-improvements branch 2 times, most recently from 9616ac2 to 2618805 Compare August 5, 2026 07:31
Improve attribution display while retaining access to complete actor identities.
Treat every Assisted-by trailer value as an agent, toggle full actors and
emails while hiding attribution comments, omit classified agent emails,
italicize GitHub noreply actors, and group attribution keys whose displayed
values are identical.

Detect agent markers in commit messages and prefix generated commit titles
with a bright-purple [A] marker shared with the Git notes marker.
Consolidates:
- fix: scope Shift handling to the active tix screen
- feat: focus tix navigation on reachable commits
- feat: isolate merged history in Shift navigation
- feat: include merge fork points in Shift navigation
- fix: defer Shift reachability until graph completion
- feat: cycle junction parents during Shift navigation
Retain the selected commit when toggling hidden history, falling back to the
top only when the commit is no longer present. Hide references together with
ancestry so filtered rows remain visually aligned.

Retain excluded parents directly connected to visible commits as dimmed,
terminal-colored boundary rows that show where graph lanes terminate without
restoring full hidden ancestry. Keep these rows outside selection, paging,
Shift navigation, signature verification, and selection restoration.
Add a default-open, focusable bottom panel for changed paths in the selected
commit. Preserve diff order, summarize color-coded change kinds and line
counts, support merge-parent cycling and path navigation, cap the panel at
half the screen, and hide it during repeated history navigation. Distinguish
inactive panels and history, expose focus feedback, and return with q/Escape.

Compute line statistics in a temporary available-parallelism worker pool and
use a short-lived cached repository for tree changes. Highlight compared
parents, reuse computed line counts, and open selected file diffs through the
built-in viewer or Git-compatible external diff and core.pager pipeline,
preserving output from immediately closing pagers.

Keep aligned metadata stable while panning and resizing panels. Avoid letting
the default changes view force inline startup into the alternate screen, and
delay empty loading frames to prevent scrollback residue and startup flashes.
On exit, retain only the left selection marker in static frames, including
when leaving an alternate screen, and let Ctrl-C terminate from any focus.
Show Git notes in history with a bright-purple [N] marker and render their
contents before trailers in the commit view. Load notes lazily for visible
commits through the repository notes platform and refresh them with the view.

Make overflowing commit messages page-scrollable with PgUp/PgDn and Ctrl-b/
Ctrl-f, clamp offsets when content changes, and show pane-specific navigation
status only while scrolling is possible and the pane is focused. Give pane
status bars a distinct background without changing the main status line.
Watch the repository reference stores with native filesystem notifications and extract every direct or symbolic reference used by the view and hidden revspecs. Re-evaluate notifications lazily: traversal-tip changes refresh history, while unrelated reference changes are ignored and visible decoration changes update without retraversal. Defer tip refreshes until the active traversal and lane computation finish, and retain Shift-R only as a fallback when a watcher cannot be established.

Keep an append-only cache of discovered commit rows and their complete parent topology. Incremental walks stop at cached commits, decode only newly encountered ODB commits, and derive the current visible and hidden-boundary projection in memory without pruning commits that leave the view. Recompute lanes off-thread and atomically replace the rendered graph so the old frame and selection remain stable until the refreshed graph is ready.

Reopen isolated repositories with a small object cache for incremental traversal, preserve notes refresh behavior for manual view toggles, and re-evaluate inline versus alternate-screen sizing after the projected history changes. Treat refs that disappear between filesystem enumeration and reading as transient, while continuing to report malformed or inaccessible refs. Add coverage for symbolic reference discovery, missing-ref races, and cached fast-forward, rewind, and restoration.
Reserve space before the history selection tail for compact information about
the selected commit. Reuse bright tree-change line counts, and for commits
pointed to by refs show one deterministic upstream ahead/behind relation or a
visible-ancestry count when hidden history exists.

Resolve fetch tracking branches through gix, use commit-graph-aware counts,
cache results by commit and upstream targets, invalidate them with reference
or projected-history changes, and reuse the navigation repository and object
cache during repeated movement.

Keep blank margins around contextual information and the right-hand selection
marker even when clipped. Clear the marker cell before applying inversion so
row text is never inverted accidentally.
@Byron
Sebastian Thiel (Byron) force-pushed the tix-improvements branch 2 times, most recently from de8bfaf to 4fb9db7 Compare August 6, 2026 05:07
Show Tree and Worktree changes together by default and cycle c from Both to
Tree to Hidden. Collect staged, unstaged, untracked, and conflicted paths with
the cancellable status iterator, preserve Git-like ordering and colors, and
reuse computed per-path line counts for summaries, selected rows, and the
existing external or built-in diff pipeline.

Watch the worktree and index only while needed, debounce updates for 75ms, and
retain independent caches, selection, scrolling, and errors for both sources.
Represent conflicts, submodules, unavailable diffs, and an enabled clean
worktree without launching inappropriate pagers.

Render both blocks over the full-height history, side by side when their
condensed summaries fit and stacked otherwise. Join unequal borders, cap their
height, keep history visible beside shorter blocks, and bound navigation above
the top-most block so advancing scrolls history while the selected row stays
fixed. Cycle focus in visual order and keep merge-parent controls on Tree.
Capture terminal mouse input while tix is active and restore it across screen transitions and exit. Map vertical wheel and trackpad events to history movement and horizontal events to the existing pan actions.

Treat vertical scrolling over the history like repeated keyboard navigation: hide the changes blocks, retain the temporary fill repository, and restore both after the existing 75 ms idle window. Keep scrolling within a focused changes block visible, and ignore clicks, drags, and pointer movement.

Apply every scroll event faithfully while rate-limiting redraws to the existing frame interval. This lets fast wheel bursts drain from the terminal queue without rendering and refilling the selected view after every event.
Keep the live commit count in the history status bar while traversal, cancellation, and lane computation are active. Once the completed graph is displayed, replace it with a reverse row number for the current selection.

Number displayed rows from the bottom so the oldest row is #1 and the top-most row is the total number of commits. Retain the commit count for empty histories where no row can be selected.
A deleted linked worktree invalidates the per-worktree Git directory watched
by tix, even on systems where the process current directory still resolves.
Normalize the common repository path lexically at startup so it no longer
traverses the removable `.git/worktrees/<name>` directory. On removal, move
into that common directory and reopen it with core.bare enabled, then restart
reference watching there so history remains live.

Drop worktree-derived state during recovery and keep the changes view limited
to tree changes. Temporary repositories and diff workers retain the bare mode,
and the line-diff pool avoids creating worktree resources even when gix still
retains an inferred main-worktree path internally.

Show successful recovery in the main status line until the next user action.
If changing into or opening the common repository fails, restore the terminal
and return the contextual error instead of silently quitting.
Lay out the commit message and change blocks within a shared overlay region so
they no longer paint over each other. Reserve the commit message width first
and let tree and worktree changes adapt within the remaining space.

Delineate the commit message with a left border and move its title onto the
first pane row while retaining its padding and scrolling status.
Filesystem-driven reference updates can insert or replace traversal tips, so a
preserved selection may leave the refreshed view positioned in stale context.
Track the refresh origin through asynchronous traversal and lane computation,
then select the first selectable row only for watched-reference refreshes.
Manual and visibility reloads continue preserving their selection.
Collapse history presentation controls behind a `v view` prefix to keep the
main status concise. Expand date, actor, mailmap, trailer, reference, and hidden
history controls on demand while leaving alignment and overlay panes direct.

Keep the display group open for consecutive presentation changes and collapse
it after navigation or any other recognized command.
Use the terminal bright-red color for deletions, unstaged changes, failed signatures, errors, behind counts, and graph rails so red remains legible against dark backgrounds.

Render insertion and removal counts only when non-zero in history selection information, changes summaries, and selected changed paths. Keep clean worktree blocks visible by their title.
Make the existing y shortcut copy the selected path when either changes block has focus. Preserve raw Git path bytes and retain commit-id copying when history has focus.
Reserve eighty content columns for commit messages on sufficiently wide terminals, in addition to the panel border and horizontal margins. This prevents conventionally wrapped commit text from orphaning its final word.
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.

3 participants