Remove winnow from gix-actor public API#2546
Merged
Sebastian Thiel (Byron) merged 12 commits intomainfrom Apr 27, 2026
Merged
Conversation
e151dda to
beb8963
Compare
1 task
It's replaced with `BStrSlice::find_byte` which is the same under the hood.
beb8963 to
3a29507
Compare
…erywhere. This will allow for simplified maintenance and editing (both human and machine) down the road, and enable additional performance optimisations. Parser compbinators to me ultimately were a failed experiment as I couldn't maintain them anyway, with it being too difficult for me to grasp and express everything in its very own kind of language, with a lot of different things to consider. Note that this also removes detailed errors from all parsers that previously used `winnow`, with the option to re-add those if there is demand. Co-authored-by: Sebastian Thiel <sebastian.thiel@icloud.com>
3a29507 to
ec7ff5a
Compare
This improves Git conformity, which is also pretty lenient. Co-authored-by: Sebastian Thiel <sebastian.thiel@icloud.com>
ec7ff5a to
41ce55c
Compare
There was a problem hiding this comment.
Pull request overview
This PR removes winnow from the public API surface (notably gix-actor) and replaces parser-combinator based parsing with imperative, cursor-oriented parsers across multiple crates. As part of the refactor, object parsing APIs are updated to require an explicit gix_hash::Kind so commit/tag parsing can validate SHA-1 vs SHA-256 object-id sizes correctly.
Changes:
- Replace
winnow-based parsers with manual cursor parsers ingix-actor,gix-object,gix-ref,gix-protocol, andgix-config, and removewinnowdependencies. - Thread
gix_hash::Kindinto commit/tag parsing entry points (and update call sites across crates). - Update tests/fuzz/benches and remove the former “verbose parsing errors” feature plumbing.
Reviewed changes
Copilot reviewed 76 out of 77 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/tools/src/lib.rs | Removes test helper tied to winnow error types. |
| tests/tools/Cargo.toml | Drops winnow dependency from test tools crate. |
| justfile | Removes verbose-object-parsing-errors checks and updates gix-object test invocations. |
| gix/src/object/tag.rs | Passes object hash kind into gix_object tag parsing APIs. |
| gix/src/object/commit.rs | Passes object hash kind into gix_object commit parsing APIs. |
| gix/Cargo.toml | Removes verbose-object-parsing-errors feature wiring from gix. |
| gix-traverse/src/commit/simple.rs | Tracks current object hash kind to parse buffered commits correctly. |
| gix-revwalk/src/graph/mod.rs | Stores hash kind in LazyCommit to parse ODB-backed commits correctly. |
| gix-revwalk/src/graph/commit.rs | Uses stored hash kind when parsing commit bytes. |
| gix-ref/tests/refs/file/reference.rs | Adds coverage for uppercase hex ids in ref parsing. |
| gix-ref/src/store/packed/transaction.rs | Threads hash_kind into tag peeling when resolving packed refs. |
| gix-ref/src/store/packed/iter.rs | Replaces winnow-based packed-refs parsing with imperative parsing. |
| gix-ref/src/store/packed/find.rs | Replaces winnow parsing in packed-refs lookup with imperative parsing. |
| gix-ref/src/store/packed/decode/tests.rs | Updates packed-refs decode tests to new imperative parsing APIs and adds uppercase coverage. |
| gix-ref/src/store/packed/decode.rs | Reimplements packed-refs header/reference decoding without winnow. |
| gix-ref/src/store/packed/buffer.rs | Adjusts packed-refs header parsing and offset computation without winnow. |
| gix-ref/src/store/file/raw_ext.rs | Threads hash_kind into tag peeling for loose refs. |
| gix-ref/src/store/file/loose/reference/decode.rs | Replaces winnow parsing for loose refs with an imperative parser. |
| gix-ref/src/store/file/log/line.rs | Reimplements reflog line parsing without winnow. |
| gix-ref/src/parse.rs | Introduces shared imperative helpers for parsing hex ids and newlines. |
| gix-ref/Cargo.toml | Drops winnow dependency from gix-ref. |
| gix-protocol/src/remote_progress.rs | Reimplements remote progress parsing without winnow. |
| gix-protocol/Cargo.toml | Drops winnow dependency from gix-protocol. |
| gix-path/tests/path/realpath.rs | Adjusts fuzzed timeout threshold on Windows. |
| gix-pack/src/data/output/count/objects/mod.rs | Passes hash_kind into commit/tag iterators while expanding objects. |
| gix-object/tests/object/tree/from_bytes.rs | Simplifies invalid-tree assertions after error-type change. |
| gix-object/tests/object/tag.rs | Updates tag tests for explicit hash kind; adds sha256/uppercase/PGP edge cases. |
| gix-object/tests/object/main.rs | Adds fixture rewriting helpers for commit/tag in sha256 test runs. |
| gix-object/tests/object/encode.rs | Updates round-trip tests to use hash-kind aware fixture loading and parsing. |
| gix-object/tests/object/commit/mod.rs | Updates commit tests for explicit hash kind and simplified error assertions. |
| gix-object/tests/object/commit/iter.rs | Updates commit iterator tests for explicit hash kind and signature API change. |
| gix-object/tests/object/commit/from_bytes.rs | Adds sha256/uppercase coverage; updates parsing calls to pass hash kind. |
| gix-object/src/tree/ref_iter.rs | Removes winnow error plumbing from tree iteration error reporting. |
| gix-object/src/tag/ref_iter.rs | Updates tag iterator API to require hash kind; removes winnow dependency. |
| gix-object/src/tag/mod.rs | Updates TagRef::from_bytes() signature to require hash kind. |
| gix-object/src/tag/decode.rs | Reimplements tag parsing + PGP signature detection without winnow. |
| gix-object/src/parse.rs | Reimplements shared object parsing utilities without winnow. |
| gix-object/src/object/mod.rs | Threads hash_kind into commit/tag object parsing in ObjectRef. |
| gix-object/src/lib.rs | Updates ref iterators to carry hash kind; simplifies decode error type. |
| gix-object/src/data.rs | Threads hash_kind into commit/tag parsing + iter creation in Data. |
| gix-object/src/commit/ref_iter.rs | Updates commit iterator API to require hash kind; removes winnow dependency. |
| gix-object/src/commit/mod.rs | Updates CommitRef::from_bytes() signature to require hash kind; threads kind into mergetag parsing. |
| gix-object/src/commit/message/mod.rs | Renames message decode entry point used by MessageRef. |
| gix-object/src/commit/message/decode.rs | Reimplements title/body splitting without winnow. |
| gix-object/src/commit/decode.rs | Reimplements full commit parsing + message parsing without winnow. |
| gix-object/fuzz/fuzz_targets/fuzz_tag.rs | Runs tag fuzz parsing for both SHA-1 and SHA-256. |
| gix-object/fuzz/fuzz_targets/fuzz_commit.rs | Runs commit fuzz parsing for both SHA-1 and SHA-256. |
| gix-object/benches/decode_objects.rs | Updates benches to pass explicit hash kind into parsing APIs. |
| gix-object/Cargo.toml | Removes winnow dep and removes verbose-object-parsing-errors feature. |
| gix-mailmap/src/lib.rs | Updates docs/examples to new SignatureRef::from_bytes() signature. |
| gix-mailmap/fuzz/fuzz_targets/mailmap.rs | Updates fuzz target to new SignatureRef::from_bytes() signature. |
| gix-imara-diff/src/sources.rs | Removes memchr usage by switching to bstr::ByteSlice::find_byte. |
| gix-imara-diff/Cargo.toml | Drops memchr dependency. |
| gix-config/tests/config/file/access/raw/set_existing_raw_value.rs | Adds test for global properties using empty section name. |
| gix-config/tests/config/file/access/raw/raw_value.rs | Adds test for global properties using empty section name. |
| gix-config/src/types.rs | Updates docs to reflect that git accepts global properties before first section. |
| gix-config/src/parse/tests.rs | Adds tests for edge-case section headers and event writing behavior. |
| gix-config/src/parse/nom/mod.rs | Removes the prior winnow-based config parser implementation. |
| gix-config/src/parse/mod.rs | Switches parser entry point to the new from_bytes module. |
| gix-config/src/parse/from_bytes/tests.rs | Adds extensive tests for the new imperative config parser. |
| gix-config/src/parse/from_bytes/mod.rs | New imperative, cursor-oriented config parser implementation. |
| gix-config/src/parse/events.rs | Updates docs to match new parser behavior for global properties. |
| gix-config/src/lib.rs | Adjusts crate-level deny lints after parser refactor. |
| gix-config/src/file/mutable/mod.rs | Makes escape_value() pub(crate) for broader internal use. |
| gix-config/Cargo.toml | Drops winnow and memchr dependencies. |
| gix-actor/tests/actor/signature.rs | Updates tests to new SignatureRef::from_bytes() signature/error type. |
| gix-actor/tests/actor/identity.rs | Updates tests to new IdentityRef::from_bytes() signature/error type. |
| gix-actor/src/signature/mod.rs | Changes public parsing API to return gix_error::ValidationError; adds consuming parser. |
| gix-actor/src/signature/decode.rs | Reimplements signature parsing without winnow and updates error handling. |
| gix-actor/src/lib.rs | Updates docs/examples to new signature/identity parsing API. |
| gix-actor/src/identity.rs | Changes public parsing API to return gix_error::ValidationError; adds consuming parser. |
| gix-actor/fuzz/fuzz_targets/actors.rs | Updates fuzz target to new parsing APIs. |
| gix-actor/Cargo.toml | Drops winnow dependency from gix-actor. |
| gitoxide-core/src/repository/mailmap.rs | Updates identity parsing calls to new API. |
| gitoxide-core/src/query/engine/update.rs | Threads hash_kind into commit parsing when extracting parents. |
| gitoxide-core/src/hours/mod.rs | Threads hash_kind into commit parsing for trailer/author extraction. |
| Cargo.lock | Removes winnow (and memchr where applicable) from the lockfile dependency graph. |
Doing so adds conformity with Git, but also simplifies the parser which now only parse hex-hashes of a single valid length. Co-authored-by: Sebastian Thiel <sebastian.thiel@icloud.com>
03c73f7 to
5d9939c
Compare
Co-authored-by: Sebastian Thiel <sebastian.thiel@icloud.com>
5d9939c to
91bfab0
Compare
a55d029 to
7ae8bf6
Compare
This predominantly restricts parsing so it won't allow any hash but the one that was passed. Co-authored-by: Sebastian Thiel <sebastian.thiel@icloud.com>
Co-authored-by: Sebastian Thiel <sebastian.thiel@icloud.com>
7ae8bf6 to
87b2da8
Compare
Mere convenience. Co-authored-by: Sebastian Thiel <sebastian.thiel@icloud.com>
… tests - update some fixture so ci-tests at least pass locally - maybe this removes one more source of flake?
26dcdbe to
09687eb
Compare
…th v0.12.0, gix-features v0.48.0, gix-hash v0.25.0, gix-hashtable v0.15.0, gix-object v0.60.0, gix-glob v0.26.0, gix-attributes v0.33.0, gix-command v0.9.0, gix-filter v0.30.0, gix-fs v0.21.0, gix-commitgraph v0.37.0, gix-revwalk v0.31.0, gix-traverse v0.57.0, gix-worktree-stream v0.32.0, gix-archive v0.32.0, gix-tempfile v23.0.0, gix-lock v23.0.0, gix-index v0.51.0, gix-config-value v0.18.0, gix-pathspec v0.18.0, gix-ignore v0.21.0, gix-worktree v0.52.0, gix-imara-diff v0.2.1, gix-diff v0.63.0, gix-blame v0.13.0, gix-ref v0.63.0, gix-sec v0.14.0, gix-config v0.56.0, gix-prompt v0.15.0, gix-url v0.36.0, gix-credentials v0.38.0, gix-discover v0.51.0, gix-dir v0.25.0, gix-mailmap v0.33.0, gix-revision v0.45.0, gix-merge v0.16.0, gix-negotiate v0.31.0, gix-pack v0.70.0, gix-odb v0.80.0, gix-refspec v0.41.0, gix-shallow v0.12.0, gix-transport v0.57.0, gix-protocol v0.61.0, gix-status v0.30.0, gix-submodule v0.30.0, gix-worktree-state v0.30.0, gix v0.83.0, gix-fsck v0.21.0, gitoxide-core v0.57.0, gitoxide v0.53.0, safety bump 48 crates SAFETY BUMP: gix-features v0.48.0, gix-hash v0.25.0, gix-hashtable v0.15.0, gix-object v0.60.0, gix-glob v0.26.0, gix-attributes v0.33.0, gix-command v0.9.0, gix-filter v0.30.0, gix-fs v0.21.0, gix-commitgraph v0.37.0, gix-revwalk v0.31.0, gix-traverse v0.57.0, gix-worktree-stream v0.32.0, gix-archive v0.32.0, gix-tempfile v23.0.0, gix-lock v23.0.0, gix-index v0.51.0, gix-config-value v0.18.0, gix-pathspec v0.18.0, gix-ignore v0.21.0, gix-worktree v0.52.0, gix-diff v0.63.0, gix-blame v0.13.0, gix-ref v0.63.0, gix-sec v0.14.0, gix-config v0.56.0, gix-prompt v0.15.0, gix-url v0.36.0, gix-credentials v0.38.0, gix-discover v0.51.0, gix-dir v0.25.0, gix-mailmap v0.33.0, gix-revision v0.45.0, gix-merge v0.16.0, gix-negotiate v0.31.0, gix-pack v0.70.0, gix-odb v0.80.0, gix-refspec v0.41.0, gix-shallow v0.12.0, gix-transport v0.57.0, gix-protocol v0.61.0, gix-status v0.30.0, gix-submodule v0.30.0, gix-worktree-state v0.30.0, gix v0.83.0, gix-fsck v0.21.0, gitoxide-core v0.57.0, gitoxide v0.53.0
bad I and Codex keep forgetting to run it.
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.
It's too easy to not detect
winnowupdates as a breaking change, and then make patch releases that break existing builds.More importantly, while at it, remove the notion of parser combinators as I found them hard to maintain, and return to simple imperative cursor-oriented parsers.
Tasks
winnowfromgix-actor(as breaking change) + refackiewgix-configfix Unable to add any repository with fresh install of GitButler on MacOS - Unexpected token error gitbutlerapp/gitbutler#8948gixas v0.83 naturally.gix-actor0.40.1 to unbreak v0.81Benches
It turns out that removing
winnowleads to a simpler but faster parser implementation, and it's probably one that I can maintain as well.gix-config
promising as well