Reading List

The most recent articles from a list of feeds I subscribe to.

From zero to Web developer

From zero to web developer -> in 14 actionable steps.

Xesite hacking

Some miscellaneous git facts

I’ve been very slowly working on writing about how Git works. I thought I already knew Git pretty well, but as usual when I try to explain something I’ve been learning some new things.

None of these things feel super surprising in retrospect, but I hadn’t thought about them clearly before.

The facts are:

Let’s talk about them!

the “index”, “staging area” and “–cached” are all the same thing

When you run git add file.txt, and then git status, you’ll see something like this:

$ git add content/post/2023-10-20-some-miscellaneous-git-facts.markdown
$ git status
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	new file:   content/post/2023-10-20-some-miscellaneous-git-facts.markdown

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 object database (in .git/objects) and updates a file called .git/index to refer to the newly added file.

This “staging area” actually gets referred to by 3 different names in Git. All of these refer to the exact same thing (the file .git/index):

  • git diff --cached
  • git diff --staged
  • the file .git/index

I felt like I should have realized this earlier, but I didn’t, so there it is.

the stash is a bunch of commits

When I run git stash to stash my changes, I’ve always been a bit confused about where those changes actually went. It turns out that when you run git stash, git makes some commits with your changes and labels them with a reference called stash (in .git/refs/stash).

Let’s stash this blog post and look at the log of the stash reference:

$ git log stash --oneline
6cb983fe (refs/stash) WIP on main: c6ee55ed wip
2ff2c273 index on main: c6ee55ed wip
... some more stuff

Now we can look at the commit 2ff2c273 to see what it contains:

$ git show 2ff2c273  --stat
commit 2ff2c273357c94a0087104f776a8dd28ee467769
Author: Julia Evans <julia@jvns.ca>
Date:   Fri Oct 20 14:49:20 2023 -0400

    index on main: c6ee55ed wip

 content/post/2023-10-20-some-miscellaneous-git-facts.markdown | 40 ++++++++++++++++++++++++++++++++++++++++

Unsurprisingly, it contains this blog post. Makes sense!

git stash actually creates 2 separate commits: one for the index, and one for your changes that you haven’t staged yet. I found this kind of heartening because I’ve been working on a tool to snapshot and restore the state of a git repository (that I may or may not ever release) and I came up with a very similar design, so that made me feel better about my choices.

Apparently older commits in the stash are stored in the reflog.

not all references are branches or tags

Git’s documentation often refers to “references” in a generic way that I find a little confusing sometimes. Personally 99% of the time when I deal with a “reference” in Git it’s a branch or HEAD and the other 1% of the time it’s a tag. I actually 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 branch or tag! So that’s cool.

Here are all the references in my blog’s git repository (other than HEAD):

$ find .git/refs -type f
.git/refs/heads/main
.git/refs/remotes/origin/HEAD
.git/refs/remotes/origin/main
.git/refs/stash

