On crafting a git implementation in Go
I wanted to brush up on some of my programming skills. Since my latest round of funemployment, I've taken some time off (mostly to play Fallout: New Vegas, as one does); my last bit of time at the last place revolved around more systems administration / infrastructure building, so I wasn't coding much. I was bouncing around between a few sites, like Leetcode and Codewars. At some point, I was watching a Primeagen video where I found a discount for codecrafters.
I've started working on the Git in Go track; I've built something similar before, so it's kind of interesting to take a guided track. Some notes from along the way:
- I tend to organize things around structs: I like to organize pieces of data together, along with the operations that should act on them. I often admire other people's code that is less struct-based, but this is how I get things done.
- The absolute bare-minimum for a git repository is a .git directory containing objects and refs directories, along with a HEAD file with the contents ref: refs/heads/master\n.
- Make sure you’re in a git root.
- Make sure that the parent directory for the file is created when storing the object.
- Hashes are computed over the raw zlib-decompressed file (header and contents). At first, I was just using the contents.
- The hash for the tree is computed over the entire raw file, including the header… just like blobs.
- I was able to reuse the Blob type to write the Tree, which worked out well:
func (tree *Tree) Write() error {
blob := BlobFromBytes(tree.rawEntries())
blob.Type = TypeTree
if blob.HashString() != tree.HashString() {
fmt.Fprintf(os.Stderr,
"tree.Write: blob hash %s != tree hash %s",
blob.HashString(), tree.HashString())
}
return blob.Write()
}
I still have two more stages to complete: commits and cloning. Still, pretty cool. I think I'm going to try Rust for the next one (Redis?). I'd like to try some of these out in Clojure, C++, C#, Kotlin, and Gleam [1] at some point too.
| [1] | Gleam is a new language built on the BEAM. |