A minimal Git implementation in Rust designed for learning Git internals and understanding how version control systems work under the hood.
This project implements core Git functionality from scratch to understand:
Git-rs supports two modes for different learning and testing needs:
When you run git-rs init
, it creates:
.git-rs/
directory (not .git/
).git-rs/git-rs-index
file (not .git/index
)This allows you to:
When you run git-rs --git-compat init
, it creates:
.git/
directory (standard Git structure).git/index
file (standard Git index)This enables you to:
Examples:
# Safe learning mode (default)
git-rs init # Creates .git-rs/
git-rs add file.txt # Uses .git-rs/git-rs-index
# Git compatibility mode
git-rs --git-compat init # Creates .git/
git-rs --git-compat add file.txt # Uses .git/index
git status # Can use real Git to check!
This project follows DDD principles with clean separation of concerns:
src/
โโโ main.rs # CLI entry point with clap
โโโ lib.rs # Library exports and error handling
โโโ domain/ # ๐ง Core business logic
โ โโโ repository.rs # Repository aggregate root
โ โโโ objects.rs # Git objects (Blob, Tree, Commit)
โ โโโ references.rs # HEAD, branches, tags
โ โโโ index.rs # Staging area model
โโโ infrastructure/ # ๐พ Persistence layer
โ โโโ object_store.rs # File-based object database
โ โโโ ref_store.rs # Reference file management
โ โโโ index_store.rs # Index file serialization
โโโ application/ # ๐ฏ Use cases (commands)
โ โโโ init.rs # โ
Repository initialization
โ โโโ add.rs # โ
File staging
โ โโโ status.rs # โ
Working tree status
โ โโโ commit.rs # โ
Commit creation
โ โโโ diff.rs # โ
Content comparison
โ โโโ clone.rs # โ
Repository cloning
โโโ cli/ # ๐ฅ๏ธ Command line interface
โโโ commands.rs # Command handlers and user interaction
Layer Responsibilities:
.git-rs/
โโโ objects/ # Content-addressed object database
โ โโโ 5a/
โ โ โโโ 1b2c3d... # Blob object (file content)
โ โโโ ab/
โ โ โโโ cd1234... # Tree object (directory listing)
โ โโโ ef/
โ โโโ 567890... # Commit object (snapshot + metadata)
โโโ refs/ # Reference storage
โ โโโ heads/ # Branch references
โ โ โโโ main # Contains: "5abc123def..."
โ โ โโโ feature-x # Contains: "7def456ghi..."
โ โโโ tags/ # Tag references
โโโ HEAD # Current branch pointer
โโโ git-rs-index # Staging area (JSON format)
โโโ config # Repository configuration
โโโ description # Repository description
Working Directory โ Staging Area โ Repository
(files) (git-rs-index) (objects/)
โ โ โ
โโโ git add โโโโโโโโโโถ โ
โ โโโ commit โโโโถ
โโโโโโโโโโโโ checkout โโโโโโโโโโโโโโโ
Object Content โ SHA-1 Hash โ Storage Path
"Hello World" โ a1b2c3... โ .git-rs/objects/a1/b2c3...
Object Format:
"<type> <size>\0<content>"
"blob 11\0Hello World"
git-rs init
- Repository InitializationWhat it does:
.git-rs/
directory structureEducational Insights:
Example:
git-rs init
# Creates: .git-rs/{objects,refs/{heads,tags},HEAD,config,description}
git-rs add
- File StagingWhat it does:
Educational Insights:
Example:
git-rs add README.md src/
# Creates blob objects and updates git-rs-index
Internal Process:
"Hello World"
"blob 11\0Hello World"
SHA-1("blob 11\0Hello World") = 5ab2c3d...
.git-rs/objects/5a/b2c3d...
{"README.md": {"hash": "5ab2c3d...", ...}}
git-rs status
- Working Tree StatusWhat it does:
.gitignore
patternsEducational Insights:
Status Categories:
Changes to be committed: # In index, different from HEAD
new file: README.md
modified: src/main.rs
Changes not staged: # In working dir, different from index
modified: README.md
deleted: old_file.txt
Untracked files: # In working dir, not in index
new_feature.rs
git-rs commit
- Commit CreationWhat it does:
Educational Insights:
Example:
git-rs commit -m "Initial implementation"
# Creates tree object, commit object, and updates branch ref
Internal Process:
git-rs-index
{name: "README.md", mode: 100644, hash: "5ab2c3d..."}
tree 42\0<tree-content>
โ 7def456ghi...
7def456ghi...
commit 156\0<commit-content>
โ 9abc123def...
.git-rs/refs/heads/main
โ 9abc123def...
Commit Object Format:
tree 7def456ghi789...
parent 1abc234def567... (if not root commit)
author John Doe <john@example.com> 1692000000 +0000
committer John Doe <john@example.com> 1692000000 +0000
Initial implementation
git-rs diff
- Content ComparisonWhat it does:
--cached
)Educational Insights:
Example:
# Show unstaged changes
git-rs diff
# Show staged changes
git-rs diff --cached
Output Format:
diff --git a/README.md b/README.md
index 1234567..abcdefg 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,4 @@
# Git-RS
-Old line
+New line
+Added line
git-rs clone
- Repository CloningComplete HTTP-based repository cloning with educational insights.
# Clone to directory with same name as repository
git-rs clone https://github.com/user/repo.git
# Clone to custom directory name
git-rs clone https://github.com/user/repo.git my-project
# Clone specific branch
git-rs clone --branch develop https://github.com/user/repo.git
Features:
git-rs log
- Commit HistoryStatus: Not yet implemented (placeholder exists in CLI)
git-rs log # Show all commit history
git-rs log -n 5 # Show last 5 commits
Will implement:
git-rs status
# Shows comprehensive file state analysis
Git uses SHA-1 content addressing for all objects:
// Object format: "<type> <size>\0<content>"
let blob_content = b"Hello World";
let object_content = format!("blob {}\0", blob_content.len());
let full_content = [object_content.as_bytes(), blob_content].concat();
let hash = sha1::digest(&full_content); // "5ab2c3d4e5f6..."
Why this matters:
Distributed: objects can be safely shared between repositories Our test suite covers:
cargo test # Run all tests
cargo test --test integration # Integration tests only
cargo test domain:: # Domain layer tests
# Initialize repository
git-rs init
# Add files to staging
git-rs add README.md src/
# Check status
git-rs status
# Create commit
git-rs commit -m "Initial implementation"
# View differences (when implemented)
git-rs diff
git-rs diff --staged
# Examine object database
find .git-rs/objects -type f
file .git-rs/objects/5a/b2c3d4...
# View staging area
cat .git-rs/git-rs-index | jq .
# Check references
cat .git-rs/HEAD
cat .git-rs/refs/heads/main
After exploring this implementation, youโll understand:
Use these commands to explore git-rs internals:
# Object inspection
hexdump -C .git-rs/objects/5a/b2c3d4...
# Decompression (requires zlib tools)
zpipe -d < .git-rs/objects/5a/b2c3d4...
# Index inspection
jq . .git-rs/git-rs-index
# Reference tracking
find .git-rs/refs -type f -exec echo {} \; -exec cat {} \;
Each command implementation includes:
For Git Beginners:
For Developers:
For Rust Learners:
.github/workflows/
for CI/CD examplesThis is primarily an educational project, but contributions are welcome:
Before committing changes, ensure code quality with our formatting script:
# Run all formatting and checks
./scripts/format.sh
# Or manually run individual tools:
cargo fmt # Rust code formatting
markdownlint-cli2 --fix "**/*.md" "!target/**" "!node_modules/**" # Markdown formatting
cargo clippy --all-targets --all-features -- -D warnings # Linting
cargo test # Test suite
Remember: This implementation uses .git-rs/
directories to avoid conflicts with real Git repositories, making it safe to experiment with in existing projects!