Repository navigation
Grix Improvements - #3060
Draft
Sebastian Thiel (Byron) wants to merge 8 commits into
Draft
Grix Improvements#3060Sebastian Thiel (Byron) wants to merge 8 commits into
Sebastian Thiel (Byron) wants to merge 8 commits into
Conversation
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.
Sebastian Thiel (Byron)
force-pushed
the
grix
branch
from
October 14, 2026 03:25
544f551 to
1af1e07
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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.