Get Even More Visitors To Your Blog, Upgrade To A Business Listing >>

Some miscellaneous git facts

I’ve been very slowly working on writing about how Git works. I thought Ialready knew Git pretty well, but as usual when I try to explain something I’vebeen learning some new things.None of these things feel super surprising in retrospect, but I hadn’t thoughtabout them clearly before.The facts are:Let’s talk about them!When you run git add file.txt, and then git status, you’ll see something like this:People usually call this “staging a file” or “adding a file to the staging area”.When you stage a file with git add, behind the scenes git adds the file to its objectdatabase (in .git/objects) and updates a file called .git/index to refer tothe newly added file.This “staging area” actually gets referred to by 3 different names in Git. Allof these refer to the exact same thing (the file .git/index):I felt like I should have realized this earlier, but I didn’t, so there it is.When I run git Stash to stash my changes, I’ve always been a bit confusedabout where those changes actually went. It turns out that when you run gitstash, git makes some commits with your changes and labels them with a referencecalled stash (in .git/refs/stash).Let’s stash this blog post and look at the log of the stash reference:Now we can look at the commit 2ff2c273 to see what it contains:Unsurprisingly, it contains this blog post. Makes sense!git stash actually creates 2 separate commits: one for the index, and one foryour changes that you haven’t staged yet. I found this kind of hearteningbecause I’ve been working on a tool to snapshot and restore the state of a gitrepository (that I may or may not ever release) and I came up with a verysimilar design, so that made me feel better about my choices.Git’s documentation often refers to “references” in a generic way that I finda little confusing sometimes. Personally 99% of the time when I deal witha “reference” in Git it’s a branch or HEAD and the other 1% of the time it’s a tag. Iactually didn’t know ANY examples of references that weren’t branches or tags or HEAD.But now I know one example – the stash is a reference, and it’s not a branchor tag! So that’s cool.Here are all the references in my blog’s git repository (other than HEAD):Apparently there’s also a git command called git notes that can create referencesunder .git/refs/notes but I don’t know anything about that.Here’s a toy git repo where I created two branches x and y, each with 1file (x.txt and y.txt) and merged them. Let’s look at the Merge commit.If I run git show 96a8afb, the commit looks “empty”: there’s no diff!But if I diff the merge commit against each of its two parent commitsseparately, you can see that of course there is a diff:It seems kind of obvious in retrospect that merge commits aren’t actually “empty”(they’re snapshots of the current state of the repo, just like any othercommit), but I’d never thought about why they appear to be empty.Apparently the reason that these merge diffs are empty is that merge diffs only show conflicts – if I instead create a repowith a merge conflict (one branch added x and another branch added y to thesame file), and show the merge commit where I resolved the conflict, it lookslike this:It looks like this is trying to tell me that one branch added x, anotherbranch added y, and the merge commit resolved it by putting z instead. Butin the earlier example, there was no conflict, so Git didn’t display a diff at all.(thanks to Jordi for telling me how merge diffs work)I’ll keep this post short, maybe I’ll write another blog post with more gitfacts as I learn them. New talk: Making Hard Things Easy You might also like the Recurse Center, my very favorite programming community (my posts about it)



This post first appeared on VedVyas Articles, please read the originial post: here

Share the post

Some miscellaneous git facts

×

Subscribe to Vedvyas Articles

Get updates delivered right to your inbox!

Thank you for your subscription

×