@@ -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,78 @@ 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
4269- Use ` gix_features::threading::* ` for interior mutability primitives
4370
4471### Path Handling
72+
4573- Paths are byte-oriented in git (even on Windows via MSYS2 abstraction)
4674- Use ` gix::path::* ` utilities to convert git paths (` BString ` ) to ` OsStr ` /` Path ` or use custom types
4775
4876## Building and Testing
4977
5078### Quick Commands
79+
5180- ` just test ` - Run all tests, clippy, journey tests, and try building docs
5281- ` just check ` - Build all code in suitable configurations
5382- ` just clippy ` - Run clippy on all crates
5483- ` cargo test ` - Run unit tests only
5584
5685### Build Variants
86+
5787- ` cargo build --release ` - Default build (big but pretty, ~ 2.5min)
5888- ` cargo build --release --no-default-features --features lean ` - Lean build (~ 1.5min)
5989- ` cargo build --release --no-default-features --features small ` - Minimal deps (~ 46s)
6090
6191### Test Best Practices
92+
6293- Run tests before making changes to understand existing issues
6394- Use ` GIX_TEST_IGNORE_ARCHIVES=1 ` when testing on macOS/Windows
6495- Journey tests validate CLI behavior end-to-end
6596
6697## Architecture Decisions
6798
6899### Plumbing vs Porcelain
100+
69101- ** Plumbing crates** : Low-level, take references, expose mutable parts as arguments
70102- ** Porcelain (gix)** : High-level, convenient, may clone Repository for user convenience
71103- Platforms: cheap to create, keep reference to Repository
72104- Caches: more expensive, clone ` Repository ` or free of lifetimes
73105
74106### Options vs Context
107+
75108- Use ` Options ` for branching behavior configuration (can be defaulted)
76109- Use ` Context ` for data required for operation (cannot be defaulted)
77110
78111## Crate Organization
79112
80113### Common Crates
114+
81115- ` gix ` : Main library entrypoint (porcelain)
82116- ` gix-object ` , ` gix-ref ` , ` gix-config ` : Core git data structures
83117- ` gix-odb ` , ` gix-pack ` : Object database and pack handling
84118- ` gix-diff ` , ` gix-merge ` , ` gix-status ` : Operations
85119- ` gitoxide-core ` : Shared CLI functionality
86120
87121## Documentation
122+
88123- High-level docs: README.md, CONTRIBUTING.md, DEVELOPMENT.md
89124- Crate status: crate-status.md
90125- Stability guide: STABILITY.md
91126- Always update docs if directly related to code changes
92127
93128## CI and Releases
129+
94130- Ubuntu-latest git version is the compatibility target
95131- ` cargo smart-release ` for releases (driven by commit messages)
96132- Split breaking changes into separate commits per affected crate if one commit-message wouldn't be suitable for all changed crates.
97133- First commit: breaking change only; second commit: adaptations
98134
99135## When Suggesting Changes
136+
1001371 . Understand the plumbing vs porcelain distinction
1011382 . Check existing patterns in similar crates
1021393 . Follow error handling conventions strictly
0 commit comments