Git Good
Git Good
Git Good
The Education Problem
S2 E2319m · Apr 05, 2026
Over 15 million developers have panicked searching "how do I undo commits in Git"—revealing why the world's most-viewed programming question isn't about algorithms, but a tool used daily by millions who still don't understand it.

The Education Problem

The Most Viewed Question on the Internet

The last series ended with Git having won. The format wars, the competing tools, the years of skepticism — all resolved in Git's favor. What we did not look at is what winning actually looks like from inside the industry, for the millions of developers who now wake up every morning and have to use the thing.

Somewhere right now, a developer is panicking. They just committed something they should not have committed, or committed to the wrong branch, or pushed a change that broke everything, and they are doing what every developer in this situation does. They are opening a browser and typing "how do I undo" into a search bar.

The most viewed programming question on Stack Overflow is not about algorithms. It is not about databases or memory management or any of the things computer science professors think are hard. It is about Git. Specifically, it is the question "How do I undo the most recent local commits in Git?" That question has been viewed over fifteen million times since it was posted in two thousand nine. Fifteen million moments of quiet panic from people who use a tool every single day and still do not understand what it does.

And that is just one question. Four of the ten most viewed questions on all of Stack Overflow are about Git. Not about a specific programming language or framework or cloud service. About a version control tool. The questions read like a catalog of confusion: how do I delete a remote branch, how do I rename a local branch, how do I revert a file to a previous commit, how do I resolve merge conflicts. Millions upon millions of views, each one representing a developer who ran into a wall and went looking for help.

Here is the thing that makes this remarkable. Git is not new. It has been around since two thousand five. It is used by virtually every software team on Earth. Developers interact with it more often than they interact with any other tool in their entire workflow, more than their text editor, more than their programming language, more than their operating system. And yet most of them could not explain what a commit actually is. They have memorized a handful of commands the way you memorize a phone number, without understanding the system behind it. Git add, git commit, git push. The sacred three-step incantation that makes code go to the cloud.

When something goes wrong, and something always goes wrong, they are lost. They do not debug. They do not reason about state. They Google. And often the advice they find tells them to run a command that fixes the immediate problem while leaving them no wiser about what happened or why. This is the education problem. The most widely used developer tool in the world is also the least understood.

The Fairy Gitmother

In two thousand sixteen, a frontend developer at Etsy named Katie Sylor-Miller did something that would resonate with millions of people. She published a website. Not a tutorial, not a course, not a comprehensive guide. Just a single page with a profane name and a simple premise: you are in trouble with Git, and here is how to get out of it.

The site was called Oh Shit, Git. There is also a version without the profanity, called Dangit Git, for workplaces with content filters. Katie had been keeping a text file on her computer for years, a personal cheat sheet of Git emergencies and their solutions. One evening she wrapped some HTML around it, published it to her server, tweeted a link, and went to bed.

I woke up the next morning and my Twitter had blown up. I was on the front page of Hacker News.

The site went viral because it did something that Git documentation almost never does. It admitted that Git is confusing. The official docs explain commands in terms of other commands, using vocabulary that assumes you already understand the thing you are trying to learn. Oh Shit, Git starts from the opposite direction. It starts from the panic. You just committed to the wrong branch. You need to undo a commit that already got pushed. You accidentally deleted something and have no idea how to get it back. Each scenario is a moment of genuine fear, and Katie meets you there with plain language and a solution.

Git does not describe workflows. Git describes internal plumbing commands and everything that it exposes in its API. The whole point of Git is that just about everything can be undone, and just about everything is fixable, and here is how you do it.

But here is the part of Katie's story that cuts closest to the education problem. Even after creating this hugely popular Git reference, she did not feel like she understood Git. She admitted this openly.

Even when I made Oh Shit Git, that became this big reference that everybody looks at to help them with Git, I still did not understand it. I did not get Git at all.

It was only when she submitted a conference talk proposal about Git and got accepted that she actually sat down to learn how the tool worked. The pressure of standing in front of an audience forced a depth of understanding that years of daily use had not. She went from Etsy to Square, eventually becoming a Principal Engineer, and the site she built in two hours one evening has been translated into twenty-eight languages. She calls herself the Fairy Gitmother. Millions of developers owe her a thank you.

The takeaway is not that Katie was uniquely confused. The takeaway is that a senior engineer who used Git daily for years could build a reference used by millions of people and still not understand the tool. That is not a personal failing. That is a design problem.

The Wizard of Zines

If Katie Sylor-Miller's contribution was meeting people in their moment of panic, Julia Evans took a different approach. She wanted to prevent the panic in the first place by giving people a mental model of what Git is actually doing.

Julia is a programmer and writer in Montreal who publishes small illustrated guides she calls zines, through her company Wizard Zines. They look like comic books about technical topics, twenty or so pages of hand-drawn diagrams and short explanations. She has made zines about Linux, networking, SQL, and the command line. In two thousand twenty-four, she published one called How Git Works, and it took her eight months to write.

