A pure Python, zero-dependency implementation of the core mechanics behind Git, built entirely from first principles. Py-Git demonstrates how modern version control systems implement content-addressable storage, staging, immutable snapshots, and commit graphs without relying on external libraries.
Every tracked file moves through a deterministic pipeline before becoming part of repository history.
graph TD
WD["📂 Working Directory"] -->|python pygit.py add| INDEX["📄 Staging Index (.pygit/index)"]
INDEX -->|python pygit.py commit| OBJECTS["📦 Object Database (.pygit/objects)"]
subgraph STORE [Content Addressable Storage]
BLOB["📄 Blob Objects"]
TREE["🌳 Tree Objects"]
COMMIT["💬 Commit Objects"]
end
OBJECTS --> STORE
COMMIT -->|Parent SHA-1| DAG["🔗 Commit DAG"]
REFS["🚩 HEAD / main"] --> COMMIT
| Operation | Complexity |
|---|---|
init |
O(1) |
status |
O(N) |
add (initial) |
O(N) |
add (unchanged files) |
Near O(1) |
commit |
O(1) relative to repository size |
Benchmarks were executed on Arch Linux using benchmark_pygit.py with OS page cache dropped before every operation, measuring true filesystem performance rather than warm-cache execution.
| Repository Scale | add |
commit |
status |
|---|---|---|---|
| 100 Files | 33.69 ms | 2.30 ms | 3.59 ms |
| 500 Files | 133.13 ms | 6.05 ms | 13.41 ms |
| 1,000 Files | 283.41 ms | 8.39 ms | 26.53 ms |
| Repository Scale | init |
add |
commit |
status |
|---|---|---|---|---|
| 100 Files | 0.13 MB | 0.48 MB | 0.32 MB | 0.17 MB |
| 500 Files | 0.13 MB | 0.82 MB | 0.46 MB | 0.42 MB |
| 1,000 Files | 0.13 MB | 1.29 MB | 0.65 MB | 0.79 MB |
.
├── pygit.py
├── benchmark_pygit.py
├── README.md
└── .pygit
├── HEAD
├── index
├── refs
└── objects
Initialize a repository:
python pygit.py initStage files:
python pygit.py add <path>
python pygit.py add .Check repository status:
python pygit.py statusCreate a commit:
python pygit.py commit -m "Commit message"