Skip to content

nadav78/minigit

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

32 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MiniGit (MVP)

MiniGit is a simplified, local, single-user version-control system built to explore and demonstrate the core mechanics behind Git-style version control. It focuses on content-addressed storage, immutable objects, directory snapshots, and linear commit history, without aiming for feature completeness or compatibility with Git.

Supported features (MVP scope)

  • minigit init: initialize a repository at .minigit/
  • minigit hash-object <file> [--write]: compute a blob object ID; optionally store it
  • minigit cat-file <oid>: print an object’s type and raw contents
  • minigit commit -m <message>: snapshot the working directory and create a commit (Linear commit history (single parent per commit))
  • minigit log: traverse and print commit history from HEAD
  • minigit checkout <commit_oid>: restore a previous snapshot and move the current ref (MVP semantics)

Non-goals

These are deliberate scope decisions for the MVP:

  • No staging area / index (add, status)
  • No branching, merging, rebasing, or conflict resolution
  • No remotes or networking (push/pull/fetch)
  • No packfiles, delta compression, or performance optimizations
  • No interoperability with real Git object formats
  • No concurrency guarantees or multi-user support

High-level design

MiniGit uses a Git-inspired object model stored under .minigit/objects/:

  • Blob: raw file bytes.
  • Tree: a directory snapshot mapping names to objects (files, subtrees, symlinks).
  • Commit: points to a root tree, an optional parent commit (single parent only), and includes metadata (timestamp + message).

Objects are content-addressed: the object ID (OID) is a SHA-1 hash of the object’s bytes. This makes stored objects effectively immutable—writing the same content yields the same OID, and existing objects are not overwritten.

HEAD and refs (MVP)

  • .minigit/HEAD points to a ref under refs/ (e.g., refs/heads/main).
  • The ref file stores the current commit OID.
  • History is linear: each commit has at most one parent.
  • Checkout moves the current branch ref to the target commit; detached HEAD is intentionally not supported in the MVP.

Checkout & restore semantics

Checkout is implemented as “restore an exact snapshot”:

  • Restores the working directory to exactly match the target commit’s root tree.
  • Overwrites existing files and directories as needed.
  • Deletes files/directories that are present in the working directory but not in the snapshot.
  • Always preserves .minigit/.

Symlinks:

  • Snapshotting does not follow symlinks; it stores the symlink itself.
  • Restore creates a real symlink when permitted; otherwise checkout fails with a clear error (no silent fallback).

Safety & correctness guarantees

  • Never writes outside the repository root (guards against path traversal / escape attempts).
  • Ignores .minigit/ during snapshotting and restoration (except ref updates).
  • Deterministic trees: directory snapshots are encoded in a stable order so the same working tree state yields the same tree OID.
  • Graceful, user-facing errors for missing objects, invalid OIDs, and detectable corruption (no crashes).

Tradeoffs & design decisions

  • No staging area: reduces surface area and keeps the data model focused on snapshots.
  • Linear history only: commit traversal is straightforward and predictable.
  • Destructive checkout is allowed: the MVP overwrites local changes to keep semantics simple (MiniGit prints a warning).
  • Correctness over performance: objects are stored individually; there are no packs, deltas, or caching.

How to run

Requirements

  • Python 3.10+ (recommended: latest stable)

Run the CLI

From the repository root:

python -m minigit --help
python -m minigit init

If installed as a script entry point (see pyproject.toml):

minigit --help

Run tests

uv run --with pytest pytest -q
# or, if pytest is already installed:
python -m pytest -q

What I learned

  • Modeling system behavior via immutable data structures and explicit state transitions (refs vs objects).
  • Designing a small system around explicit invariants (object immutability, path safety, deterministic snapshots).
  • Filesystem traversal and cross-platform edge cases (byte-for-byte correctness, symlinks, path handling).
  • Building a spec-driven MVP with thin slices and tests to keep scope under control.

About

A simplified, local version-control system demonstrating content-addressed storage, immutable snapshots, and linear commit history.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors