DEV Community

Lakshya Varshney
Lakshya Varshney

Posted on

I Rebuilt Git Without Git — 3,390 Lines of Python, Zero Dependencies

I Rebuilt Git Without Git — 3,390 Lines of Python, Zero Dependencies

For the Zero Dependency Hackathon, I decided not to build another application that simply happens to have an empty requirements.txt.

I wanted to answer a harder question:

How much of a real developer tool can you rebuild from scratch using only Python's standard library?

My answer is pygit — a content-addressed, Git-like version control system implemented in a single Python file.

3,390 lines.
1 Python file.
141 tests.
30 commands.
0 external dependencies.

And no, it isn't a wrapper around Git.

pygit_single.py never invokes the real git executable. The object model, staging area, refs, merge logic, CLI, and synchronization protocol are implemented from scratch.

The packages I would normally install

If I wanted to build something like this in Python, there are plenty of libraries that could handle much of the work.

I could reach for:

  • GitPython / dulwich / pygit2 for Git functionality
  • diff-match-patch for diffing
  • zstandard / python-lz4 for compression
  • PyYAML for structured state
  • Click / Typer for the CLI
  • requests / paramiko for networking
  • pathspec for gitignore-style matching
  • pytest for testing

Instead, I removed the dependencies entirely.

The challenge wasn't simply deleting requirements.txt.

The challenge was rebuilding what those packages normally give you.

What did I actually build?

1. Content-addressed object storage

The foundation of pygit is a content-addressed object model.

Files become blobs, directory structures become trees, commits contain tree and parent references, and tags point to commits.

Objects are hashed using hashlib.sha256, compressed with zlib, and stored as loose objects or packed during garbage collection.

No database.
No Git library.

Just Python's standard library and the filesystem.

Internal Architecture

2. A real staging area

add builds a JSON index mapping paths to blob hashes.

Branch switching doesn't just change a pointer — the index is rebuilt from the target tree while the working tree is updated, keeping status consistent after a checkout.

3. Three-way merging

One of the most important parts I wanted to implement rather than fake was merging.

pygit performs three-way merges using difflib.SequenceMatcher at the line level.

It handles:

  • Fast-forward merges
  • Clean three-way merges
  • Conflicting merges

When changes actually collide, it produces genuine conflict markers:

<<<<<<<
=======
>>>>>>>
Enter fullscreen mode Exit fullscreen mode

and returns a non-zero exit status rather than silently resolving the conflict.

4. A surprisingly large Git-style command surface

This isn't just init, add, and commit.

There are 30 commands, including:

branch, checkout, switch, merge, tag, reset, stash, cherry-pick, rebase, revert, reflog, blame, gc, clean, remote, serve, fetch, clone, push, and config.

I also tested behavior against real Git where there was a meaningful comparison to make, including failure cases.

The part that really had no package to hide behind: networking

For remote synchronization, I didn't use Git's protocol or install a networking abstraction.

pygit has its own client/server synchronization protocol.

A clone/fetch follows a flow like:

client → WANT <ref>
server → TIP <sha>
client → HAVE <known shas>
server → streams missing objects
Enter fullscreen mode Exit fullscreen mode

Push performs a fast-forward check and refuses to update a remote when the histories have diverged.

The transport uses Python's standard-library socket, with binary length-framed object transfer.

So:

No requests.
No paramiko.
No Git wire protocol.

Just sockets and a protocol designed for pygit.

custom sync protocol

What replacing the dependencies looked like

This is where the "zero dependency" requirement became an actual engineering challenge.

The substitution table ended up looking like this:

Normally install I used instead
GitPython / dulwich / pygit2 My own implementation
diff libraries difflib
zstandard / lz4 zlib
PyYAML json
Click / Typer argparse
requests / paramiko socket
pathspec fnmatch
pytest unittest
Directory-walking helpers os.walk

These aren't hypothetical substitutions. STDLIB.md documents the replacements and states that each row is backed by an actual import/use in the codebase.

zero dependency map

The result

The final implementation is a single Python source file.

There is no packaging step.

There is no pip install.

There is no vendored dependency tree.

There is no subprocess call to Git.

Running it is simply:

python3 pygit_single.py init
python3 pygit_single.py add .
python3 pygit_single.py commit -m "First commit"
Enter fullscreen mode Exit fullscreen mode

The project has 141 tests covering object serialization, repository operations, diffs, status, ignore rules, all three merge paths, stash, tags, reset, reflog, cherry-pick, rebase, revert, packfiles, garbage collection, blame, cleanup safety, colored output, and the network protocol.

The project also has a reproducibility check based on the SHA-256 of the source file, so the exact source a judge evaluates can be independently verified.

What I learned

The interesting lesson wasn't simply:

"You can use Python's standard library."

We already know that.

The interesting lesson was that dependencies often represent engineering decisions that you have to make yourself when you remove them.

A library doesn't just save lines of code.

It saves you from thinking about:

  • Object formats
  • Serialization
  • Merge semantics
  • Filesystem state
  • Protocol framing
  • History traversal
  • Failure modes
  • CLI behavior
  • Testing infrastructure
  • Edge cases

Building pygit forced me to understand those pieces instead of treating them as black boxes.

That's what made the project worth building.

pygit is my submission to the Zero Dependency Hackathon — Track A: Developer Tools & CLI.

Project

GitHub Repository — Lakshya-Varshney/pygit

Demo

Watch the pygit demo on YouTube

#ZeroDependencyHack #Python #OpenSource #Git #DeveloperTools #CLI #PythonStandardLibrary #BuildInPublic

Top comments (0)