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 add→git commit -m "msg"→git push. That’s 90% of your day. Everything else is for when things get interesting.