@@ -5,27 +5,53 @@ This repository contains `gitoxide` - a pure Rust implementation of Git. This do
55## Project Overview
66
77- ** Language** : Rust (MSRV documented in gix/Cargo.toml)
8- - ** Structure** : Cargo workspace with multiple crates (gix-* , gitoxide-core, etc.)
8+ - ** Structure** : Cargo workspace with multiple crates (gix-\ * , gitoxide-core, etc.)
99- ** Main crates** : ` gix ` (library entrypoint), ` gitoxide ` binary (CLI tools: ` gix ` and ` ein ` )
1010- ** Purpose** : Provide a high-performance, safe Git implementation with both library and CLI interfaces
1111
1212## Development Practices
1313
1414### Test-First Development
15+
1516- Protect against regression and make implementing features easy
1617- Keep it practical - the Rust compiler handles mundane things
1718- Use git itself as reference implementation; run same tests against git where feasible
1819- Never use ` .unwrap() ` in production code, avoid it in tests in favor of ` .expect() ` or ` ? ` . Use ` gix_testtools::Result ` most of the time.
1920- Use ` .expect("why") ` with context explaining why expectations should hold, but only if it's relevant to the test.
2021
2122### Error Handling
23+
2224- Handle all errors, never ` unwrap() `
2325- Provide error chains making it easy to understand what went wrong
24- - Use ` thiserror ` for libraries generally
2526- Binaries may use ` anyhow::Error ` exhaustively (user-facing errors)
2627
28+ #### ` gix-error ` (preferred for plumbing crates)
29+
30+ Plumbing crates are migrating from ` thiserror ` enums to ` gix-error ` . Check whether a crate already
31+ uses ` gix-error ` (look at its ` Cargo.toml ` ); if it does, follow the patterns below. If it still uses
32+ ` thiserror ` , keep using ` thiserror ` for consistency within that crate.
33+
34+ - ** Error type alias** : ` pub type Error = gix_error::Exn<gix_error::Message>; `
35+ - ** Static messages** : ` gix_error::message("something failed") `
36+ - ** Formatted messages** : ` gix_error::message!("failed to read {path}") `
37+ - ** Wrapping callee errors with context** : ` .or_raise(|| message("context about what failed"))? `
38+ - ** Standalone error (no callee)** : ` Err(message("something went wrong").raise()) `
39+ - ** Wrapping an ` impl Error ` with context** : ` err.and_raise(message("context")) `
40+ - ** Closure/callback bounds** : use ` Result<T, Exn> ` (bare), not ` Exn<Message> ` ;
41+ inside the function, convert with ` .or_raise(|| message("..."))? ` ;
42+ inside the closure, convert typed to bare with ` .or_erased() `
43+ - ** ` Exn<E> ` does NOT implement ` std::error::Error ` ** — this is by design.
44+ - To convert: use ` .into_error() ` to get ` gix_error::Error ` (which does implement ` std::error::Error ` )
45+ - Example: ` std::io::Error::other(exn.into_error()) `
46+ - ** In tests** returning ` gix_testtools::Result ` (= ` Result<(), Box<dyn Error>> ` ), ` Exn ` can't be used
47+ with ` ? ` directly — use ` .map_err(|e| e.into_error())? `
48+ - ** Common imports** : ` use gix_error::{message, ErrorExt, ResultExt}; `
49+ - See ` gix-error/src/lib.rs ` module docs for a full migration guide from ` thiserror `
50+
2751### Commit Messages
52+
2853Follow "purposeful conventional commits" style:
54+
2955- Use conventional commit prefixes ONLY if message should appear in changelog
3056- Breaking changes MUST use suffix ` ! ` : ` change!: ` , ` remove!: ` , ` rename!: `
3157- Features/fixes visible to users: ` feat: ` , ` fix: `
@@ -36,67 +62,79 @@ Follow "purposeful conventional commits" style:
3662 - ` change!: rename Foo to Bar. (#123) `
3763
3864### Code Style
65+
3966- Follow existing patterns in the codebase
4067- No ` .unwrap() ` - use ` .expect("context") ` if you are sure this can't fail.
4168- Prefer references in plumbing crates to avoid expensive clones
69+ - Avoid calling ` .detach() ` unless an owned value is explicitly required. Many ` gix ` APIs accept attached ids and references directly, so prefer keeping repository-backed handles like ` gix::Id ` when possible.
4270- Use ` gix_features::threading::* ` for interior mutability primitives
4371
4472### Path Handling
73+
4574- Paths are byte-oriented in git (even on Windows via MSYS2 abstraction)
4675- Use ` gix::path::* ` utilities to convert git paths (` BString ` ) to ` OsStr ` /` Path ` or use custom types
4776
4877## Building and Testing
4978
5079### Quick Commands
80+
5181- ` just test ` - Run all tests, clippy, journey tests, and try building docs
5282- ` just check ` - Build all code in suitable configurations
5383- ` just clippy ` - Run clippy on all crates
5484- ` cargo test ` - Run unit tests only
5585
5686### Build Variants
87+
5788- ` cargo build --release ` - Default build (big but pretty, ~ 2.5min)
5889- ` cargo build --release --no-default-features --features lean ` - Lean build (~ 1.5min)
5990- ` cargo build --release --no-default-features --features small ` - Minimal deps (~ 46s)
6091
6192### Test Best Practices
93+
6294- Run tests before making changes to understand existing issues
6395- Use ` GIX_TEST_IGNORE_ARCHIVES=1 ` when testing on macOS/Windows
6496- Journey tests validate CLI behavior end-to-end
6597
6698## Architecture Decisions
6799
68100### Plumbing vs Porcelain
101+
69102- ** Plumbing crates** : Low-level, take references, expose mutable parts as arguments
70103- ** Porcelain (gix)** : High-level, convenient, may clone Repository for user convenience
71104- Platforms: cheap to create, keep reference to Repository
72105- Caches: more expensive, clone ` Repository ` or free of lifetimes
73106
74107### Options vs Context
108+
75109- Use ` Options ` for branching behavior configuration (can be defaulted)
76110- Use ` Context ` for data required for operation (cannot be defaulted)
77111
78112## Crate Organization
79113
80114### Common Crates
115+
81116- ` gix ` : Main library entrypoint (porcelain)
82117- ` gix-object ` , ` gix-ref ` , ` gix-config ` : Core git data structures
83118- ` gix-odb ` , ` gix-pack ` : Object database and pack handling
84119- ` gix-diff ` , ` gix-merge ` , ` gix-status ` : Operations
85120- ` gitoxide-core ` : Shared CLI functionality
86121
87122## Documentation
123+
88124- High-level docs: README.md, CONTRIBUTING.md, DEVELOPMENT.md
89125- Crate status: crate-status.md
90126- Stability guide: STABILITY.md
91127- Always update docs if directly related to code changes
92128
93129## CI and Releases
130+
94131- Ubuntu-latest git version is the compatibility target
95132- ` cargo smart-release ` for releases (driven by commit messages)
96133- Split breaking changes into separate commits per affected crate if one commit-message wouldn't be suitable for all changed crates.
97134- First commit: breaking change only; second commit: adaptations
98135
99136## When Suggesting Changes
137+
1001381 . Understand the plumbing vs porcelain distinction
1011392 . Check existing patterns in similar crates
1021403 . Follow error handling conventions strictly
0 commit comments