|
| 1 | +# Copilot Instructions for Gitoxide |
| 2 | + |
| 3 | +This repository contains `gitoxide` - a pure Rust implementation of Git. This document provides guidance for GitHub Copilot when working with this codebase. |
| 4 | + |
| 5 | +## Project Overview |
| 6 | + |
| 7 | +- **Language**: Rust (MSRV documented in gix/Cargo.toml) |
| 8 | +- **Structure**: Cargo workspace with multiple crates (gix-*, gitoxide-core, etc.) |
| 9 | +- **Main crates**: `gix` (library entrypoint), `gitoxide` binary (CLI tools: `gix` and `ein`) |
| 10 | +- **Purpose**: Provide a high-performance, safe Git implementation with both library and CLI interfaces |
| 11 | + |
| 12 | +## Development Practices |
| 13 | + |
| 14 | +### Test-First Development |
| 15 | +- Protect against regression and make implementing features easy |
| 16 | +- Use containers to test elaborate user interactions |
| 17 | +- Keep it practical - the Rust compiler handles mundane things |
| 18 | +- Use git itself as reference implementation; run same tests against git where feasible |
| 19 | +- Never use `.unwrap()`, not even in tests. Use `quick_error!()` or `Box<dyn std::error::Error>` instead |
| 20 | +- Use `.expect("why")` with context explaining why expectations should hold |
| 21 | + |
| 22 | +### Error Handling |
| 23 | +- Handle all errors, never `unwrap()` |
| 24 | +- Provide error chains making it easy to understand what went wrong |
| 25 | +- Use `thiserror` for libraries generally |
| 26 | +- Binaries may use `anyhow::Error` exhaustively (user-facing errors) |
| 27 | + |
| 28 | +### Commit Messages |
| 29 | +Follow "purposeful conventional commits" style: |
| 30 | +- Use conventional commit prefixes ONLY if message should appear in changelog |
| 31 | +- Breaking changes MUST use suffix `!`: `change!:`, `remove!:`, `rename!:` |
| 32 | +- Features/fixes visible to users: `feat:`, `fix:` |
| 33 | +- Refactors/chores: no prefix (don't affect users) |
| 34 | +- Examples: |
| 35 | + - `feat: add Repository::foo() to do great things. (#234)` |
| 36 | + - `fix: don't panic when calling foo() in a bare repository. (#456)` |
| 37 | + - `change!: rename Foo to Bar. (#123)` |
| 38 | + |
| 39 | +### Code Style |
| 40 | +- Follow existing patterns in the codebase |
| 41 | +- Use `gix_hash::ObjectId` and `gix_hash::oid` to prepare for SHA256 support |
| 42 | +- No `.unwrap()` - use `.expect("context")` with clear reasoning |
| 43 | +- Prefer references in plumbing crates to avoid expensive clones |
| 44 | +- Use `gix_features::threading::*` for interior mutability primitives |
| 45 | + |
| 46 | +### Async Usage |
| 47 | +- Provide async clients as opt-in using feature toggles |
| 48 | +- Server-side: support async out of the box with conditional compilation |
| 49 | +- Use `blocking` to make `Read` and `Iterator` async when needed |
| 50 | +- Long-running operations support interruption via `gix_features::interrupt` |
| 51 | + |
| 52 | +### Path Handling |
| 53 | +- Paths are byte-oriented in git (even on Windows via MSYS2 abstraction) |
| 54 | +- Use `os_str_bytes` to convert git paths to `OsStr`/`Path` or use custom types |
| 55 | + |
| 56 | +## Building and Testing |
| 57 | + |
| 58 | +### Quick Commands |
| 59 | +- `just test` - Run all tests, clippy, journey tests, and try building docs |
| 60 | +- `just check` - Build all code in suitable configurations |
| 61 | +- `just clippy` - Run clippy on all crates |
| 62 | +- `cargo test` - Run unit tests only |
| 63 | + |
| 64 | +### Build Variants |
| 65 | +- `cargo build --release` - Default build (big but pretty, ~2.5min) |
| 66 | +- `cargo build --release --no-default-features --features lean` - Lean build (~1.5min) |
| 67 | +- `cargo build --release --no-default-features --features small` - Minimal deps (~46s) |
| 68 | + |
| 69 | +### Test Best Practices |
| 70 | +- Run tests before making changes to understand existing issues |
| 71 | +- Use `GIX_TEST_IGNORE_ARCHIVES=1` when testing on macOS/Windows |
| 72 | +- Journey tests validate CLI behavior end-to-end |
| 73 | + |
| 74 | +## Architecture Decisions |
| 75 | + |
| 76 | +### Plumbing vs Porcelain |
| 77 | +- **Plumbing crates**: Low-level, take references, expose mutable parts as arguments |
| 78 | +- **Porcelain (gix)**: High-level, convenient, may clone Repository for user convenience |
| 79 | +- Platforms: cheap to create, keep reference to Repository |
| 80 | +- Caches: more expensive, clone Repository or free of lifetimes |
| 81 | + |
| 82 | +### Options vs Context |
| 83 | +- Use `Options` for branching behavior configuration (can be defaulted) |
| 84 | +- Use `Context` for data required for operation (cannot be defaulted) |
| 85 | + |
| 86 | +### Default Trait Implementations |
| 87 | +- Can change only if effect is contained within caller's process |
| 88 | +- Changing default file version is a breaking change |
| 89 | + |
| 90 | +## Crate Organization |
| 91 | + |
| 92 | +### Stability Tiers |
| 93 | +1. **Production Grade** (Tier 1-2): `gix-lock`, `gix-tempfile` |
| 94 | +2. **Stabilization Candidates**: Feature-complete, need more use before 1.0 |
| 95 | +3. **Initial Development**: Usable but possibly incomplete |
| 96 | +4. **Very Early/Idea**: Minimal implementation or placeholders |
| 97 | + |
| 98 | +### Common Crates |
| 99 | +- `gix`: Main library entrypoint (porcelain) |
| 100 | +- `gix-object`, `gix-ref`, `gix-config`: Core git data structures |
| 101 | +- `gix-odb`, `gix-pack`: Object database and pack handling |
| 102 | +- `gix-diff`, `gix-merge`, `gix-status`: Operations |
| 103 | +- `gitoxide-core`: Shared CLI functionality |
| 104 | + |
| 105 | +## Documentation |
| 106 | +- High-level docs: README.md, CONTRIBUTING.md, DEVELOPMENT.md |
| 107 | +- Crate status: crate-status.md |
| 108 | +- Stability guide: STABILITY.md |
| 109 | +- Always update docs if directly related to code changes |
| 110 | + |
| 111 | +## CI and Releases |
| 112 | +- Ubuntu-latest git version is the compatibility target |
| 113 | +- `cargo smart-release` for releases (driven by commit messages) |
| 114 | +- Split breaking changes into separate commits per affected crate |
| 115 | +- First commit: breaking change only; second commit: adaptations |
| 116 | + |
| 117 | +## When Suggesting Changes |
| 118 | +1. Understand the plumbing vs porcelain distinction |
| 119 | +2. Check existing patterns in similar crates |
| 120 | +3. Follow error handling conventions strictly |
| 121 | +4. Ensure changes work with feature flags (small, lean, max, max-pure) |
| 122 | +5. Consider impact on both library and CLI users |
| 123 | +6. Test against real git repositories when possible |
0 commit comments