https://github.com/warriorssami/bit
A lil' Bit of Git
https://github.com/warriorssami/bit
dsa git tdd
Last synced: 2 months ago
JSON representation
A lil' Bit of Git
- Host: GitHub
- URL: https://github.com/warriorssami/bit
- Owner: WarriorsSami
- Created: 2025-01-18T19:26:17.000Z (over 1 year ago)
- Default Branch: master
- Last Pushed: 2026-04-15T21:15:49.000Z (3 months ago)
- Last Synced: 2026-04-15T23:23:06.534Z (3 months ago)
- Topics: dsa, git, tdd
- Language: Rust
- Homepage:
- Size: 484 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Agents: AGENTS.md
Awesome Lists containing this project
README
# Bit - Just a lil' bit of Git in Rust
A Git implementation written in Rust, inspired by James Coglan’s book ["Building Your Own Git"](https://shop.jcoglan.com/building-git/). `bit` is intentionally educational, but it is built with production-style engineering discipline: explicit domain modeling, invariant-driven design, and a strong test suite.
## Overview
`bit` models Git as interactions between four core areas:
- **Object database** (`.git/objects`): immutable content-addressed objects.
- **Index** (`.git/index`): staging-area metadata and next-tree blueprint.
- **References** (`.git/HEAD`, `refs/*`): symbolic and direct pointers into history.
- **Workspace**: mutable files checked out for editing.
Most command behavior can be reasoned about as transitions across these areas.
## Implemented Commands
- ✅ `bit init`
- ✅ `bit hash-object`
- ✅ `bit ls-tree`
- ✅ `bit add`
- ✅ `bit commit`
- ✅ `bit status`
- ✅ `bit diff`
- ✅ `bit branch` (create/list/delete)
- ✅ `bit checkout`
- ✅ `bit log`
- ✅ `bit merge` (multi-scenario DAG merges, conflict-aware behavior)
## Domain Models and Invariants
### 1) Object model
- Supports Git object categories needed by current commands (blob/tree/commit flows).
- Serialization follows Git format: ` \0`.
- Object IDs are SHA-1 of serialized object bytes.
- Objects are immutable once written.
### 2) Index model
- Entries are deterministically ordered.
- Header entry count reflects serialized entries.
- Index checksum verifies integrity.
- Parent/child path conflicts are normalized when replacing file/dir shapes.
- Index read/write uses locking semantics to maintain consistency under concurrent operations.
### 3) Revision + refs model
- Branch and revision parsing supports common forms (`ref`, `^`, `~n`, aliases).
- Branch name validation follows Git-like constraints and explicit parser rules.
- HEAD and refs are managed as first-class repository state.
### 4) Merge and graph model
- Merge behavior is validated on multiple non-trivial commit DAGs.
- Best common ancestor scenarios and branching edge-cases are covered by integration tests.
### 5) Diff and patch model
- Diff endpoints are explicit (`workspace↔index`, `index↔HEAD`, `rev↔rev`).
- File-level status (`A`,`D`,`M`, mode-only changes) is deterministic.
- Patch hunks should remain stable in ordering and context output semantics.
### 6) Log traversal model
- Traversal honors included and excluded revision expressions.
- Commit output ordering should be deterministic, including tie-breaking for identical timestamps.
- Decorations are a read-only projection of current refs over commits.
### 7) Checkout migration model
- Checkout is a controlled migration between revisions across refs, index, and workspace.
- Safety checks should prevent silent clobbering of local/staged work.
- Success means workspace/index are synchronized to target tree semantics.
### 8) Core algorithms and data structures
- **Merkle DAG** for commit/history integrity and reachability.
- **Tree/index path hierarchy (trie-like)** for parent/child path operations.
- **Revision AST** to represent references, parent (`^`), ancestor (`~n`), ranges, and exclusions.
- **Myers-style diff baseline** for minimal edit script patch construction (future enhancements may refine heuristics).
- **Binary codec discipline** for future wire protocol framing and pack parsing.
## Rust Engineering Practices
This project emphasizes:
- idiomatic ownership and borrowing,
- explicit `Result`-based error handling,
- deterministic filesystem interaction,
- lock-aware repository mutations,
- incremental changes with strong test coverage.
## Architecture
```text
src/
├── main.rs # CLI interface and command routing
├── commands/ # Command implementations
│ ├── plumbing/ # Low-level Git commands
│ └── porcelain/ # User-facing commands
├── areas/ # Repository areas: database/index/refs/workspace
└── artifacts/ # Domain objects and algorithms (objects, diff, merge, log, status)
```
## How to Run Locally
### Prerequisites
- Rust 1.93 or later
- Cargo
### Build
```bash
cargo build --release
```
Binary path:
```bash
target/release/bit
```
## Usage
```bash
# initialize repository
bit init [path]
# write or hash objects
bit hash-object [-w]
bit ls-tree [-r]
# staging + commits
bit add ...
bit commit -m "message"
# inspect state
bit status [--porcelain]
bit diff [--cached] [--name-status] [--diff-filter=ADMR] [old] [new]
bit log [targets...] [-- --paths] [--oneline] [--abbrev-commit] [--decorate=] [--patch]
# branch / checkout / merge
bit branch create [source]
bit branch list [-v]
bit branch delete ... [-f]
bit checkout
bit merge -m "merge message"
```
## Testing
The test suite combines unit, property-based, and integration tests to validate Git semantics.
### Environment setup
```bash
mkdir -p ../playground
```
### Run tests
```bash
cargo test
cargo test -- --nocapture
```
Targeted examples:
```bash
cargo test add
cargo test commit
cargo test diff
cargo test log
cargo test merge
```
## Testing Strategy (TDD + Coglan-style semantics)
### TDD loop
1. Write a failing test from behavior/spec.
2. Implement minimum code to pass.
3. Refactor while preserving green tests.
### Unit tests
Use for pure logic and parsers:
- revision syntax,
- branch-name validation,
- object payload formatting/parsing,
- small deterministic transforms.
### Property tests (`proptest`)
Use for invariant-heavy behavior:
- valid/invalid revision and branch grammar,
- parser determinism,
- boundary input spaces.
Store generated failing cases in `proptest-regressions/` when applicable.
### Integration tests
Use command-level scenarios under `tests/`:
- compare command output and state transitions,
- cover merge graph topologies,
- validate index/workspace/ref interactions,
- compare against `git` where practical.
### Merge / diff / log invariant tests to prioritize
- **Merge**: fast-forward eligibility, criss-cross BCAs, multi-parent lineage ordering, conflict marker persistence.
- **Diff**: endpoint correctness, mode-only changes, multi-file hunk stability, deterministic status ordering.
- **Log**: include/exclude revision expressions, path-filtered history, stable ordering with timestamp ties, decoration rendering variants.
### Remote + pack tests (future)
- pkt-line codec round-trips and malformed-frame rejection.
- negotiation state-machine tests for `want/have/ack` flows.
- pack decoding tests for full objects and chained deltas.
- object-integrity checks after unpack + write.
## Roadmap aligned with *Building Git from Scratch*
> The roadmap is organized by domain themes that mirror the book’s progression from low-level object mechanics to higher-level collaboration/storage concerns.
### A. Object storage and plumbing
- [x] Initialize repository structure
- [x] Hash/write loose objects
- [x] Read/tree-walk object structures
- [ ] Additional plumbing introspection and validation commands
### B. Index and snapshot construction
- [x] Stage files and directory trees
- [x] Handle file/dir replacement conflicts
- [x] Persist and validate index metadata/checksum
- [ ] Interactive staging (`add -p`)
### C. Commit graph and history traversal
- [x] Write commits and parent relationships
- [x] Traverse history for `log`
- [x] Revision expressions and branch-based targeting
- [ ] Extended ancestry/query expressions parity
### D. Workspace inspection and patching
- [x] `status` for staged/unstaged/untracked states
- [x] `diff` for workspace/index/commit comparisons
- [x] Patch-oriented log output
- [ ] More advanced diff heuristics and rename/copy tracking
### E. Branching, checkout, merge
- [x] Branch create/list/delete
- [x] Checkout with ref/symbolic-ref behavior
- [x] Merge for complex DAG scenarios (including multi-BCA patterns)
- [ ] More complete conflict resolution UX
- [ ] Rebase/cherry-pick workflows
### F. Remotes and packed storage
- [ ] Clone/fetch/push/pull protocols
- [ ] Packfiles and delta compression
- [ ] Reflog, hooks, and GC lifecycle tooling
#### Remote flow and pack protocol (expanded)
- **Transport handshake/capabilities**: model protocol v2 style negotiation (capabilities, command selection, shallow/filter options where relevant).
- **Object negotiation**: exchange `want`/`have` sets and ACK states to minimize transfer.
- **Pack stream framing**: use pkt-line length-prefixed binary records with flush/delim packets.
- **Pack data model**: support object entry headers, base/delta representations (`OFS_DELTA`, `REF_DELTA`), and integrity verification at stream/repo boundaries.
- **Apply/delta pipeline**: decode + resolve base chains + reconstruct canonical objects before persistence.
- **Safety invariants**: never accept malformed framing/checksums silently; keep object graph/hash checks explicit.
## Known Gaps
- No remote/network protocol support yet.
- Packed object storage and delta compression are not implemented.
- History-rewriting workflows (rebase/cherry-pick) are pending.
- Merge UX can be improved for richer conflict presentation/resolution workflows.
## Contributing
1. Start from a failing test.
2. Implement minimally.
3. Keep changes small and focused.
4. Ensure formatting and tests pass.
5. Update README/instructions if behavior changes.
## Acknowledgments
- James Coglan for *Building Your Own Git*.
- The Git project for behavioral reference.
- The Rust ecosystem for excellent tooling.