Git Basics — The 15 Commands You'll Use Forever, and the Mental Model Behind Them
Even in an era when AI writes the code for you, you still type git yourself. The 15 commands a beginner needs — and the one mental model that makes all of them obvious.
Even when AI writes the code, version control is still on you. Claude can produce great code, but where it lives, how you undo a mess, and how you merge with other people's work — that's your job.
The good news: the core of git is 15 commands. The bad news: if you learn them as "things to memorize," you'll be afraid of git forever. The first merge conflict will freeze you.
This post teaches git by understanding, not memorization. One mental model, then 15 commands on top of it.
The mental model — four locations
Git is, in the end, a game of moving files between four locations.
[Working Dir] → [Staging] → [Local Repository] → [Remote]
(editing) (selected) (your computer) (GitHub, etc.)- Working directory — files open in your editor, the ones you're editing right now.
- Staging area (index) — what you've marked as "this is going into the next commit." This is git's special sauce.
- Local repository — the commit history on your machine, stored in
.git/. - Remote repository — GitHub, GitLab, somewhere on the internet.
Most commands just move files between these four places. add moves working dir → staging. commit moves staging → local repo. push moves local → remote. Hold this picture in your head and every command makes sense.
0. One-time setup — global config
The first thing to do after installing git. Your name and email get stamped into every commit.
git config --global user.name "Your Name"
git config --global user.email "you@example.com"
# Default branch name — modern convention is main, not master
git config --global init.defaultBranch main
# Line endings (Mac/Linux)
git config --global core.autocrlf input
# Aliases (optional)
git config --global alias.st status
git config --global alias.co checkout
git config --global alias.br branchVerify with:
git config --list1. git init / git clone — the two starting points
There are exactly two ways to make a repository.
Start a new one in an empty folder:
mkdir my-project
cd my-project
git initA .git/ folder appears. That folder is the git repository. Delete it and you have a normal folder again.
Clone someone else's:
git clone https://github.com/user/repo.git
git clone https://github.com/user/repo.git my-folder-name # rename target folderClone is more than a download — it also wires up the remote, so push / pull work immediately.
2. git status — the command you'll type most often
The biggest secret of people who are good at git: they run git status fifty times a day.
git statusIt shows you the current state in one screen:
- which branch you're on
- which files are modified
- what's in the staging area
- which files are untracked
Every next move starts with status. If you don't know what to do, run status. Shorthand:
git status -s # short
git status -sb # short + branch info3. git add — put it on the stage
git add file.txt # one file
git add src/ # everything under a folder
git add . # everything under the current folder
git add -A # everything in the repo
git add -p # pick hunks interactively (powerful)git add -p is the one to learn. When a single file contains several kinds of changes, git walks you through each hunk and asks "stage this one?" That's how you split one mess into clean, meaningful commits.
4. git commit — write it down for real
What you staged becomes a permanent record.
git commit -m "feat: add login flow"A good commit message's first line is under 50 characters, starts with an imperative verb. Same idea in any language:
feat: add login flow(good)added login(okay)i went ahead and added the login flow today(bad)
When you need a longer message:
git commit # opens your editor: subject line, blank line, bodyCommon variants:
git commit -am "..." # add + commit in one shot (only for already-tracked files)
git commit --amend # edit the last commit's message or contents (before pushing!)5. git log — read the history
See the commits that have piled up.
git log # everything
git log --oneline # one line per commit
git log --oneline --graph # with branch graph
git log --oneline --graph --all # all branches
git log -p # with diffs
git log -5 # most recent 5
git log --author="kim" # by author
git log --since="1 week ago" # by dateMy most-used combo:
git log --oneline --graph --all -20That one line shows you the shape of the repository's recent past at a glance.
6. git diff — what actually changed
For when you need to see exactly what's different.
git diff # working dir vs staging (unstaged changes)
git diff --staged # staging vs last commit (staged but not committed)
git diff HEAD # working dir vs last commit (all changes)
git diff main feature # differences between branches
git diff abc123 def456 # differences between commitsAlways git diff --staged before you commit. It catches the stray console.log or debug code you forgot was in there.
7. .gitignore — what to keep out
In the repository root, create a .gitignore file and list paths git should ignore.
# Dependencies
node_modules/
.venv/
__pycache__/
# Build output
dist/
build/
.next/
# Environment variables (always!)
.env
.env.local
.env.*.local
# OS
.DS_Store
Thumbs.db
# Editors
.vscode/
.idea/
*.swpLanguage-specific templates live at github/gitignore. Copy-paste.
8. git branch / git switch — branches
A branch is a parallel universe inside the same repository. When you switch from one branch to another, the files in your working directory change to match that branch's last state.
git branch # list branches
git branch feature/login # create a new branch (don't move)
git switch feature/login # move to a branch
git switch -c feature/login # create and move in one step (use this)
git switch main # back to main
git branch -d feature/login # delete (only if merged)
git branch -D feature/login # force delete (even if not merged)Older git used git checkout for both moving branches and restoring files — too overloaded, too confusing. Since git 2.23 the job is split:
git switch— change branchesgit restore— restore files
Use the new names. They're clearer.
The standard workflow shape:
git switch main # start from main
git pull # get latest
git switch -c feature/x # branch off
# ... work ...
git add . && git commit -m "feat: ..."
git push -u origin feature/x # first push of this branch9. git merge — bring branches together
Once a branch's work is done, it needs to land somewhere.
git switch main # move to the receiving branch
git merge feature/login # bring feature/login's commits into mainConflicts happen when both branches change the same lines of the same file in different ways. Git stops and tells you.
The conflict markers look like this:
<<<<<<< HEAD
const port = 3000;
=======
const port = 8080;
>>>>>>> feature/loginTo resolve:
- Open the file, decide what's right (or keep both)
- Delete the
<<<,===,>>>markers git add <file>git commit(git fills in a merge commit message for you)
To abort a merge in progress:
git merge --abortYou're back where you started.
10. git pull / git push — sync with the remote
Exchange commits with the remote.
git pull # fetch remote changes and merge into your branch
git push # send your commits to the remote
git push -u origin feature/x # first push (sets upstream)
git fetch # fetch only — no merge (safer pull)My recommended pattern: fetch first, look, then pull.
git fetch
git log --oneline ..origin/main # see what new commits are on the remote
git pull # merge if it looks fineWhen you're in a hurry, just git pull. But if a push is rejected (! [rejected]), it almost always means there are commits on the remote you don't have. Pull first, push again.
11. git restore — undo a file
The safest way to undo: roll a working-directory file back to its last committed state.
git restore file.txt # discard working-directory changes
git restore --staged file.txt # unstage (undo a previous `git add`)
git restore . # discard all changes (dangerous!)12. git reset — undo a commit
Undo a commit that's already been made. Three modes:
git reset --soft HEAD~1 # uncommit, keep changes staged
git reset HEAD~1 # uncommit, unstage, changes stay in working dir
git reset --hard HEAD~1 # nuke everything (commit, stage, working dir)HEAD~1 means "one commit before HEAD." HEAD~3 is "three commits before." To target a specific commit, use the hash:
git reset --hard abc12313. git revert — the safe undo
If reset rewrites history, revert adds a new line to history. It creates a new commit that applies the inverse of an old commit's changes.
git revert abc123reset can't safely touch pushed commits. revert is the only safe way to undo a commit that's already shared.
# Scenario: a bug commit you pushed yesterday needs to go away
git revert HEAD # creates a commit that undoes the last one
git push # push the undo commit, safely14. git stash — temporary shelf
You're mid-work, and you need to jump to another branch for a minute. Committing feels wrong; throwing away feels worse.
git stash # shelve current changes; working dir becomes clean
git stash list # what's on the shelf
git stash pop # pull the most recent stash back + remove it from the shelf
git stash apply # pull it back but leave it on the shelf
git stash drop # drop it from the shelf
git stash -u # include untracked filesClassic scenario:
# You're working on a feature and someone needs a hotfix on main
git stash
git switch main
# ... hotfix ...
git switch feature/x
git stash pop15. git reflog — the final safety net
"I just ran reset --hard — is the work gone forever?"
Probably not. Almost never.
git reflogGit records every time HEAD moved — commits, resets, checkouts, merges, all of it. Find the hash you want to recover and:
git reset --hard abc123 # jump back to that pointOr rescue just that commit onto a new branch:
git branch recovered abc123The daily loop — on one page
This is basically what most days look like:
# Morning — start fresh
git switch main
git pull
# Begin new work
git switch -c feature/something
# One cycle (repeat dozens of times)
# ... edit code ...
git status # what changed
git diff # how it changed
git add -p # pick meaningful chunks
git diff --staged # double-check before commit
git commit -m "feat: ..."
# Push to remote
git push -u origin feature/something
# When the work is done
git switch main
git merge feature/something # or via a PR
git branch -d feature/somethingFive common traps
The mistakes beginners run into most, and how to climb out.
1. "I committed .env"
git rm --cached .env # untrack
echo ".env" >> .gitignore # add to ignore list
git commit -m "chore: untrack .env"
# And rotate every leaked secret. Immediately.2. "My commit message is wrong"
git commit --amend -m "the right message" # before push only3. "Push was rejected"
Almost always: there are commits on the remote you don't have.
git pull # merge in
git push # try again4. "I branched off the wrong place"
# Should have branched from main, branched from feature/old
git switch feature/new
git rebase --onto main feature/old
# If that's too much, just copy the changes and start over from main5. "Yesterday's work disappeared"
git reflog # every HEAD movement, with hashes
git reset --hard <lost-hash>Closing — the real secret of git
The 15 commands above cover roughly 95% of what professional developers do in a typical week. The other 5% — rebase, cherry-pick, bisect, and friends — you'll learn when you need them.
The real secret to git is not being afraid of it.
Almost every git accident is recoverable. If it was committed, reflog can probably save it. If it wasn't pushed, it never left your laptop. If it was pushed, revert undoes it cleanly. The only truly unrecoverable case: uncommitted changes wiped by git reset --hard.
So the actual rule is simple — commit often. Every 30 minutes of work. The message doesn't have to be brilliant. If the commit exists, git becomes your safety net automatically.
The next post in this series will cover team workflows — rebase, cherry-pick, and the GitHub collaboration patterns that come after the basics.
Related writing
How to Land Your First Dev Job — It's Risk Reduction, Not an Exam
Landing a junior job isn't an exam that proves your knowledge. It's about reducing the employer's risk. Portfolio, résumé, applications, coding tests, and interviews step by step — plus what AI changed, in an honest field guide.
A Career Path for People Just Starting as Developers — The 2026 Version
Does it still make sense to become a developer when AI writes the code? Yes — but the path changed. An honest roadmap of what to learn and in what order, how to choose a first job, and what to avoid.