Over the last six years, I've become better at using Git for version control. But my conceptions of the index, the working copy, the object graph and remotes have just grown fuzzier.
Sometimes, I can only understand something by implementing it.
So, I wrote Gitlet, my own version of Git.
I pored over tutorials.
I read articles about internals.
I tried to understand how API commands work by reading the docs, then gave up and ran hundreds of experiments on repositories and rummaged through the
.git directory to figure out the results.
I discovered that, if approached from the inside out, Git is easy to understand. It is the product of simple ideas that, when combined, produce something very deep and beautiful.
For a quick introduction to what happens when you run the basic Git commands, read Git in six hundred words.
For a six thousand word deep dive into the innards of Git, read Git from the inside out.
The heavily annotated Gitlet source is one thousand lines long. This may sound intimidating, but it's OK. The annotations explain both Git and the code in great detail. The code mirrors the terminology of the Git command line interface, so it should be approachable. And the implementation of the main Git commands is just three hundred and fifty lines.
$ git clone email@example.com:maryrosecook/gitlet.gitOr install it from npm:
$ npm install -g gitlet
I wrote Gitlet to explain how Git works. It would be unwise to use Gitlet to version control your projects. But it does work. Sort of.First, install Node.js. Then:
$ npm install -g gitlet $ mkdir a $ cd a ./a $ gitlet init ./a $ echo first > number.txt ./a $ gitlet add number.txt ./a $ gitlet commit -m "first" [master 2912d7a2] first ./a $ cd .. $ gitlet clone a b $ cd b ./b $ echo second > number.txt ./b $ gitlet add number.txt ./b $ gitlet commit -m "second" [master 484de172] second $ cd ../a ./a $ gitlet remote add b ../b ./a $ gitlet fetch b master From ../b Count 6 master -> b/master ./a $ gitlet merge FETCH_HEAD Fast-forward ./a $ gitlet branch other ./a $ gitlet checkout other Switched to branch other ./a $ echo third > number.txt ./a $ gitlet add number.txt ./a $ gitlet commit -m "third" [other 656b332d] third ./a $ gitlet push b other To ../b Count 9 other -> other
$ git clone firstname.lastname@example.org:maryrosecook/gitlet.git $ cd gitlet $ npm install $ npm test
The code is open source, under the MIT licence.