git system

stop clicking buttons to manage your code history.

The git documentation is sprawling — dozens of man pages, thousands of lines across them. You need about fifteen commands and you’ll handle 95% of everything version control throws at you.

You wanted to save your code. So you downloaded GitHub Desktop. Or GitKraken. Or SourceTree. You clicked “Clone.” You wrote some code. You looked at the “Changes” panel. You typed a message in a little text box. You clicked a green button. Your code was “committed.” You clicked another button. Your code was “pushed.” You have no idea what just happened, but it’s on GitHub now, so you moved on.

Then someone said “merge conflict” and your entire world stopped. The GUI showed you red highlights and green highlights and arrows and a three-pane view and you stared at it like it was an MRI of your own brain. You clicked “Accept Current” because it was the first button you saw. You broke the feature branch. You don’t know how to undo it. You’re Googling “git undo merge conflict” and finding Stack Overflow answers from 2014 with 47 different approaches, all of which start with “well, it depends.”

The command line won’t make merge conflicts fun. But it’ll make everything else faster, and when conflicts happen, you’ll understand what’s actually going on.

Unless you’re running Windows then wtf none of this applies to you. But hey, come to the dark side, go install WSL2 and you can follow along. We’ll wait. Impatiently.

If you’re lazy like me (all sysadmins are!) then click here for the git cheat sheet.


The basics: init, clone, status

Start a new repo

git init

Current directory is now a git repo. No GitHub account needed. No “Create Repository” dialog. Just a hidden .git folder that tracks everything.

Clone an existing repo

git clone git@github.com:user/repo.git

Downloads the entire repo — every file, every branch, every commit. You’re ready to work immediately.

Check what’s going on

git status

Shows what’s changed, what’s staged, what’s untracked. This is the command you should run before and after every operation. It’s your sanity check. Your GUI shows this in a sidebar; git shows it in text you can actually read.


The commit workflow

This is 80% of what you’ll do with git. Every day.

Stage files

git add file.txt
git add src/
git add -A

Staging means “I want these changes in my next commit.” git add file.txt stages one file. git add src/ stages a whole directory. git add -A stages everything. Be deliberate about what you stage — it’s better than blindly committing everything.

Commit

git commit -m "fix: resolve null pointer in user auth"

Saves a snapshot. The -m flag is the message. Write good messages. “fixed stuff” tells future-you nothing. “fix: resolve null pointer in user auth when session expires” tells future-you exactly what happened and why.

Stage and commit in one shot

git commit -am "update: add error handling to API client"

-a stages all tracked files that have been modified. Doesn’t include new (untracked) files — those still need git add first.


View history

Log

git log --oneline

One line per commit. Hash and message. Clean. Readable.

git log --oneline -20

Last 20 commits. Usually all you need.

See what changed in a commit

git show abc1234

Shows the full diff for that commit. What was added, what was removed, which files were touched.

See what you’ve changed (before committing)

git diff

Shows unstaged changes — what you’ve modified but haven’t added yet.

git diff --staged

Shows staged changes — what will go into your next commit. Review this before committing. Always.


Branches

Branches let you work on something without touching the main code. Your GUI puts this behind a dropdown menu. git does it in one command.

Create and switch to a new branch

git checkout -b feature/login

Creates the branch and switches to it in one shot. You’re now working on feature/login. Main is untouched.

Switch between branches

git checkout main
git checkout feature/login

Instant. No loading. No “switching context” spinner.

List branches

git branch

Shows all local branches. The one with the asterisk is where you are.

git branch -a

Shows local and remote branches.

Delete a branch

git branch -d feature/login

Deletes a branch that’s already been merged. -D (capital) force-deletes even if unmerged. Use with caution.


Merging

Merge a branch into main

git checkout main
git merge feature/login

Two commands. Switch to main, merge the feature in. If there are no conflicts, it’s done. If there are conflicts, git tells you which files, you fix them, then:

git add .
git commit -m "merge: feature/login into main"

The merge conflict (it’s not that scary)

When git can’t auto-merge, it marks the conflicts in the file:

<<<<<<< HEAD
your code on main
=======
their code from the feature branch
>>>>>>> feature/login

Pick the version you want (or combine them), remove the markers, save, git add, git commit. That’s it. Your GUI shows the same conflict with colored panels and buttons, but it’s the same decision — which code stays.


Pushing and pulling

Push to remote

git push origin main

Sends your commits to the remote repo. First time on a new branch:

