Gitlet is a version-control system implemented in Java as part of UC Berkeley's CS61B course project. It mimics a small but functional subset of Git, including committing, branching, checkout, merging, and log history.
- Usage:
java gitlet.Main init
- Description:
Initializes a new Gitlet repository in the current directory.
- Usage:
java gitlet.Main add [file name]
- Description:
Stages the file for addition.
- Usage:
java gitlet.Main commit [message]
- Description:
Saves a snapshot of the current state.
- Usage:
java gitlet.Main rm [file name]
- Description:
Removes a file from staging or tracking.
- Usage:
java gitlet.Main log
- Description:
Displays commit history.
- Usage:
java gitlet.Main global-log
- Description:
Displays all commits.
- Usage:
java gitlet.Main find [commit message]
- Description:
Finds commits with the given message.
- Usage:
java gitlet.Main status
- Description:
Displays branches, staged files, and untracked files.
- Usages:
java gitlet.Main checkout -- [file name] java gitlet.Main checkout [commit id] -- [file name] java gitlet.Main checkout [branch name]
- Description:
Restores files from a commit or branch.
- Usage:
java gitlet.Main branch [branch name]
- Description:
Creates a new branch.
- Usage:
java gitlet.Main rm-branch [branch name]
- Description:
Deletes a branch.
- Usage:
java gitlet.Main reset [commit id]
- Description:
Moves the current branch to a specified commit.
- Usage:
java gitlet.Main merge [branch name]
- Description:
Merges another branch into the current branch.
Gitlet is a version-control system implemented in Java as part of UC Berkeley’s CS61B course project. It mimics a small but functional subset of Git, including committing, branching, checkout, merging, and log history.
This was one of the first large-scale software engineering projects I completed. Unlike smaller assignments that guide you step by step, Gitlet gives you only a full specification, and you have to design and implement the system yourself. That made the project much more challenging, but also much more rewarding.
Working on Gitlet taught me a lot about object-oriented design, function and class naming, organizing a larger codebase, working with file I/O and serialization, and handling edge cases carefully. It also showed me how important design decisions are early on. A poor design can easily cost many hours later when the project grows and new commands depend on the old ones.
One of the biggest challenges was the merge command. It is the longest and most complicated part of the project, and it depends on nearly every previous command being correct. If earlier commands are even slightly wrong, merge becomes very difficult to debug. In that sense, the project behaves a lot like a state machine: many different file states and branch states must be handled correctly, and the autograder checks those cases very thoroughly.
I also learned that trying to put everything into one class makes the project much harder to manage. Breaking the work into separate classes and helper methods made the design much cleaner and easier to reason about.
I received a full score of 1600/1600 on the main autograder for this project.

init— initialize a new Gitlet repositoryadd— stage files for additioncommit— save snapshots of tracked filesrm— stage files for removallogandglobal-log— view commit historyfind— search commits by messagestatus— show repository statecheckout— restore files or switch branchesbranchandrm-branch— manage branchesreset— move the current branch to an earlier commitmerge— merge changes from another branch into the current branch
Some of the more interesting parts of the project were:
- storing commits and blobs using SHA-1 hashes
- representing commit history as a directed acyclic graph
- finding split points for merges
- handling merge conflicts
- keeping track of staged additions and removals
- making the implementation work correctly with serialized files on disk
The hardest part of the project was the merge command. It depended on the correctness of nearly every other command, and required careful handling of many file states and edge cases. Good design decisions early on saved a lot of time later.
Gitlet is a project of about 1,000 lines(Although my implementation ended up being appox ~ 1.5k loc). It is not very large, but it contains a wealth of knowledge points and ideas. This project can fully train beginners to implement a just-right project.
I gained a lot from this project. For example, my understanding of function naming, object-oriented ideas, functional programming methods, and induction and organization skills have all been improved. Good design decisions early on can save dozens of hours of work later, while poor design choices can easily set a project back by 10–30 hours or more.
Thank you, UCB, for making the project specifications and autograder publicly available. Thank you, Professor Josh, for creating such a valuable learning experience.