kit is a minimal, educational version control system written in modern C++. Inspired by Git, it is designed to help developers learn and explore the internals of version control systems: content-addressed object storage, trees, refs, and merges — built from scratch.
All core commands are implemented:
| Command | Description |
|---|---|
kit init |
Initialize a new .kit/ repository |
kit add <file> |
Stage file(s) into the index |
kit commit -m <msg> |
Commit staged files |
kit status |
Show staged / modified / untracked files |
kit log |
Show commit history |
kit diff |
Line-level diff between working directory and commits |
kit branch |
Create, list, and delete branches |
kit checkout <branch> |
Switch branches or commits |
kit merge <branch> |
Merge a branch into the current branch |
kit reset <commit> |
Reset to a specific commit |
kit stash |
Temporarily save and restore changes |
- CMake ≥ 3.14
- A C++17 compiler
- OpenSSL (for SHA-1 hashing)
cxxopts and Google Test are fetched automatically via CMake FetchContent.
git clone https://github.com/kyuna0312/kit-vcs.git
cd kit-vcs
mkdir cpp/build && cd cpp/build
cmake ..
makeBinary output: cpp/build/kit-vcs
OpenSSL is located via
find_package(OpenSSL). If CMake can't find it (e.g. Homebrew on macOS), point it there:cmake .. -DOPENSSL_ROOT_DIR=$(brew --prefix openssl)
cd cpp/build
ctest # run all tests
./test_unit # unit tests, verbose
./test_integration # integration testsTests use Google Test, fetched automatically via CMake FetchContent.
kit init
kit add main.cpp
kit commit -m "Initial commit"
kit branch feature
kit checkout feature
# ...edit files...
kit add main.cpp
kit commit -m "Add feature"
kit checkout master
kit merge feature
kit logkit mirrors Git's three-layer object model — commit → tree → blobs — stored as flat, SHA-1-addressed files:
.kit/
├── HEAD # "ref: refs/heads/<branch>" or a bare commit hash (detached)
├── index # staged file list (path → blob hash)
├── objects/ # blobs, trees, commits — flat files named by SHA-1
├── refs/
│ └── heads/ # one file per branch, containing a commit hash
└── stash/ # stashed snapshots
The on-disk wire format is fully specified in spec/FORMAT.md, with byte-exact fixtures under spec/fixtures/ so alternative implementations (e.g. Rust) can verify interoperability.
cpp/src/
├── main.cpp # entry point → kit::cli::run()
├── cli/
│ ├── cli.cpp # command dispatch
│ └── commands/ # cmd_add, cmd_commit, cmd_merge, ... one pair per command
├── core/
│ ├── repository.cpp # opens/inits .kit/, reads/writes objects
│ ├── refs.cpp # HEAD and branch pointers
│ ├── index.cpp # staging area
│ └── objects/ # Blob, Tree, Commit
└── utils/ # SHA-1 (OpenSSL), diff, filesystem, logging, Result<T>
Errors are handled explicitly with a Result<T> type — no exceptions on the happy path.
- Learn Git internals by rebuilding them.
- Keep the implementation small enough to read in one sitting.
- Play with low-level file I/O, hashing, and commit DAGs.
- Serve as a reference implementation: the format spec enables ports to other languages.
This project is licensed under the MIT License. See the LICENSE file for details.
Contributions are welcome! Feel free to open issues or submit pull requests to improve kit-vcs.