Tool-belt series · Git · VS Code · GUI-first
Every Git tutorial is written for people who live in a terminal. You don't, and you don't need to — VS Code's Source Control panel does everything you'll actually do, and the GUI is genuinely better for the two things that matter most: reading a diff before you commit and resolving a merge conflict. This page is the mental model plus the five buttons, with no command line required.
You can click Commit and Sync without knowing what they do — right up until something goes sideways, and then you're stuck. The model underneath is genuinely simple: four concepts, five buttons. An hour here means you never again lose work, never again fear a conflict, and can undo almost anything.
Everything below is the GUI. There's a short table at the end mapping each button to the command it runs, purely so that when you paste an error into a chat and something suggests a command, you know which button you already pressed.
Forget the jargon for a moment. Git is a save system for a folder, with the ability to run parallel versions and merge them back. That's genuinely all it is.
A save point for the whole folder, with a note attached. Not a file save — a snapshot of everything, at a moment, that you can return to. Making one is cheap and you should make lots.
A parallel version of the folder. You go off, make save points, and the original is untouched the whole time. When you're happy, you merge it back. If you're not, you bin it and nothing was lost.
The shared copy on GitHub. Your machine has its own complete copy; nothing you do is visible to anyone else until you push. This is why you can experiment freely.
Between "I changed a file" and "I made a save point" there's a middle step: staging. You're saying these particular changes go in this commit. In VS Code it's the + next to each file — the difference between Changes (edited, not included) and Staged Changes (going into the next commit).
Why it exists: you often edit five files and only three belong to the thing you're describing. Staging lets you commit those three with an honest message, and the other two separately. If you never care, VS Code will offer to stage everything for you when you commit — and that's a perfectly reasonable way to work.
Third icon down the left-hand activity bar — the one that looks like a branching line. Or Ctrl+Shift+G. Nearly everything lives here.
Illustration of the layout — your VS Code will differ slightly by version and theme, but every element shown is in the same place.
This is the whole workflow. It doesn't get more complicated than this for 95% of what you do.
Before you touch anything, pull down what's changed. The ↻ in the bottom-left status bar, or ⋯ → Pull. Starting stale is the number one cause of the conflicts in section 4.
Click the branch name in the status bar → Create new branch… → type a name like fix-mobile-nav. You're now working in a parallel copy and main is safe no matter what you do.
Do this every time, even for small things. It costs three seconds and it means you can always abandon an idea cleanly.
Edit files, let Claude Code edit files, whatever. Files appear under Changes as you go. Nothing is recorded yet.
Click each file, read the diff, then + to stage it. To stage everything at once, hover Changes and click the + on that header row.
One line describing what changed and why. Your future self reads these when hunting for when something broke — "updates" tells them nothing.
Still local. Nothing has left your machine yet, and you can still change your mind.
The blue button becomes Publish Branch the first time, then Sync Changes afterwards. Once pushed, GitHub shows a Compare & pull request banner — click it, write a sentence, create the PR, merge it. That's the workflow you're already using.
The thing everyone dreads, and it's genuinely not that bad once you know what Git is asking you. Worth reading properly, because you hit this every time two branches touch the same card grid.
Git merges automatically whenever it can. It only stops when two branches changed the same lines of the same file and it can't tell which one you meant. That's the entire cause.
It is not an error, and nothing is broken or lost. Git is asking you one question: "which of these do you want — or both?" You answer, you commit, it's over.
This is exactly what happens when two feature branches each add a card to the same grid in index.html: both edited the same spot, and both changes are wanted. The answer is nearly always both.
Illustration of the inline conflict view. The four blue links appear above every conflict block. Green = your branch, blue = what you're merging in.
VS Code jumps you to the conflict and colours the two competing blocks.
Current is your branch. Incoming is what you're merging in. Ask plainly: which of these should the file end up with?
Accept Current, Accept Incoming, or Accept Both. For two cards in a grid, it's Accept Both nearly every time. If neither is right, just edit the text by hand and delete the marker lines yourself — that's completely legitimate.
Search the file for <<<<<<<. If any remain, you missed a conflict further down the file — a big file can have several.
Staging a conflicted file is how you tell Git it's resolved. Commit, and the merge completes.
The real confidence unlock. Once you know you can undo anything, you stop being cautious in the ways that slow you down.
| You want to… | Do this in the GUI | Safe? |
|---|---|---|
| Throw away edits to one file (not committed) | The ↺ icon next to the file in Changes | No undo — the edits are gone. See below. |
| Unstage a file | The − next to it under Staged Changes | Totally safe — your edits stay |
| Fix the message you just wrote | ⋯ → Commit → Undo Last Commit, retype, commit again | Safe if you haven't pushed |
| Undo a commit that's already pushed | Right-click the commit in the Graph / history → Revert | Safest option — adds an opposite commit, rewrites nothing |
| Get back a file version from this morning | Open the file → Timeline view at the bottom of Explorer → click a point → copy what you need | Read-only browsing — completely safe |
| Abandon a branch entirely | Switch to main, then delete the branch from the branch list |
Safe — main was never touched |
Committed work is extremely hard to lose permanently — Git keeps a log of where every branch has pointed for weeks, so even a "deleted" commit is usually recoverable by someone who knows where to look. Uncommitted work has no such protection.
Which reduces to one rule: commit early, commit messily. Tidy history is a nice-to-have. Not losing an afternoon's work is not.
You've already connected a workspace to GitHub, so this will look familiar — Fabric's Git integration is deliberately the same model with fewer buttons.
You don't need these. They're here so that when documentation or an AI answer mentions a command, you can map it to the button you already know.
| The button you click | What it runs |
|---|---|
| + on a file | git add file |
| Commit | git commit -m "your message" |
| Sync Changes | git pull then git push |
| Publish Branch | git push -u origin branch-name |
| Create new branch | git checkout -b branch-name |
| Switch branch | git checkout branch-name |
| ↺ Discard Changes | git restore file — the irreversible one |
| Revert (right-click a commit) | git revert <commit> |