Skip to content

Grix Improvements - #3060

Draft
Sebastian Thiel (Byron) wants to merge 195 commits into
mainfrom
grix
Draft

Sebastian Thiel (Byron) wants to merge 195 commits into
mainfrom
grix

Conversation

@Byron

@Byron Byron commented Oct 14, 2026

Copy link
Copy Markdown
Member

This PR is just to run CI and fix it up from time to time.
Unless it can be reviewed in one go, commits are likely to be picked into different branches to get them merged.

break;
}
b"get" => {
if let Some((entry, _)) = entries.iter().find(|(entry, _)| credential.matches(entry, false)) {
}
b"erase" => {
let len = entries.len();
entries.retain(|(entry, _)| !credential.matches(entry, true));
}
}
b"store" if timeout >= 0 && !credential.ephemeral && credential.complete() => {
entries.retain(|(entry, _)| !credential.matches(entry, false));
for file in &files {
for line in lines(file, true)?.into_iter().flatten() {
let line = line.or_raise(|| message("Could not read credential store"))?;
if let Some(entry) = parse_url(&line).filter(|entry| matches(&context, entry, false)) {
file,
Some(&context),
Some(encode_url(&context)),
false,
file,
(!has_credential).then_some(&context),
None,
true,
Provide byte-preserving stripspace and comment-line transformations for the
Rust Git CLI. Keep shared text behavior in the plumbing crate so future
commit-message and CLI consumers can reuse it.

Git reference: 6de20f6092dcf9bdb1c8efe03db4b70c82b423dd,
t/t0030-stripspace.sh, builtin/stripspace.c and strbuf.c. The Rust
implementation is independent; regressions include binary data, Git's
whitespace definition, paragraph boundaries, and tab-prefixed comments.

Validation: gix-utils unit/integration/doc tests; byte comparison through
gix-testtools; the grix candidate passes all 30 unmodified t0030 cases.
A newline supplied through `git -c core.commentChar=<newline>` became an
empty value because override parsing trimmed both sides of `=`. This also
changed whitespace-sensitive values and accepted whitespace in key names.

Split the assignment without trimming. Update the documented examples
and the existing fixture to use valid keys, and compare CLI/API override
values with Git for whitespace, empty values, quotes, and additional `=`.

Git reference: `6de20f6092dcf9bdb1c8efe03db4b70c82b423dd`,
`t/t0030-stripspace.sh` case 21 and `git_config_parse_parameter()` in
`config.c`. The regression failed before the fix.

Validation: 131 `gix` configuration tests pass; the Rust CLI passes all
30 unmodified `t0030-stripspace` cases.
Expose the shared `core.commentChar`/`core.commentString` interpretation
needed by the Rust Git CLI without putting configuration semantics into
its command crate. Honor assignment order, preserve byte strings, and
return classified validation errors with key/value metadata.

The helper is for non-editor text processing: `auto` resolves to `#` and
content-dependent editor prefix selection is outside this API. Implicit
values are rejected with the documented empty-value diagnostic for now.

Git reference: `6de20f6092dcf9bdb1c8efe03db4b70c82b423dd`,
`environment.c` and `t/t0030-stripspace.sh`. Tests cover alias order,
subsections, case handling, binary prefixes, and invalid values.

Validation: 131 `gix` configuration tests pass; the Rust CLI passes all
30 unmodified `t0030-stripspace` cases with no skips.
Record Byron's instruction to commit semantically closed, validated steps
in both local checkouts using the `tix` skill. Keep this worktree-specific
workflow note separate from backend changes intended for upstream porting.

Validation: documentation and diff review.
Git configuration and expiry operations interpret exact `never`/`false`
as zero and `all`/`now` as the maximum unsigned timestamp. Ordinary date
parsing cannot express these semantics: `now` otherwise resolves to the
reference clock.

Add `parse_expiry()` using the existing date parser for ordinary input,
retaining its validation metadata and converting signed relative results
to Git's unsigned timestamp representation. This enables typed config
defaults in the grix CLI without putting shared date semantics there.

Behavior reference: Git `6de20f6092dcf9bdb1c8efe03db4b70c82b423dd`,
`date.c:957` (`parse_expiry_date`) and `t1310-config-default.sh` case 4.
The implementation is independent Rust; supported ordinary date syntax
continues to follow `gix_date::parse()`.

Validation: regression added before implementation; `cargo test -p gix-date`
(2 unit, 64 integration, 1 doctest), `cargo clippy -p gix-date --all-targets
-- -D warnings`, formatting, and diff checks. Tests compare representative
values and invalid input against Git through isolated `gix-testtools` helpers.

The `test-fast (windows-latest)` and `test-fixtures-windows
(windows-latest)` CI jobs failed in `expiry_values_match_git`: Git for
Windows returned `u64::MAX` for `1 year ago` with a reference clock at
second 1, while `parse_expiry()` returned the wrapped pre-epoch date.
Windows' `mktime()` cannot represent that calendar date, so compare
calendar subtraction with Git using a post-epoch result. Keep the
pre-epoch wrapping contract covered directly for seconds and years.

Validation: the four expiry tests pass with
`GIX_TEST_IGNORE_ARCHIVES=1 cargo test -p gix-date --test time parse::expiry`,
and `cargo fmt --all -- --check` passes.
Configuration consumers must distinguish a missing optional target from
a required path and from filesystem failures. Interpolation alone removes
the `:(optional)` marker without making that distinction.

Add `Path::resolve()` on top of the existing interpolation API. It returns
`None` only for an optional target whose metadata lookup reports not found,
including dangling symlinks. Other IO errors retain their original cause;
required paths do not need to exist. Explicit empty paths remain empty and
optional empty paths are omitted, while `interpolate()` remains strict.
Relative paths use the process current directory for inspection and retain
their relative spelling.

Behavior reference: Git `6de20f6092dcf9bdb1c8efe03db4b70c82b423dd`,
`t1311-config-optional.sh`, path handling in `config.c`, and
`wrapper.c:is_missing_file()`. This independently implemented helper lets
grix omit optional config entries before selecting the last value.

Validation: regressions added before implementation, 67 integration tests
and 3 doctests for `gix-config-value`, clippy with warnings denied,
formatting, and diff checks. Isolated `gix-testtools` comparisons ran with
the requested reference Git, including missing/existing targets, home
interpolation, dangling links, and ENOTDIR. Comparisons are version-gated
for developers with Git older than 2.53; native assertions always run.

The `test-32bit (arm32v7)` CI job failed in all three Git comparison
sections for optional paths. Its Debian image provides Git 2.47.3,
which treats `:(optional)` literally. The usual version-skip helper
always enables comparisons on CI, even when that Git lacks support.
Check the existing `GIT_VERSION` value directly for these comparisons;
the resolver assertions still run with every Git version.

Validation: all four resolver tests pass against Git 2.54, and with
`CI=true` and a disposable Git version shim reporting 2.47.3, exercising
the comparison gate without skipping resolver coverage.
`cargo fmt --all -- --check` passes.
Typed configuration consumers need to distinguish a missing `=` from an
explicit empty value for every matching occurrence. Existing multivalue
accessors collapse both into empty strings, and the single-value implicit
accessor cannot validate earlier values or retain their individual scopes.

Add `File::raw_values_implicit_with_sections()`, returning normalized
optional values with their original sections. Reuse its parsing path for
existing accessors while preserving their signatures and results. This
lets grix format implicit booleans, reject implicit paths, accept explicit
empty paths, and omit optional entries before choosing the last result.

Behavior reference: Git `6de20f6092dcf9bdb1c8efe03db4b70c82b423dd`,
`t1300-config.sh` typed path/boolean cases and `t1311-config-optional.sh`.
An isolated Git comparison verifies implicit true versus explicit empty
false. Regression cases cover repeated sections, source metadata,
continuations, escaping, missing keys, and compatibility of old accessors.

Validation: regressions added before implementation; 377 runtime tests
with all features, 31 stable-compatible doctests, all-target Clippy with
warnings denied, formatting and diff checks. The `document-features`
doctest configuration needs nightly and was excluded on stable.
All 131 `gix` configuration integration tests also pass with the new lookup.
Git's config replacement operation keeps one new value at the final
matching position. `set_all()` instead retains every occurrence, while
index-by-index mutation forces consumers to reconstruct that operation.

Add `MultiValueMut::replace_at_indices()`. Validate the complete sorted,
unique selection before mutation, keep unmatched entries in order, and
make empty selections a no-op so callers can decide whether to append.

Behavior reference: Git `6de20f6092dcf9bdb1c8efe03db4b70c82b423dd`,
`t1303-wacky-config.sh` replacement cases and `config.c` multivar editing.
Regression tests compare through isolated `gix-testtools` helpers,
covering repeated sections, implicit/empty values, escaping, neighboring
entries, and invalid indices that leave the file unchanged.

Validation: 13 focused multivalue tests against source Git; 104 unit,
274 integration, 1 memory, and 31 doctests with installed Git; Clippy,
formatting, and diff checks. An unrelated installation-config assumption
prevents the full suite from using the uninstalled source binary.
Changing a staged object ID, mode, path or stage could leave a valid-looking
`TREE` extension behind. A later `git write-tree` then reused the old tree,
even though the index entries described different content.

Discard the cache when exposing mutable entries, inserting or removing
entries, or replacing path storage. This also covers deferred removal flags
and callbacks that mutate entries without removing them. Sorting and
read-only access preserve the cache. Stat-only mutation conservatively
loses the cache until a more selective mutation API is available.

Reference: Git `8d1b215c01512b9658d4525c54ff9b9245f9a7e8`,
`read-cache.c` and `cache-tree.c`. Regression comparisons use isolated Git
repositories and check `write-tree` output and `fsck --cache`.

Validation: regression failed before the fix; all 101 index tests pass;
all-target Clippy with warnings denied, rustfmt, and diff checks pass.

Model: Astra 6.0
Callers can now register and check out an unborn symbolic HEAD directly,
without creating a temporary branch or replacing a detached commit ID.
Accept full targets beneath `refs/`, reject existing targets, and reserve
local branch names across worktrees. Other symbolic targets may be shared.

Initial and deferred checkout create an empty index. Preparation creates
neither a branch nor a HEAD reflog. The public `Head` and `Error` enums gain
`Unborn` and `ReferenceExists` variants respectively.

Reference: Git `8d1b215c01512b9658d4525c54ff9b9245f9a7e8`,
`builtin/worktree.c`. Tests compare with `git worktree add --orphan` and
verify HEAD, index, reflog and branch state. Unlike Git, preserve the
existing occupancy invariant for unborn local branches too.

Validation: all 61 repository worktree tests pass on the current grix base;
formatting and diff checks pass.

Model: Astra 6.0
Provide the protocol data model needed to send native pushes. Validate
reference commands, object formats and packet boundaries before writing;
negotiate required capabilities and preserve advertised old IDs for the
server's compare-and-swap checks. Expose pack-format and sideband choices.

Parse report-status and report-status-v2, retaining partial failures and
proc-receive destination details. Reject missing, unsolicited or malformed
statuses so an interrupted push cannot be mistaken for confirmed success.
Transport execution and pack generation are separate steps.

Reference: Git `8d1b215c01512b9658d4525c54ff9b9245f9a7e8`,
`send-pack.c`, `builtin/receive-pack.c`, and the pack protocol specification.
An isolated receive-pack test verifies real partial deletion and stale
compare-and-swap failures.

Validation: 71 blocking protocol tests and 4 async push tests pass;
no-network compilation passes. All-target Clippy passes with only the
existing disabled-tracing drop_non_drop lint allowed; formatting passes.

Model: Astra 6.0
Add a byte-oriented matcher that returns borrowed source declarations and
their line numbers. The default follows Git's identifier rule. Explicit
Rust byte-regex patterns support ordered exclusions and capture group 1,
letting consumers provide language rules without duplicating scanning.
Git's POSIX funcname/xfuncname configuration is not parsed by this API.

Preserve invalid UTF-8 and Git's whitespace semantics, including vertical
tab and form feed. Keep presentation width and hunk selection with callers.

Reference: Git `8d1b215c01512b9658d4525c54ff9b9245f9a7e8`,
`xdiff-interface.c`, `xdiff/xemit.c`, and `ctype.c`. Read-only fixtures
compare default and shared-regex syntax with Git's hunk headers.

Validation: all 110 diff integration tests pass; the six matching tests
and all-target Clippy pass after moving Git setup into fixture creation.
Formatting and diff checks pass.

Model: Astra 6.0
Allow applications that manage working files themselves to register a
linked worktree in an existing directory. Reuse HEAD validation and config
inheritance, and persist only administrative files, without writing an
index or checking out tracked content.

Add gix-worktree's `prepare_in_place()` with rollback ownership limited to
the newly created `.git` link for existing destinations. Never replace an
existing `.git` file, directory or symlink; retain unrelated files even if
configuration setup fails after registration starts.

Validation: 16 plumbing add tests and all 63 repository worktree tests
pass, including rollback, existing gitlinks, relative paths, sparse config,
shared unborn targets, and Git recognition. Formatting and diff checks pass.

Model: Astra 6.0
Native push clients must drain receive-pack sidebands while uploading the
pack; a full progress pipe can otherwise deadlock both peers. Preserve the
writer's Send bound in a new request constructor and extraction method so
callers can upload on a worker while reading on their current thread.

Existing non-Send request writers remain supported by the original
constructor and extraction methods. Built-in transports use the Send path;
generic TCP writers and HTTP PostBody implementations now require Send.

Validation: curl transport tests and concurrent/non-Send request regressions
pass; the reqwest client compiles. All-target Clippy passes with pre-existing
async-shaped test lint findings allowed. Formatting and diff checks pass.

Model: Astra 6.0
Expose targeted worktree unlinking for applications that retain checkout
contents when removing Git integration. Reuse registration selection and
backlink validation, remove only the selected gitlink and administration,
and leave unrelated worktree registrations alone.

Respect worktree locks and protect initialized submodule metadata unless
forced. Modified and untracked files are always retained. Missing checkout
paths or gitlinks can still have their administration removed.

Validation: all 66 repository worktree tests pass, including retained
files, unrelated stale registrations, locks, submodules, and altered
backlinks. Formatting and diff checks pass.

Model: Astra 6.0
Git encodes an empty push option as `0004`, which is distinct from the
`0000` flush packet. Accept and produce empty payloads in both blocking and
async packetline encoders, decoders and writers. Byte-stream readers skip
empty data packets so they cannot report premature EOF before a flush.

Reference: Git `8d1b215c01512b9658d4525c54ff9b9245f9a7e8`,
`Documentation/gitprotocol-common.adoc` and push-option framing.

Validation: all four regressions failed before the fix. Forty blocking
tests and a doctest, two async unit tests, forty async integration tests
and a doctest pass; combined-feature Clippy and formatting pass.

Model: Astra 6.0
Provide breadth-first traversal of arbitrary object tips for consumers
that need object closure, including pack generation and garbage collection.
Follow tag targets, commit trees and parents, and tree entries; omit
gitlinks because they name objects in other repositories. Deduplicate
shared objects and support shallow boundaries without skipping their trees.

Validate edge kinds even when a target was already visited. Missing or
malformed objects terminate the iterator with an error, preventing callers
from treating incomplete reachability as a complete object set.

Reference: Git `8d1b215c01512b9658d4525c54ff9b9245f9a7e8`,
`list-objects.c`, `reachable.c`, and `rev-list --objects`. Read-only fixtures
cover nested and blob tags, repeated tips, shared trees, unavailable
gitlinks, shallow parents, malformed trees and incorrect tag target kinds.

Validation: all 60 traversal tests pass; the four new tests also pass with
SHA-256 fixtures. All-target Clippy, formatting and diff checks pass.

Model: Astra 6.0
Git's configured hunk headers use POSIX basic and extended expressions,
including backreferences. Rust's regex crate cannot interpret that syntax
and matching behavior faithfully. Import the MIT-licensed posix-regex
0.1.4 engine from Redox as a separately maintained plumbing crate.

Retain its copyright and license, and record the upstream revision in the
README and crate source. Preserve the original compiler and matcher tests,
placing public API coverage in integration tests. Apply the small compiler
and style adaptations needed for current Rust without changing the engine.

This checkpoint does not wire the engine into Git configuration. Parser,
matching and resource-bound conformance fixes will precede that integration.

Validation: all 33 imported tests pass with default and no_std features;
all-target/all-feature Clippy with warnings denied passes.

Model: Astra 6.0
Concurrent pack uploads must interrupt both directions when the producer or
consumer fails. Dropping borrowed TCP or child-process streams does not
close them, and would leave the other side waiting indefinitely.

Allow request writers to carry an abort callback. Built-in TCP connections
shut down their sockets, while process transports terminate the service.
Verify that TCP abort stops reads and writes.

Model: Astra 6.0
Send receive-pack commands, shallow boundaries, push options, and generated
packs while draining remote sidebands concurrently. Preserve per-reference
status reports and abort failed uploads so either side can finish without
deadlocking.

Exercise pack transfer, hook output, empty push options, deletion-only
requests, and pack-producer failure against Git.

Model: Astra 6.0
Reject unclosed groups, references to absent or still-open groups, and
invalid bracket ranges. Parse one-digit POSIX backreferences without
consuming a following literal digit, and retain literal brackets and ERE
closing parentheses where Git accepts them. Inclusive byte ranges now
handle 255 without overflowing.

Compare parser acceptance and selected captures with Git's hunk headers
using isolated read-only fixtures. Enable workspace lints with narrow
exceptions for inherited code and provide printable parser errors.

Model: Astra 6.0
Interpret GNU POSIX escapes and word boundaries like Git, including literal
escaped letters and absolute anchors. Respect positional BRE anchors and
reject chained bracket ranges. Fold ASCII letters in literals, character
classes, and backreferences without also folding punctuation.

New public `Token` variants represent boundary and absolute-anchor checks.
Regression tests and Git differential fixtures cover the corrected cases.

Model: Astra 6.0
Provide a native pruning primitive for callers that have computed a complete
protection set. Recheck modification times after reachability lookup,
preserve recent files, and tolerate concurrent deletion. Dry runs return the
same object and compressed-byte counts without deleting files.

Restrict pruning to regular files in hexadecimal fanout directories. Leave
symbolic links, packs, alternates, temporary files, and unknown paths alone.
Document the caller's responsibility for recent objects' dependencies and
repository policy.

Compare expiry boundaries and reachability with Git for SHA-1 and SHA-256.
Cover cancellation, concurrent freshening, and unexpected paths as well.

Model: Astra 6.0
Provide `Repository::clear_merge_state()` with `git merge --quit` behavior:
leave HEAD, the index, and working files intact, and remove merge messages,
conflict metadata, and `AUTO_MERGE`.

Preserve autostashes in `refs/stash` with a forced reflog before removing
their source reference. Invalid stashes and failed preservation retain the
merge state for recovery. Operate on the selected worktree independently
of reference namespaces, matching Git's local operation commands.

Compare with Git, including disabled reflogs, existing stashes, locked
references, linked worktrees, and reference namespaces.

Model: Astra 6.0
Make decoded `REUC` paths, modes, and object IDs available to callers.
Maintenance must retain these objects so a resolved conflict can still be
restored after garbage collection.

Compare all three original stages with `git ls-files --resolve-undo` for
SHA-1 and SHA-256 indexes, including executable file modes.

Model: Astra 6.0
Use the correct closing delimiter for BRE and ERE intervals, accept GNU
omitted bounds, and enforce Git's finite repetition limit. Reject leading
ERE repetition operators. Share interval parsing so the two syntaxes cannot
diverge in range validation.

Compare parser acceptance with Git and correct inherited tests that used
an unescaped closing brace for BRE intervals.

Model: Astra 6.0
Add `Repository::write_pack()` behind `pack-generate` for reusable native
push, local transfer, and maintenance. Deduplicate supplied IDs and stream
compressed objects while checking their checksums and ignoring replacement
refs. Respect configured pack compression and cancellation.

The caller selects objects and owns the output; errors can leave a partial
pack. Validate generated packs with Git's strict index-pack, including
SHA-256, and cover missing, corrupt, and replaced objects.

Model: Astra 6.0
GitMeta must preserve pre-push hook execution while replacing the Git binary.
Let callers inspect the exact advertised and planned updates before either
native local or protocol pushes transfer objects. Hook errors abort publication,
including before quarantine creation. Existing callers retain their hook policy
with the default absent callback, and applications reuse `gix-hook` for execution.

Local push regressions pass; a rejecting callback leaves refs and objects untouched.

Model: Astra 6.0
GitMeta's selected grix features leave three dead-code expectations unfulfilled.
These declarations intentionally tolerate unused scaffolding regardless of which
features use it, so allow that lint without requiring it to fire.

Model: Astra 6.0
GitMeta hydrates blobs in bounded fetches while retaining an open repository.
Each batch can add a pack, exhausting the slot capacity chosen when the store
was opened. Grow automatically sized slot maps without moving the shared slot
allocations or invalidating existing pack IDs. Explicitly fixed capacities keep
their existing behavior, and growth stays bounded by the pack ID representation.

The new capacity regression, all 94 object-store tests, the threaded suite, and
all-target Clippy with parallel support pass.

Model: Astra 6.0
…story

GitMeta publishes from blobless metadata clones. Exclude the receiver's
advertised graph before reading outgoing objects and retain missing IDs
as opaque boundaries, while still rejecting missing newly needed objects.

Validated protocol v1/v2 hydration, local and wire push against Git,
missing-new-object rejection, traversal and remote tests, and GitButler
native push compatibility.

Model: Astra 6.0
Expose `quote_with()` for callers honoring `core.quotePath=false`, while
preserving the default behavior of `quote()`. GitMeta uses this for
native changed-path output.

Validated all 14 ANSI-C quotation tests.

Model: Astra 6.0
GitMeta needs to compact hydrated object batches even when promised history
is absent. Add `Repository::repack_objects()` using the existing inventory,
verification and safe replacement machinery. Keep promisor objects separate,
preserve object ages and kept packs, and retain all inventoried objects.

Validated nine GC tests, including partial graphs, hydrated objects, cruft
ages and lock/corruption failures; gix all-target Clippy passes with
`object-maintenance`. GitMeta maintenance and 900 serialization rounds pass.

Model: Astra 6.0
Blobless metadata synchronization must also work with servers that do not
advertise filtering. Follow Git by reporting the unsupported filter through
progress and receiving the complete requested graph.

Validated protocol v1/v2 against Git t5500 behavior, plus hydration and
partial-clone push tests.

Model: Astra 6.0
Like Git upload-pack, unshallowing against a complete source also transfers
known client boundary histories outside the selected refs. Retain boundaries
that the source cannot supply.

Validated 18 local fetch tests, including a Git-oracle merged DAG, repeated
relative deepening, unrelated history completion and foreign boundaries.
Native operations run with Git absent from PATH.

Model: Astra 6.0
GitMeta needs native blame for uncommitted contents and the previous commit
and path emitted by Git porcelain. Reuse the existing traversal to expose
that information, respect shallow boundaries, and prevent attribution across
file-type changes. Existing commit-based entry points remain available.

Validated 61 plumbing unit, 39 integration, one doc and five porcelain tests
against Git, plus native GitMeta inspection tests and targeted Clippy.

Model: Astra 6.0
Use the shared streaming runner for `gc.recentObjectsHook` so silent children
can be cancelled and reaped. Parse object IDs incrementally with bounded
invalid output while preserving stderr and failure propagation.

Validated ten GC tests, including CRLF, a missing final newline, malformed
and oversized output, cancellation and object retention. Targeted Clippy passes.

Model: Astra 6.0
The same blob can use different attributes and text converters at different
paths. Include the path in object-backed cache keys so blame and diff do not
reuse another path's conversion.

Regression reproduced the incorrect binary-driver reuse before the fix; ten
platform tests and all-target Clippy pass.

Model: Astra 6.0
Allow callers such as GitMeta to opt into configured text converters. Use
the same converted contents for initial lines and historical comparisons,
while measuring rename similarity on stored blobs. Respect current attributes
and preserve raw binary and symlink behavior. Default behavior stays unchanged.

Validated plumbing and porcelain blame suites with Git, including converter
failures, path-dependent attributes, renames and default-off behavior.

Model: Astra 6.0
Add `Repository::blame_worktree_file()` to read tracked worktree contents,
apply filters and optional textconv, and follow staged rename sources.
Keep the synthetic index and blobs in memory; preserve previous origins
without changing repository objects or index contents.

Validated staged renames, additional unstaged edits, complete rewrites and
unchanged object/index state against Git; native GitMeta inspection passes.

Model: Astra 6.0
Relative textconv commands need the same repository environment and working
directory as filters. Reuse the existing filter context and anchor worktree
roots to the repository's captured current directory, retaining diagnostics.

Validated 55 blob tests and three blame textconv tests, including object and
worktree conversion from another directory. Both crate Clippy checks pass.

Model: Astra 6.0
Add prepared contents with ordered parent origins to blame plumbing. Worktree
blame includes `MERGE_HEAD` and tracks each parent's rename source, allowing
incoming lines and local resolutions to retain their proper attribution.
Repository objects and the index remain unchanged.

Validated full blame suites and worktree comparisons against Git, including
renamed merge paths, local resolutions and malformed merge metadata.

Model: Astra 6.0
Support explicit ignored commits in plumbing and `blame.ignoreRevsFile` in
porcelain. Reassign changed lines using ordered byte-pair similarity, retain
unmatched additions, and expose factual ignored/unblamable line sets.

Validated seven oracle tests spanning fuzzy changes, merges, renames, ranges,
annotated tags, config resets and malformed or missing inputs. Attribution
matches Git; stale merge markers and sorted-reset behavior are intentionally
not reproduced. Minimal-feature check and targeted Clippy pass.

Model: Astra 6.0
A commit can be reached through more than one source path. Scope attribution
and cached entries to each origin, revisit deferred paths, resolve root
hunks independently, and keep different filenames out of coalesced ranges.

The regression first reproduced a wrong originating filename. Full blame
suites, eleven porcelain blame tests, seven ignored-revision tests and strict
Clippy now pass; independent review found no blocking issue.

Model: Astra 6.0
Expand the synthetic index through existing tree APIs in the in-memory
object overlay before rename detection. This permits worktree blame with
unrelated sparse directories while preserving the persisted sparse index.

The regression failed before the fix; native attribution now matches Git
and leaves index bytes and on-disk object counts unchanged. Clippy passes.

Model: Astra 6.0
Default the added blame options in the Gitoxide CLI and integration caller.
Keep the sender-hook callback inline, permit its intentional type complexity,
and correct formatting and a redundant test borrow.

Validated Gitoxide all-target checking and strict all-target Clippy across
the affected crates with object maintenance, HTTP and both hash variants.
These corrections are appended to preserve the published grix ancestry.

Model: Astra 6.0
The grix credential frontend needs Git-compatible askpass prompts and
credential responses. Quote the URL in prompts and retain authentication
challenges when credentials came from a prompt. Completed helper responses
still clear those challenges.

The behavior is covered by Git's t0302 and lib-credential.sh at
6de20f6092dcf9bdb1c8efe03db4b70c82b423dd. Both regressions failed before the
fix. Validation: cargo test --locked -p gix-credentials with
GIX_TEST_IGNORE_ARCHIVES=1; 1 unit, 99 integration and 6 program tests pass.
Provide an optional column renderer for grix's Git-compatible column command
and other listing frontends. Support column/row traversal, dense widths,
custom separators, ANSI colors, Unicode display widths and I/O errors.
Bound row/column dimensions by the input length and handle zero-width cells.

Behavior independently implemented from Git's column interface and t9002 at
6de20f6092dcf9bdb1c8efe03db4b70c82b423dd. Differential checks covered invalid
UTF-8, ANSI colors, emoji and control widths. Public API tests cover these
cases, dense layout, narrow/zero/max widths, and failed output writes.

Validation: cargo test --locked -p gix-utils --features column (35 tests)
and cargo clippy --locked -p gix-utils --features column --all-targets --
-D warnings, with GIX_TEST_IGNORE_ARCHIVES=1 for tests.
Expose a constructor for credential command input that expands each URL in
place. Later fields override those components, and a later URL resets the
earlier fields. Keep the existing lossless context decoder unchanged and
reuse literal credential URL decoding from the native helper implementation.

This prevents grix from selecting credentials for a host overridden later in
the request. Validate every field, including fields superseded by a URL,
before considering credentials usable.

Two regressions failed before the change. Comparisons use git credential
fill from Git 6de20f6092dcf9bdb1c8efe03db4b70c82b423dd, including URL reset,
field ordering, literal components and blank termination. Validation:
cargo test --locked -p gix-credentials with GIX_TEST_IGNORE_ARCHIVES=1 and
the pinned Git on PATH; 1 unit, 101 integration and 6 program tests passed.
Let applications select the Git-compatible executable used when a builtin
credential helper needs a subprocess, including shell-expanded store/cache
arguments. Static native helper handling remains in-process and existing
callers retain their default Git discovery.

Grix supplies its own executable so a dynamic helper cannot fall back to
C Git from PATH. An isolated dispatcher test fails with an empty PATH before
the fix and now covers credential and dynamic native helper invocations.

Validation: cargo test --locked -p gix-credentials with
GIX_TEST_IGNORE_ARCHIVES=1 and pinned Git on PATH; 1 unit, 102 integration,
and 6 program tests passed. Git reference:
6de20f6092dcf9bdb1c8efe03db4b70c82b423dd, credential helper interfaces.
Propagate malformed commit-tree and tag-target decoding errors instead of
panicking. Grix's cat-file adapter accepts untrusted object contents and
must return a fatal command error while preserving normal peeling behavior.

A focused regression reproduced the panic before the change. Pinned Git
6de20f6092dcf9bdb1c8efe03db4b70c82b423dd rejects equivalent malformed objects
with cat-file exit 128 and no object output.

Validation: cargo test --locked -p gix --no-default-features
--features sha1,index --test gix object:: with GIX_TEST_IGNORE_ARCHIVES=1;
44 tests passed.
Git's t0302 leaves a credential file unreadable, then truncates it before
storing again. Treat an empty regular file as containing no entries when
read access is denied, allowing the locked rewrite to publish a private,
readable replacement. Continue refusing to replace nonempty unreadable files.

The isolated regression reproduced PermissionDenied before the change and
compares store/erase results with pinned Git. Validation: cargo test --locked
-p gix-credentials with GIX_TEST_IGNORE_ARCHIVES=1 and pinned Git on PATH;
1 unit, 103 integration and 6 program tests passed. Reference:
6de20f6092dcf9bdb1c8efe03db4b70c82b423dd, t0302 cases 56-58.
Pinned source builds without release tags can report git version 2.56.GIT.
Recognize that patch component as zero so version-gated fixtures can use the
same pinned reference as grix compatibility suites. Retain numeric release,
release-candidate, commit and vendor suffix behavior.

The new regression failed on the pinned version before this fix. Validation:
three version parser tests plus the focused Bash version-gate integration
test pass with Git 6de20f6092dcf9bdb1c8efe03db4b70c82b423dd on PATH.
The grix credential frontends must accept Git's request framing without waiting
for stdin to close. Expose `protocol::read()` and use it in the existing helper
entrypoint, preserving LF/CRLF terminators and propagating earlier I/O errors.

A deterministic regression supplies a complete request followed by an error if
the reader tries to reach EOF. It failed before the change and now passes.
Full `gix-credentials` validation passed: 1 unit, 104 integration, 6 program tests.

Reference: isolated probes of `credential fill` from Git
`6de20f6092dcf9bdb1c8efe03db4b70c82b423dd` (`2.56.GIT`), keeping stdin open
after sending complete fields and an empty line.
The grix config frontend exposed a platform difference while validating against
its pinned Git build: Darwin libc ERE rejects GNU nested repetitions and empty
alternatives, treats GNU escapes literally, and selects captures differently.
Keep the default GNU behavior and expose an explicit `Dialect::Darwin` for
callers matching Git's libc ERE and enhanced BRE conventions in the C locale.

Retain every native Git comparison assertion, selecting the corresponding
platform dialect, and add ten fixtures plus five host-independent Darwin tests.
The existing GNU tests remain unchanged. The failing syntax/capture regressions
now pass along with all 51 `gix-regex` tests, all-targets Clippy, and a `no_std`
library build.

Reference: Git `6de20f6092dcf9bdb1c8efe03db4b70c82b423dd` (`2.56.GIT`),
config regex selection and diff hunk-header fixtures; Darwin's Git build uses
libc ERE and `compat/regcomp_enhanced.c` for BRE. Validation used the pinned
binary on PATH and regenerated fixtures with `GIX_TEST_IGNORE_ARCHIVES=1`.
Malformed credential helper output can reach an application's diagnostic printer.
Errors previously retained full values and input metadata, exposing passwords or
refresh tokens whenever a delimiter or UTF-8 validation failed. Keep the failure
reason while omitting untrusted field bytes from both decoding and encoding errors.

The regression reproduces the leak and checks Display and Debug formatting for
malformed secrets, malformed keys, and lines without separators. Update the
existing diagnostic snapshots without changing their validation assertions.
Full `gix-credentials` validation passed: 1 unit, 105 integration, 6 program tests.

Discovered during grix credential frontend review after complete t0302 coverage
against Git `6de20f6092dcf9bdb1c8efe03db4b70c82b423dd` (`2.56.GIT`).
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