Eight months for twenty pages might sound excessive until you understand what Julia was doing. She was not writing documentation. She was building a visual vocabulary for something that has always been explained with words. Git is, at its core, a directed acyclic graph. That is a structure made of nodes and arrows where you can follow the arrows in one direction but never loop back. Commits point to their parents. Branches point to commits. Tags point to commits. The entire history of a project is a graph you can draw on paper, and once you can see it, everything about Git makes sense. Merging is combining two paths in the graph. Rebasing is replaying commits onto a different path. A detached HEAD just means you are looking at a specific node instead of following a branch name.

The trouble is that Git's interface is text. You type commands and get text back. The graph that makes everything click is invisible. You have to hold it in your head, and nobody taught you how to build it there. Julia's insight was that the gap between Git's visual reality and its textual interface is where all the confusion lives. Her zines bridge that gap by literally drawing the picture.

She also identified something specific about Git's communication problem. Git's vocabulary actively misleads people. Terms like "fast-forward," "remote-tracking branch," and "reference" sound technical and intimidating but describe simple ideas. The status messages Git prints after you run a command sometimes do not accurately reflect what just happened. When the tool itself is unreliable as a teacher, you need someone on the outside translating.

Julia and Katie even collaborated. The Oh Shit, Git zine, published through Wizard Zines, combines Katie's panic-first scenarios with Julia's visual explanations. Between them they have probably done more to make Git accessible than any official documentation effort. And neither of them works on Git itself. They are translators, standing between a powerful tool and the people trying to use it, doing work the tool's creators never prioritized.

The Book That Teaches a Tool That Resists Teaching

There is a book about Git that functions as the closest thing to an official textbook. It is called Pro Git, written by Scott Chacon and Ben Straub, and it is free. Completely free, published under a Creative Commons license, hosted on the official Git website. It has been translated fully into more than fifteen languages, with partial translations in six more and another eight in progress. Hundreds of contributors have submitted corrections and additions over the years. If you have ever searched for "how does Git work" and ended up on git-scm.com, you have probably read parts of it without knowing it had a name.

Scott Chacon is not just an author. He co-founded GitHub. He has arguably done more than any single person to make Git accessible, through the book, through GitHub's design, through years of talks and blog posts explaining Git's internals to confused audiences. And yet even Pro Git struggles with a fundamental tension. To explain Git properly, you have to explain the object model, the directed acyclic graph, the difference between the working directory, the staging area, and the repository. You have to explain that a branch is a pointer, that a commit is a snapshot and not a diff, that the history is immutable until you rewrite it. Each of these statements is true and necessary and will cause a beginner's eyes to glaze over within thirty seconds.

The book handles this well. It starts with the basics and builds gradually. But "gradually" in Git still means confronting ideas that most developers never encounter in any other tool they use. No other developer tool requires you to understand a graph data structure to use it competently. No other tool has three different staging areas between your file and the server. No other tool lets you rewrite published history and then expects you to know when that is appropriate and when it will ruin your colleagues' afternoon.

This is the tension at the heart of the education problem. Git is not arbitrarily complex. Its complexity maps to real problems. Distributed version control, where every copy is a full repository with complete history, genuinely requires a more complex mental model than a centralized system where there is one server and everyone syncs to it. The staging area exists because sometimes you want to commit only some of your changes, not all of them. History rewriting exists because sometimes the story of how you got to a solution matters as much as the solution itself. These are real needs. But explaining them to someone who just wants to save their code and share it with their team is like teaching someone automotive engineering when they asked for driving lessons.

The Bootcamp Gap

Every year, tens of thousands of people graduate from coding bootcamps and enter the software industry. They have learned a programming language, maybe two. They have built projects. They can write code that works. And somewhere in their twelve or sixteen week program, they got maybe one day on Git. Sometimes two. Rarely more.

In that day they learned git add, git commit, git push. Maybe git pull. Maybe git clone. They learned that Git tracks their code and that GitHub is where code lives. They practiced the workflow: make changes, stage them, commit with a message, push to GitHub. If they were lucky, their instructor mentioned branches. If they were very lucky, they practiced creating a branch, switching to it, and merging it back.

Then they get their first job. And their team uses Git Flow, or GitHub Flow, or trunk-based development with feature flags. Their team has branch protection rules and required code reviews and automated tests that run before any merge. Their team has merge conflicts that span hundreds of lines across dozens of files. Their team has a colleague who insists on rebasing and another who insists that rebasing is dangerous, and a third who does something called interactive rebase that seems to involve rewriting the laws of physics.

The bootcamp graduate has none of the vocabulary for this. They do not know what HEAD means. They do not know what the reflog is, the safety net that records every move you make and lets you recover from almost any mistake. They do not know the difference between merge and rebase, except that both sometimes produce terrifying red text about conflicts. They do not know that git reset has three modes that do three very different things, and that using the wrong one can make their work disappear.

