01
Mental Model
The Git pipeline
edit → add → commit → push → PR → merge
Every change follows this pipeline. Understand where you are in it at all times.
02
What is HEAD?
In Git, HEAD = where you are currently working.
When HEAD points to a branch, your commits land on that branch. When HEAD points directly to a commit (not a branch), you are in detached HEAD state — commits are "floating" and not attached to any branch.
| State | HEAD points to | Behavior |
|---|---|---|
| On a branch | refs/heads/main → commit |
Commits are saved in that branch. Branch pointer moves forward. |
| Detached HEAD | A raw commit hash | Commits are not attached to any branch. They will be lost if you switch away without saving. |
Fix a detached HEAD
# You'll see this if detached:
# "HEAD detached at abc1234"
# Fix: create a branch to save your work
git checkout -b my-rescued-work
03
Safety Check
Do this first before any operation.
Verify your state
git branch --show-current # verify you are on the correct branch
git status # see what's staged, modified, untracked
Never work in detached HEAD — if you see
HEAD detached at ..., create a branch immediately with git checkout -b <name>.
04
Branches
Branch operations
git branch # list local branches
git branch --show-current # show current branch
git checkout -b <branch> # create + switch to new branch
git switch -c <branch> # same (newer syntax)
git branch -d <branch> # delete a local branch (safe — refuses if unmerged)
git branch -D <branch> # force-delete a local branch
05
Add / Commit / Push
Stage, commit, push
git add . # stage all changes
git add <file> # stage a specific file
git commit -m "msg" # commit with message
git push # push to remote (if upstream is set)
06
First Push (Set Upstream)
Link local branch to remote
git push -u origin <branch> # push + link local branch to remote
After this, git push / git pull work without specifying the remote.
07
Push to Another Branch
Push current work to a different remote branch
git push origin HEAD:<target-branch>
08
Pull Latest
Fetch + merge or rebase
git pull origin main # fetch + merge latest changes from main
git pull --rebase origin main # fetch + rebase (cleaner history, no merge commit)
09
Merge into Main
Standard merge workflow
git checkout main # switch to main
git pull origin main # make sure main is up to date
git merge <branch> # merge <branch> into main
git push origin main # push updated main to remote
10
Pull Request (CLI with GitHub CLI)
Create a PR from the terminal
gh pr create --base main --head <branch> --title "title" --body "description"
11
Undo / Fix Mistakes
Common undo operations
git restore <file> # discard unstaged changes in a file
git restore --staged <file> # unstage a file (keep changes in working tree)
git commit --amend -m "new msg" # fix the last commit message (before push)
git reset --soft HEAD~1 # undo last commit, keep changes staged
git stash # temporarily shelve changes
git stash pop # re-apply stashed changes
12
Inspect
View history and changes
git log --oneline -10 # last 10 commits, compact
git diff # unstaged changes
git diff --staged # staged changes (what will be committed)
git log --oneline --graph # visual branch history
13
Quick Reference Table
| Task | Command |
|---|---|
| See current branch | git branch --show-current |
| Create + switch branch | git checkout -b <branch> |
| Stage everything | git add . |
| Commit | git commit -m "msg" |
| First push | git push -u origin <branch> |
| Subsequent pushes | git push |
| Pull latest main | git pull origin main |
| Merge branch into main | git checkout main && git pull && git merge <branch> |
| Create PR | gh pr create --base main --head <branch> |
| Undo last commit (keep changes) | git reset --soft HEAD~1 |
| Discard file changes | git restore <file> |
| Stash work | git stash / git stash pop |