Some other references people mentioned in reponses to this post:

  • refs/notes/*, from git notes
  • refs/pull/123/head, and `refs/pull/123/head for GitHub pull requests (which you can get with git fetch origin refs/pull/123/merge)
  • refs/bisect/*, from git bisect

merge commits aren’t empty

Here’s a toy git repo where I created two branches x and y, each with 1 file (x.txt and y.txt) and merged them. Let’s look at the merge commit.

$ git log --oneline
96a8afb (HEAD -> y) Merge branch 'x' into y
0931e45 y
1d8bd2d (x) x

If I run git show 96a8afb, the commit looks “empty”: there’s no diff!

git show 96a8afb
commit 96a8afbf776c2cebccf8ec0dba7c6c765ea5d987 (HEAD -> y)
Merge: 0931e45 1d8bd2d
Author: Julia Evans <julia@jvns.ca>
Date:   Fri Oct 20 14:07:00 2023 -0400

    Merge branch 'x' into y

But if I diff the merge commit against each of its two parent commits separately, you can see that of course there is a diff:

$ git diff 0931e45 96a8afb   --stat
 x.txt | 1 +
 1 file changed, 1 insertion(+)
$ git diff 1d8bd2d 96a8afb   --stat
 y.txt | 1 +
 1 file changed, 1 insertion(+)

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 other commit), 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 repo with a merge conflict (one branch added x and another branch added y to the same file), and show the merge commit where I resolved the conflict, it looks like this:

$ git show HEAD
commit 3bfe8311afa4da867426c0bf6343420217486594
Merge: 782b3d5 ac7046d
Author: Julia Evans <julia@jvns.ca>
Date:   Fri Oct 20 15:29:06 2023 -0400

    Merge branch 'x' into y

diff --cc file.txt
index 975fbec,587be6b..b680253
--- a/file.txt
+++ b/file.txt
@@@ -1,1 -1,1 +1,1 @@@
- y
 -x
++z

It looks like this is trying to tell me that one branch added x, another branch added y, and the merge commit resolved it by putting z instead. But in 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)

that’s all!

I’ll keep this post short, maybe I’ll write another blog post with more git facts as I learn them.

My company is hiring: who wants to work with me in Developer Relations?

I have a spot on my team for a Developer Advocate and you can apply here: Developer Advocate all genders – Remote, Europe, UK Please, don’t send me CVs or tell me to “take a look” as all applicants need to be in the system so we can follow the needed legal procedure. What you’ll […]

Could it be that maybe LinkedIn was the answer after all? If so, I lost the game.

With Twitter imploding and people (myself included) trying to move to multiple similar apps, I was following everyone I knew numerous times. It may not look like it, but I can be a bit shy! If we're "Twitter/conference friends", you probably noticed me clicking the follow button on at least three new platforms. Then, some social anxiety creeps in!

"Oh, I liked my friend's post on Mastodon. Should I also like and share it on the other platform they also shared it?"

"Oh no, this person only follows me back on this platform, but not on the other. Do they hate me?"

"Am I being annoying?"

"Where do I post this mediocre attempt at a joke?" (actually, the answer for that is your personal website.)

While I am content with Mastodon (I've had an account since 2017), I did sign up for Threads and BlueSky. I will probably sign up for whatever else comes along because, you know… FOMO. Turns out I had forgotten about our old friend LinkedIn, which is also where everyone is!

I initially created an account in 2012 and kept it until 2016 or 2017. At that point, I had amassed hundreds of connections. I was also a young woman, so a few previous male co-workers constantly crept on me, from frequently visiting my profile to even drunk messaging me (yes, on LinkedIn). At that time, I wasn't using my last name online and was keen to protect my privacy and location, so having a profile where anyone could see where I was for 8 hours a day did not make sense. It was a time of my life when I was going through lots of anxiety, so I deleted my account.

I just remembered about LinkedIn in mid-pandemic. I created a new account, added my current co-workers and some close friends and realised I only had 11 connections. I felt… a bit concerned about how it would make me look. The pandemic and life gave me lots more to worry about, so I forgot about LinkedIn again until a couple of weeks ago.

A friend messaged me, telling me something happened to them on LinkedIn, and I decided to log in. Turns out more people I know are on it (obviously!). More people to follow and add! And my number of connections is still tiny. What does that say about me? In 2023! Social media anxiety is back!

"Okay, so LinkedIn is, in theory, the professional side of social media. Am I being too much for adding this person I have only interacted with on Twitter?"

"This recommended person, I know them and have worked with them, but.. We haven't spoken in years. What should I do?!"

"I follow this person on four other social media platforms. Will I come across as overly keen if I click "follow here too??"

Anyway - I did click in a few! I even saw some posts from the State of the Browser that I was mentioned in.

But this got me thinking. Dang, what could have happened if creepy men weren't bothering me back in the day? Could I have kept connections with lovely people I have actually worked with in the past? Most aren't active on tech Twitter or these new platforms.

Because let's be realistic: before Twitter imploded, tech Twitter was/is very much only a Twitter thing. Most people I have ever worked with don't care about Twitter. And quite frankly, some of them were the best people I ever worked with. But they are all on LinkedIn. And I wasn't for years because I felt I had to get away to feel safe. How unfair. What opportunities could I have missed because of this?

There's a lot of crap on LinkedIn. It is its own meme, but something tells me that these new microblogging platforms will come and go, but LinkedIn will still be there with its own cursed vibe.

Anyway, if we have actually met, feel free to add me on LinkedIn!