git push -u origin feature/login

-u sets the upstream tracking. After that, git push alone works.

Pull from remote

git pull

Downloads and merges remote changes. If someone else pushed while you were working, this brings you up to date.

Fetch without merging

git fetch

Downloads remote changes but doesn’t merge them. Lets you inspect what’s new before incorporating it. Safer than git pull when you want to see what’s coming.


Undoing things

Unstage a file

git restore --staged file.txt

You staged something by accident. This unstages it. The changes are still in your working directory — nothing is lost.

Discard changes to a file

git restore file.txt

Reverts the file to the last committed version. Your changes are gone. Be sure.

Amend the last commit

git commit --amend -m "better commit message"

Changes the message of the most recent commit. Also lets you add forgotten files — git add forgotten.txt then git commit --amend.

Only amend commits you haven’t pushed yet. Amending pushed commits rewrites history and will make everyone on your team unhappy.

Revert a commit (safely)

git revert abc1234

Creates a new commit that undoes the changes from abc1234. History is preserved. This is the safe way to undo something that’s already been pushed.


Stash (save work for later)

You’re in the middle of something. You need to switch branches. Your changes aren’t ready to commit.

git stash

Saves your changes and gives you a clean working directory. Switch branches, do your thing, come back.

git stash pop

Restores your stashed changes. You’re back where you left off.

git stash list

Shows all your stashes. Because sometimes you stash three things and forget about two of them.


The flags that actually matter

Command What it does
git status What’s changed, staged, untracked.
git add FILE Stage a file for commit.
git commit -m "msg" Commit with a message.
git log --oneline Compact history.
git diff Unstaged changes. --staged for staged.
git checkout -b NAME Create and switch to a branch.
git merge BRANCH Merge a branch into the current one.
git push Send commits to remote.
git pull Fetch and merge remote changes.
git stash / git stash pop Temporarily shelve and restore changes.
git restore FILE Discard changes. --staged to unstage.
git revert HASH Safely undo a pushed commit.

“But GitHub Desktop—”

Oh, the GUI client. Let’s go.

“GitHub Desktop makes git easy.” GitHub Desktop makes a specific subset of git easy. Clone, commit, push. The moment you need to stash, rebase, cherry-pick, bisect, or do anything beyond the basics, you’re either lost in menus or switching to the terminal anyway. You’ve been learning a subset instead of the tool.

“GitKraken has a beautiful graph.” GitKraken’s graph is gorgeous. It’s a visual representation of your branch history with colors and lines and merge nodes. It’s also $50/year for the full version and uses 500MB of RAM to show you what git log --oneline --graph shows in 2MB.

“SourceTree is free.” SourceTree is Atlassian’s client. It’s free. It also has approximately 400 buttons, tabs, and panels. Every simple operation requires finding the right button in the right panel. git commit -m "msg" is one command. SourceTree’s commit workflow is: click “Commit” at the top, look at the diff panel, check the boxes next to files, type a message, click “Commit” at the bottom. Six clicks for one command.

“I don’t need to learn the command line for git.” You don’t. Until you do. And when something goes wrong — a bad merge, a lost commit, a detached HEAD — every solution involves the command line. Every Stack Overflow answer. Every blog post. Every coworker who knows how to fix it. They’ll all give you a command to run. You might as well understand what it does.

“The GUI shows me diffs visually.” git diff shows you diffs in your terminal. If you want a visual diff, git difftool opens your preferred diff viewer. Or pipe it to less and use color. You don’t need a 500MB application to see a red line and a green line.


git cheat sheet

You made it. Or you skipped straight here. Either way, no judgment. Copy and paste these. Pin them. Tattoo them on your forearm. Whatever works.

What you’re doing Command
Start a new repo git init
Clone a repo git clone URL
Check status git status
Stage files git add FILE or git add -A
Commit git commit -m "message"
View log git log --oneline -20
See changes git diff (unstaged) / git diff --staged
New branch git checkout -b feature/name
Switch branch git checkout main
Merge git merge feature/name
Push git push (or git push -u origin branch)
Pull git pull
Stash git stash / git stash pop
Undo staged file git restore --staged FILE
Discard changes git restore FILE
Undo a pushed commit git revert HASH
Amend last commit git commit --amend -m "new msg"

The workflow: git addgit commit -m "msg"git push. That’s 90% of your day. Everything else is for when things get interesting.

Back to the top, you overachiever.