Every Git tutorial assumes a terminal. VS Code's Source Control panel covers everything you'll actually do — and it's genuinely better for the two things that matter most: reading a diff before you commit and resolving a merge conflict.
Why bother understanding it at all
You can click Commit and Sync blind — until something goes sideways. The model underneath is simple: four concepts, five buttons. Know them and you never lose work, never fear a conflict, and can undo almost anything. (Command-line translations are in a table at the bottom, for when an AI answer suggests a command you've already clicked.)
01
The mental model — four things, in plain English
Git is a save system for a folder that can run parallel versions and merge them back. That's the whole idea.
One change, four stops. A branch is a parallel copy of this whole picture; a merge just reconciles two Local Repo boxes back into one.
Commit
A save point for the whole folder, not one file — a snapshot you can return to. Cheap; make lots.
Branch
A parallel version of the folder. The original stays untouched while you work. Merge it back when happy, bin it if not — nothing lost.
Remote
The shared copy on GitHub. Your machine holds its own complete copy — nothing's visible to anyone until you push.
And the fourth: the staging area — the one that confuses everybody
Between editing a file and making a save point sits staging — you choose which changes go in this commit. In VS Code that's the + next to each file: Changes (edited, not included) vs. Staged Changes (going into the next commit).
Why bother: if only some edits belong to what you're describing, stage just those. Otherwise let VS Code stage everything on commit — also fine.
The sentence that makes it clickChanges = what you've edited. Staged = what's going into the next save point. Commit = make the save point. Sync = share it. Everything else in the panel is a variation on this.
02
The Source Control panel — a guided tour
Third icon down the activity bar, or Ctrl+Shift+G. Nearly everything lives here.
The habit worth building firstRead every diff before you commit. Green is added, red is removed. Ten seconds per file catches the accidental deletion, the leftover debug line, and the file you didn't mean to touch.
1Source Control icon — third down the activity bar; badge = files changed.
2The ⋯ menu — everything that isn't a button: Pull, Push, Checkout to…, Undo Last Commit.
3Message box — one line saying what changed. Ctrl+Enter commits straight from here.
4Commit — the save point, local only. Becomes Publish Branch or Sync Changes once there's something to send.
5Staged Changes — going into this commit. − takes a file back out without touching your edits.
6Changes — edited, not included yet. Click the name for the diff; hover the row for ↺ and +.
7Status bar — branch name, then sync state. 1↑ = one commit waiting to push.
Schematic, not a screenshot — your version/theme will differ in detail. Those three row icons only appear on hover, which is why most people never find them.
03
The daily loop — six clicks, every time
This is the whole workflow. It doesn't get more complicated than this for 95% of what you do.
Only the two ends touch GitHub. Steps 2–5 are all local, which is what makes experimenting safe. Skipping step 1 is where most conflicts start.
Start from a fresh copy — Sync Changes
Pull down what's changed first: the ↻ in the status bar, or ⋯ → Pull. Starting stale is the top cause of conflicts.
Make a branch — click the branch name, bottom-left
Branch name → Create new branch… → name it, e.g. fix-mobile-nav. main stays safe no matter what — do this even for small changes, it costs three seconds.
Change things — normally
Edit files as normal. They appear under Changes — nothing's recorded yet.
Read the diffs, then stage — the + buttons
Click each file, read the diff, then + to stage. Hover the Changes header and click its + to stage everything at once.
Write a message and hit Commit
One line: what changed and why — "updates" tells your future self nothing. Still local; you can still change your mind.
Publish Branch / Sync Changes → then the PR in the browser
Blue button: Publish Branch the first time, Sync Changes after. Pushed → GitHub's Compare & pull request banner → write a sentence, create the PR, merge.
Commit more often than feels necessaryA commit is a save point, not a statement of completion. Ten small clear commits beat one giant one — and pinpoint exactly what broke.
04
Merge conflicts — what they actually are
Not as bad as it feels once you know what Git's actually asking. You'll hit this whenever two branches touch the same lines.
What's actually happening
Git merges automatically whenever it can, and only stops when two branches changed the same lines of the same file — it can't tell which you meant.
Nothing is broken or lost. Git is asking one question: which of these do you want — or both? Answer, commit, done.
Classic case: two branches each add a card to the same grid in index.html. Both are wanted — the answer is nearly always both.
Both sides are kept. Git fences them with marker lines and leaves the choice to you. The markers vanish the moment you click Accept, so the file below looks scarier than it is.
The four blue links appear above every conflict block. Green = your branch, blue = what's merging in.
Resolving one, click by click
Open the file — it's marked C in Source Control
VS Code jumps to the conflict and colours both competing blocks.
Read both sides and decide
Current = your branch. Incoming = what you're merging in. Which should the file end up with?
Click the answer
Accept Current, Accept Incoming, or Accept Both — usually Both for two added cards. Or edit by hand and delete the markers yourself.
Check no markers survive
Search for <<<<<<<. Any left means a conflict further down — big files can have several.
Save, stage, commit
Staging a conflicted file is how you tell Git it's resolved. Commit, and the merge completes.
The three-way Merge EditorResolve in Merge Editor gives yours/theirs/result side by side with checkboxes. Use it for anything messier than two added blocks.
How to stop having themConflicts come from branches drifting apart. Sync before you start, keep branches short-lived, and merge main in if a branch runs long — small conflicts now beat big ones later.
05
Undoing things — ranked by how much you'll want them
Once you know almost everything's undoable, you stop being cautious in 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
The one genuinely dangerous buttonDiscard Changes (the ↺) deletes uncommitted work with no way back — Git never had a copy. VS Code's local file history sometimes saves you, but don't rely on it. If unsure, commit first.
The safety net worth knowing about
Committed work is hard to lose — Git logs every place a branch has pointed for weeks, so even a "deleted" commit is usually recoverable. Uncommitted work has no such net.
One rule: commit early, commit messily. Tidy history is nice-to-have; not losing an afternoon's work isn't.
Source control shows changed items with the same status idea — edited here, in the repo, or both (a conflict).
Commit pushes workspace changes up. Update pulls repo changes down. Same push/pull, different words.
Branch out to a new workspace — no VS Code equivalent: an isolated workspace from a branch, so you don't touch what others are using.
PRs still happen on GitHub in the browser — that's the part the browser's good at.
Where it differs from codeFabric items serialise to JSON/metadata, so a conflict there is far harder to read than in HTML. Rule: avoid conflicts rather than resolve them — one person per item, short-lived branches, update before you start.
07
What each button runs — for translation only
You don't need these — they're here to map a suggested command back to the button you already clicked.
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>
Where the GUI genuinely beats the terminalReading a diff and resolving a conflict — side-by-side colour and click-to-accept beat staring at markers in a text file. Plenty of terminal-fluent people still switch to VS Code for exactly these two jobs.