So they do what every developer in this situation does. They go to Stack Overflow. They find a command that seems to match their problem. They run it. Sometimes it works. Sometimes it makes things worse. Either way, they learn nothing about why. The emergency is over. The confusion remains. And the cycle repeats until they have been a professional developer for three years and still feel like a fraud every time they interact with their version control system.

Increasingly, the search bar is not even involved. The developer opens a chat window instead and types "fix my merge conflict." The AI produces a sequence of commands. The developer runs them. The conflict resolves. And the developer is no wiser than they were before, except now they have a new dependency, one that is faster than Stack Overflow and less likely to show them the ten other answers that might have taught them something. Whether this is better or worse than the old pattern is genuinely unclear. The AI can explain its reasoning if you ask, and sometimes people do ask, and sometimes that explanation plants a seed of understanding. But asking takes deliberate effort, and under deadline pressure nobody asks. They just copy the commands and move on.

This is not the bootcamps' fault, not entirely. They are trying to compress an enormous amount of material into a very short time, and Git is not the thing their students are paying to learn. But the result is a generation of developers who think of Git as a necessary evil, a hostile system they must appease with the correct incantation rather than a tool they direct with intention.

Why This Cannot Be Fixed

Here is the uncomfortable truth that every Git educator eventually confronts. You cannot simplify Git without lying, and the lies will hurt you later.

Take branching. The standard simplified explanation is that a branch is like making a copy of your code so you can work on something without affecting the main version. This is a fine mental model for about six months. Then you encounter a detached HEAD, where you are not on any branch at all, and the copy metaphor falls apart because nothing was copied. A branch in Git is a pointer. It is a file that contains a forty-character identifier pointing to a commit. Creating a branch writes one line to one file. That is why it is instant. But "a branch is a pointer to a commit" is not a useful explanation for someone who does not yet know what a commit is in any meaningful sense.

Or take the staging area. The simplified version is that git add tells Git which files you want to include in your next commit. True enough. But then someone adds a file, edits it again, commits, and finds that the second edit is not in the commit. Because git add stages the file's content at the moment you run it, not the file itself. The simplified explanation was a lie that cost someone twenty minutes of confusion and a frantic trip to Stack Overflow.

One of the reasons people found Git very hard to use was that most people who started without using Git were coming from a background of something CVS-like. The concepts are different. The commands are different. Git never even tried to look like CVS, quite the reverse.

Linus is right, and this cuts both ways. Git's refusal to pretend to be something simpler is what makes it powerful. Every abstraction it offers maps to something real in the object store. When you understand that model, Git becomes predictable. You can reason about state, recover from mistakes, construct exactly the history you want. But reaching that understanding requires crossing a chasm that most developers never cross, because most developers do not need to, most of the time. The three-command workflow works. It works until it does not, and then you are fifteen million views on a Stack Overflow question.

You can do things so many ways. You can often do the same or similar things different ways. And the best way to learn Git is probably to first only do very basic things.

This is where I think the education problem is actually two problems wearing a trench coat. The first is that Git's interface was built by and for kernel developers who already understood the concepts. The command names are inconsistent, the flags are cryptic, the error messages assume knowledge the reader does not have — and the error messages deserve a conversation of their own, which is coming next time. That problem is solvable, and people are solving it. Better error messages ship with every Git release. The new git switch and git restore commands split what used to be three different behaviors crammed into git checkout. The interface is slowly, carefully getting better.

The second problem is harder. Git models something genuinely complex. Distributed version control with immutable content-addressed history and cheap branching and merging is not a simple idea dressed up in complicated clothing. It is a fundamentally different way of thinking about files and time and collaboration. You cannot teach it in a day. You cannot reduce it to a cheat sheet. The people who understand Git well, the Katie Sylor-Millers and Julia Evanses and Scott Chacons, did not find a shortcut. They put in months of effort, drew the graphs, experimented with the edge cases, and built the mental model node by node.

The honest answer to "why is Git so hard to learn" is that it is a complex tool that rewards deep understanding and punishes shallow memorization, in an industry that optimizes for shipping fast and learning just enough. The fifteen million views on that Stack Overflow question are not a bug. They are the system working exactly as designed, a system where it is faster to look up the answer than to understand the tool.

But there is a hopeful thread in this story. Katie built a site in two hours that has helped millions. Julia spent eight months drawing graphs that make the invisible visible. Scott gave away a textbook that has been translated into dozens of languages. None of them waited for Git to fix itself. They stood between the tool and the people, and they translated. The education problem is real, and it may never fully go away, because the complexity is real too. But the translators keep coming. And every developer who goes from memorizing commands to understanding the graph underneath is one fewer panicked search at two in the morning. That is worth something.

Git status. The single most important command for anyone learning Git. Run it constantly. Run it before you do anything, run it after you do anything, run it when you are not sure what just happened.

The output tells you which branch you are on, which files are staged for the next commit, which files have been modified but not staged, and which files Git does not know about yet. It is your map. Every section of that output corresponds to a concept this series has covered. Once you can read git status without confusion, you understand Git.