git cheatsheet

Quick-lookup reference · all essential commands

maindevelopfeature/*hotfix/*
⇄ Git Areas Flow
WORKSPACE       STAGING      LOCAL REPO    REMOTE REPO
    |               |               |               |
    | git add/mv/rm |               |               |
    |-------------->|               |               |
    |               |  git commit   |               |
    |               |-------------->|               |
    |               |               |               |
    |        git commit -a          |               |
    |------------------------------>|               |
    |               |               |               |
    | git reset     |               |               |
    | <file>        |               |               |
    |<--------------|               |               |
    |               |               |               |
    |        git reset <commit>     |               |
    |<------------------------------|               |
    |               |               |               |
    |               |               |  git push     |
    |               |               |-------------->|
    |               |               |               |
    |               |               |  git fetch    |
    |               |               |<--------------|
    |               |               |               |
    | git diff      |               |               |
    |xxxxxxxxxxxxxxx|               |               |
    |               |               |               |
    |        git diff HEAD          |               |
    |xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx||               |
    |               |               |               |
    |          git clone / pull                     |
    |<----------------------------------------------|
    |               |               |               |
⌂ Basics
Switch branchgit switch <branch>
Restore file (discard changes)git restore <file>
Restore file to stagedgit restore --staged <file>
Detached HEAD checkoutgit checkout <commit>
Clone repogit clone <url>
Init repogit init
Stage allgit add .
Commit with messagegit commit -m "feat: msg"
Skip staging, commit trackedgit commit -a -m msg
tipAmend last commitgit commit --amend

Subject ≤50 chars, present tense, no period. Body ≤72 chars: what & why.

↺ Reset
safeUndo commit, keep stagedgit reset --soft HEAD~1
Undo commit, unstage changesgit reset --mixed HEAD~1
dangerUndo commit, discard changesgit reset --hard HEAD~1
dangerDiscard all uncommitted changesgit reset --hard HEAD
dangerReset local to remote maingit fetch origin && git reset --hard origin/main
Reset file in Staging Areagit reset <commit> <file>
dangerOverwrite staging + working dirgit checkout <commit> <file>
Squash last N into one commitgit reset --soft HEAD~N && git commit

--soft: keeps staged · --mixed: unstages · --hard: discards

⇡ Rebase
Linear rebase onto remote maingit rebase origin/main
Interactive last 5 commitsgit rebase -i HEAD~5
Interactive from commitgit rebase -i <hash>
Continue after conflictgit rebase --continue
Abort rebasegit rebase --abort

In editor: pick · squash (s) · reword (r) · drop (d) · edit (e)

Squash via mergegit merge --squash <branch>
🍒 Cherry-pick
Apply a commit to current branchgit cherry-pick <hash>
Pick multiple commitsgit cherry-pick h1 h2 h3
Pick inclusive rangegit cherry-pick h1^..h2
Continue after conflictgit cherry-pick --continue
Abort cherry-pickgit cherry-pick --abort

Wrong branch commit? checkout target, cherry-pick, then reset --hard HEAD~1 on source.

📦 Stash
Save work temporarilygit stash
Stash with namegit stash push -m "name"
List stashesgit stash list
Apply & remove top stashgit stash pop
Apply without removinggit stash apply stash@{n}
Drop specific stashgit stash drop stash@{n}
Clear all stashesgit stash clear
🏷 Tags
Create lightweight taggit tag v1.0-lw
Create annotated taggit tag -a v1.0 -m "Release v1.0"
List all tagsgit tag
Show tag metadatagit show v1.0
Push single taggit push origin v1.0
Push all tagsgit push origin --tags
Delete local taggit tag -d v1.0.1
Delete remote taggit push origin --delete v1.0.1

Lightweight = pointer only. Annotated = full object with author, date, msg.

⑂ Branches
List local branchesgit branch
List all (local + remote)git branch -a
Branches merged into maingit branch --merged main
Create & switchgit switch -c <name>
safeDelete (safe)git branch -d <name>
dangerDelete (force)git branch -D <name>
Delete remote branchgit push origin --delete <name>

Workflow: main → develop → feature/* → develop → release/* → main + develop. hotfix/* branches off main.

☁ Remote / Sync
Fetch (no merge)git fetch origin
Pull (fetch + merge)git pull
Push branchgit push origin <branch>
Push & set upstreamgit push -u origin <branch>
dangerForce push rewritten historygit push --force --mirror origin
Show remotesgit remote -v
Add remotegit remote add origin <url>
🔍 Inspect
Working dir vs staginggit diff
Staging vs last commitgit diff --cached
Working dir vs HEADgit diff HEAD
Files changed in commitgit diff-tree -r <hash>
Status overviewgit status
Commit history (pretty)git log --oneline --graph
Last author per linegit blame <file>

git diff: working↔index · git diff HEAD: working↔last commit · git status: working↔index

⏪ Revert
safeCreate undo commit (safe for shared)git revert <hash>
Revert without auto-commitgit revert -n <hash>

Revert adds a new commit. Use instead of reset on shared/main branches.

git reset
moves pointer
git restore
local files only
git revert
adds undo commit
🗑 Remove / Clean
Untrack file (keep on disk)git rm --cached <file>
dangerRemove from all history (modern)git filter-repo --path <file> --invert-paths
dangerRemove sensitive text from historygit filter-repo --replace-text <(echo 'secret==>***')
Analyze repo structuregit filter-repo --analyze
Add to gitignoreecho "file" >> .gitignore

After filter-repo, force push with --force --mirror to overwrite remote history.

🔬 Bisect
Start bisect sessiongit bisect start
Mark current as badgit bisect bad
Mark known good commitgit bisect good <hash>
Skip untestable commitgit bisect skip
Exit & return to branchgit bisect reset

Git binary-searches commits. Mark each checkout bad/good until culprit is found.

🕑 Reflog
See all HEAD movementsgit reflog
Recover deleted branchgit checkout -b <name> HEAD@{n}
Show refloggit reflog show

Git keeps 90 days of HEAD history (30 for unreachable). Untracked files are NOT recovered. Run git gc to purge manually.

🪝 Git Hooks
Enable hook (remove .sample)mv pre-commit.sample pre-commit
Make executablechmod +x .git/hooks/pre-commit
pre-commitlint / format / tests — abort if exit 1
prepare-commit-msgauto-insert Jira ID or template
commit-msgenforce naming: feat: fix: docs:
pre-pushvalidate before upload
pre-receiveserver: reject policy violations
updateserver: per-branch rejection
post-receiveserver: trigger CI/CD webhook

Use Husky or pre-commit framework to share hooks — .git/ isn't tracked by VCS.

🌿 Branch Model
mainproduction-ready code
developnext release integration
feature/*branches off develop → merges to develop
release/*final prep before main
hotfix/*branches off main → merges to main + develop
⚡ Misc
List files changed in commitgit diff-tree -r <hash>
See per-line blamegit blame <file>
Show all movements of HEADgit reflog
Remove from tracking (keep disk)git rm --cached <file>
Stage patches interactivelygit add -p
Show configgit config --list
Set global usergit config --global user.name "Name"
Pretty one-line log with graphgit log --oneline --graph --all
git cheatsheet · workspace → staging → local repo → remote repo