cheat sheet

Git Cheat Sheet

Every command, flag, and workflow pattern. Searchable, filterable by level, copy-ready.

/ to focus
level:
Git Command Explainer paste any git command
Command
Breakdown

Setup & Configuration

Quick reference
Set username
git config --global user.name
Init new repo
git init
Clone a repo
git clone <url>
View all config
git config --list

Identity & Editor

beginner
Set global username and email
git config --global user.name "Your Name" git config --global user.email "you@example.com"
Set default editor
git config --global core.editor "code --wait" # VS Code git config --global core.editor "vim"
Set default branch name
git config --global init.defaultBranch main
View config settings
git config --list # all settings git config --list --show-origin # with file paths git config user.name # single value
Config scopes: system, global, local
git config --system # /etc/gitconfig - all users git config --global # ~/.gitconfig - current user git config --local # .git/config - this repo (default) # local overrides global overrides system
Useful global aliases
git config --global alias.st status git config --global alias.co checkout git config --global alias.br branch git config --global alias.lg "log --oneline --graph --all"

Init & Clone

beginner
Initialize a new repository
git init # in current directory git init my-project # create new directory
Clone a repository
git clone <url> git clone <url> my-folder # into specific folder git clone --depth 1 <url> # shallow clone (faster) git clone --branch dev <url> # clone specific branch

Staging & Status

Quick reference
What's changed?
git status
Stage everything
git add .
Stage interactively
git add -p
Review staged changes
git diff --staged

Status & Diff

beginner
Check working tree status
git status git status -s # short format git status -sb # short + branch info
Diff - what's changed
git diff # unstaged changes git diff --staged # staged changes git diff HEAD # all changes vs last commit git diff main..feature # between branches git diff --stat # summary of files changed git diff --word-diff # word-level changes
List tracked files
git ls-files # all tracked files git ls-files --others --exclude-standard # untracked git ls-files -m # modified files

Adding & Removing Files

beginner
Stage files
git add file.txt # specific file git add . # all changes in current dir git add -A # all changes in repo git add src/ # entire directory
Interactive staging - stage hunks
git add -p # patch: choose hunks interactively git add -i # interactive menu # In patch mode: y=yes, n=no, s=split, q=quit, ?=help
Intent to add (stage new files for diffing)
git add --intent-to-add new-file.txt # Registers the file so git diff shows it as all-new # without actually staging its content yet
Unstage files (keep changes)
git restore --staged file.txt # modern git reset HEAD file.txt # classic
Discard working tree changes
git restore file.txt # discard changes in file git restore . # discard all unstaged changes
Remove / rename tracked files
git rm file.txt # delete file and stage removal git rm --cached file.txt # untrack but keep file on disk git mv old.txt new.txt # rename (stage automatically)

.gitignore

beginner
Common .gitignore patterns
node_modules/ .env *.log *.pyc !important.log # negate (don't ignore this) **/temp/ # in any directory
Search within tracked files
git grep "TODO" # search working tree git grep "function" HEAD~5 # search at a commit git grep -n "pattern" # show line numbers git grep -l "TODO" # filenames only git grep -i "fixme" # case-insensitive
Faster than grep for Git repos - respects .gitignore
Stop tracking an already-tracked file
git rm --cached .env # Then add .env to .gitignore and commit
Global ignore file (all repos)
git config --global core.excludesFile ~/.gitignore_global # Add patterns: .DS_Store, Thumbs.db, *.swp

Committing

Quick reference
Quick commit
git commit -m "message"
Stage tracked + commit
git commit -am "message"
Fix last commit
git commit --amend --no-edit
Show last commit
git show HEAD

Creating Commits

beginner
Commit staged changes
git commit -m "feat: add login page" git commit # opens editor
Stage all tracked files and commit
git commit -am "fix: correct typo in header" # -a stages modified tracked files (not new untracked)
Amend the last commit
git commit --amend -m "new message" # change message git commit --amend --no-edit # add staged files, keep message
Only amend commits not yet pushed - rewrites history
Conventional commit format
git commit -m "feat(auth): add OAuth login" git commit -m "fix(api): handle null response" git commit -m "docs: update README" git commit -m "chore!: breaking change"
Empty commit (trigger CI)
git commit --allow-empty -m "chore: trigger CI"

Inspecting Commits

beginner
Show commit details
git show # last commit git show HEAD # last commit (explicit) git show abc1234 # specific commit git show HEAD~2 # two commits ago git show --stat # files changed only
Resolve a commit SHA from any ref
git rev-parse HEAD # full SHA of HEAD git rev-parse --short HEAD # abbreviated SHA git rev-parse main # SHA of branch tip git rev-parse --abbrev-ref HEAD # current branch name
Useful in scripts: BRANCH=$(git rev-parse --abbrev-ref HEAD)

Branching

Quick reference
Create + switch branch
git switch -c <branch>
List branches
git branch
Switch branch
git switch main
Delete branch
git branch -d <branch>

Create, Switch & List

beginner
List branches
git branch # local branches git branch -r # remote tracking branches git branch -a # all branches git branch -v # with last commit info git branch --merged # merged into current git branch --no-merged # not yet merged
Create and switch branches
git switch -c feature/login # create + switch (modern) git checkout -b feature/login # create + switch (classic) git switch main # switch branch git switch - # return to previous branch
Rename and delete branches
git branch -m new-name # rename current branch git branch -d feature/done # safe delete (merged) git branch -D feature/abandon # force delete
-D discards all unmerged commits permanently
Create branch from specific commit or tag
git switch -c hotfix abc1234 git switch -c release-1.0 v1.0

Merging & Rebasing

Quick reference
Merge branch
git merge <branch>
Merge with commit
git merge --no-ff
Rebase onto main
git rebase main
Interactive rebase
git rebase -i HEAD~3

Merge

beginner
Merge strategies
git merge feature/login # fast-forward if possible git merge --no-ff feature/login # always create merge commit git merge --squash feature/login # squash all commits to one git merge --ff-only feature/login # abort if not fast-forward
Merge strategy options (ours / theirs)
git merge -X ours feature # conflicts: prefer our version git merge -X theirs feature # conflicts: prefer their version # Note: -X is the conflict resolution strategy, # not the same as --strategy=ours (which ignores theirs entirely)
Resolve merge conflicts
git status # see conflicted files # Edit files to resolve, then: git add file.txt # mark resolved git commit # complete the merge # Or abort: git merge --abort
Revert a merge commit
git revert -m 1 abc1234 # -m 1 means: keep parent 1 (the branch you merged into) # -m 2 would keep parent 2 (the branch you merged in)

Rebase

intermediate
Rebase current branch onto main
git rebase main git rebase --continue # after resolving conflict git rebase --abort # cancel
Reapplies commits on top of main - creates linear history
Interactive rebase - rewrite history
1 2 3 4 5 6 7 8 9
git rebase -i HEAD~3 # last 3 commits # In editor, change 'pick' to: # r / reword - change commit message # s / squash - meld into previous # f / fixup - squash, discard message # d / drop - remove commit # e / edit - pause to amend # b / break - stop here for inspection # Save and close editor to execute
Rebase --onto a different base
git rebase --onto main old-base feature # Moves commits from feature NOT in old-base onto main

Cherry-pick

intermediate
Apply specific commits to current branch
git cherry-pick abc1234 # single commit git cherry-pick abc1234 def5678 # multiple commits git cherry-pick abc1234..def5678 # range (exclusive start) git cherry-pick -n abc1234 # apply but don't commit git cherry-pick --continue / --abort

Remotes

Quick reference
List remotes
git remote -v
Fetch changes
git fetch origin
Pull with rebase
git pull --rebase origin main
Push branch + track
git push -u origin <branch>

Managing Remotes

beginner
View remotes
git remote # list names git remote -v # with URLs git remote show origin # full info about remote
Add, remove and rename remotes
git remote add origin <url> git remote remove origin git remote rename origin upstream git remote set-url origin <new-url>

Fetch, Pull & Push

beginner
Fetch remote changes (don't merge)
git fetch origin # fetch all branches git fetch --all # all remotes git fetch --prune # remove stale remote refs # fetch --prune vs remote prune: # fetch --prune = fetch + cleanup in one step git remote prune origin # cleanup only (no fetch)
Pull
git pull # fetch + merge git pull --rebase origin main # fetch + rebase git pull --ff-only # abort if not fast-forward
Push to remote
git push origin main git push -u origin feature/login # set upstream tracking git push origin --delete feature/done # delete remote branch
Force push
git push --force-with-lease # safe: fails if remote changed git push --force # overwrites remote no matter what
Always prefer --force-with-lease over --force on shared branches

History & Log

Quick reference
Visual branch graph
git log --oneline --graph --all
Filter by author/date
git log --author --since
Who changed what
git blame file.txt
Find when code added/removed
git log -S "search term"

git log

beginner
Basic log views
git log # full log git log --oneline # one line per commit git log --oneline --graph --all # all branches visual git log -5 # last 5 commits git log -p # with diffs (patch) git log -p -- file.txt # diffs for specific file
Filter log output
git log --author="Alice" git log --since="2 weeks ago" git log --grep="fix:" # by commit message git log --follow -- file.txt # file history (through renames) git log --stat # files changed per commit git log main..feature # commits in feature, not main
Custom log format
git log --format="%h %an %s" # %h=short hash %H=full hash %an=author # %s=subject %ar=relative date %d=refs
Pickaxe - find when code was added or removed
git log -S "functionName" # string added/removed git log -G "regex.*pattern" # regex in diff

Blame, Bisect & Refs

intermediate
git blame - who wrote each line
git blame file.txt git blame -L 10,20 file.txt # lines 10-20 only git blame -w file.txt # ignore whitespace git blame abc1234 -- file.txt # at specific commit
git bisect - binary search for a bug
1 2 3 4 5 6 7 8
git bisect start git bisect bad # current commit is broken git bisect good v1.2.0 # last known good commit/tag # Git checks out midpoint, test it, then: git bisect good # or git bisect bad # Repeat until Git finds the first bad commit git bisect reset # restore HEAD when done
Ref shortcuts
HEAD # current commit HEAD~1 # one commit before HEAD HEAD^ # first parent (same as HEAD~1) HEAD^2 # second parent (merge commit) v1.0 # tag main@{yesterday} # where main was yesterday

Undoing Changes

Quick reference
Safe undo (new commit)
git revert HEAD
Undo commit, keep staged
git reset --soft HEAD~1
Restore file from commit
git restore --source=HEAD~2
Find lost commits
git reflog

revert vs reset

intermediate
git revert - safe undo (creates new commit)
git revert HEAD # undo last commit git revert abc1234 # undo specific commit git revert -m 1 abc1234 # revert a merge commit git revert --no-commit HEAD # stage the revert, don't commit yet
Safe for shared branches - preserves history
git reset - move HEAD (rewrites history)
git reset --soft HEAD~1 # undo commit, keep staged git reset --mixed HEAD~1 # undo commit + unstage (default) git reset --hard HEAD~1 # undo commit + discard changes
--hard permanently discards your working tree changes
Only reset commits not yet pushed to shared branches
Restore a specific file from any commit
git restore --source=HEAD~2 -- file.txt git restore --source=abc1234 -- src/app.js # Restores the file without moving HEAD
Use this instead of git reset when you only want one file back

Reflog & Clean

intermediate
Recover lost commits with reflog
git reflog # full history of HEAD movements git reflog main # reflog for specific branch # Find the SHA, then restore: git switch -c recovered abc1234 git reset --hard abc1234
Reflog entries kept ~90 days by default
Clean untracked files
git clean -n # dry run - show what would be removed git clean -f # remove untracked files git clean -fd # also remove untracked directories git clean -fdx # also remove ignored files
Always run -n first - git clean cannot be undone

Stash

Quick reference
Stash changes
git stash
Restore + drop stash
git stash pop
List stashes
git stash list
Named stash
git stash push -m "name"

Stash Operations

intermediate
Save and restore stash
git stash # save tracked changes git stash push -u # include untracked files git stash push -m "wip: login" # with description git stash pop # restore latest + remove stash git stash apply # restore latest, keep stash git stash apply stash@{2} # restore specific stash
Inspect and manage stashes
git stash list git stash show -p # diff for latest git stash show stash@{1} # specific stash git stash drop stash@{0} # delete one stash git stash clear # delete all stashes
Create a branch from a stash
git stash branch wip-feature stash@{0} # Creates branch, checks it out, applies + drops stash
Stash only specific files
git stash push -m "partial" file1.js file2.css

Tags

Quick reference
Lightweight tag
git tag v1.0.0
Annotated tag
git tag -a v1.0.0 -m "..."
Push all tags
git push origin --tags
List tags by pattern
git tag -l "v1.*"

Creating & Managing Tags

intermediate
Lightweight vs annotated tags
git tag v1.0.0 # lightweight git tag -a v1.0.0 -m "Release 1.0.0" # annotated (preferred) git tag -a v0.9.0 abc1234 -m "Backfill" # tag a past commit
List, show and delete tags
git tag # list all tags git tag -l "v1.*" # filter by pattern git show v1.0.0 # show tag details git tag -d v1.0.0 # delete local tag git push origin v1.0.0 # push one tag git push origin --tags # push all tags git push origin --delete v1.0.0 # delete remote tag
Checkout a tag (detached HEAD)
git checkout v1.0.0 # detached HEAD state git switch -c hotfix/1.0.1 # branch from here

Power Commands

Quick reference
Search tracked files
git grep "TODO"
Multiple checkouts
git worktree add
Current branch name
git rev-parse --abbrev-ref HEAD
Search all history
git log --all --grep

Worktrees, Submodules & Sparse Checkout

advanced
git worktree - multiple checkouts of same repo
git worktree add ../hotfix hotfix/issue-42 # Work in ../hotfix while main dir stays on main git worktree list git worktree remove ../hotfix
Useful for reviewing PRs or hotfixes without stashing
Sparse checkout - only fetch specific folders (monorepos)
git sparse-checkout init git sparse-checkout set packages/frontend docs/ git sparse-checkout list # show active patterns git sparse-checkout disable # return to full checkout
Dramatically reduces checkout time for large monorepos
Submodules - embed a repo inside a repo
git submodule add <url> libs/shared git submodule update --init --recursive git clone --recurse-submodules <url> git submodule update --remote # update to latest

Scripting & Utilities

advanced
rev-parse - resolve any ref to SHA
git rev-parse HEAD # full SHA git rev-parse --short HEAD # short SHA git rev-parse --abbrev-ref HEAD # branch name git rev-parse --show-toplevel # repo root path # In scripts: BRANCH=$(git rev-parse --abbrev-ref HEAD) SHA=$(git rev-parse --short HEAD)
Find common ancestor of two branches
git merge-base main feature/login
Export repo snapshot (no .git folder)
git archive --format=zip HEAD -o release.zip git archive --format=tar.gz v1.0.0 -o v1.0.0.tar.gz
Count commits per author
git shortlog -sn git shortlog -sn --since="30 days ago"
format-patch and am - email-style patch workflow
# Create patch files from last 3 commits git format-patch -3 # produces .patch files git format-patch main..feature # range as patches # Apply a patch file git am 0001-my-change.patch git am --signoff *.patch # with sign-off trailer
rerere - replay recorded conflict resolutions
git config --global rerere.enabled true # Git now records how you resolve conflicts. # Next time the same conflict appears (e.g. repeated rebase), # Git resolves it automatically. git rerere # check status git rerere diff # show recorded resolution git rerere forget # forget a bad resolution
Maintenance and garbage collection
git gc # compress objects git gc --aggressive # thorough (slower) git prune # remove unreachable objects git fsck # verify integrity
Sign commits with GPG
git config --global user.signingkey <key-id> git commit -S -m "signed commit" git config --global commit.gpgsign true git log --show-signature
Rewrite history - remove a file from all commits
pip install git-filter-repo git filter-repo --path secrets.txt --invert-paths
Rewrites all commit SHAs - all contributors must re-clone after this

Workflows

Quick reference
Start a feature
switch -c → push -u
Sync with main
fetch + rebase origin/main
Merge a feature
merge --no-ff → push
Create a release
tag -a → push --tags

Feature Branch Workflow

intermediate
Full feature branch lifecycle
1 2 3 4 5 6 7 8 9 10 11
git switch main git pull # start from latest main git switch -c feature/my-feature # ... make changes ... git add -p # review hunks carefully git commit -m "feat: my feature" git fetch origin git rebase origin/main # rebase onto latest git push -u origin feature/my-feature # Open Pull Request → review → merge → delete branch git branch -d feature/my-feature # cleanup local

Hotfix Workflow

intermediate
Emergency fix on production
1 2 3 4 5 6 7 8 9 10
git switch main git pull git switch -c hotfix/issue-42 # ... fix the bug ... git commit -am "fix: resolve issue 42" git switch main git merge --no-ff hotfix/issue-42 git tag -a v1.0.1 -m "Hotfix 1.0.1" git push origin main --tags git branch -d hotfix/issue-42

Undo a Recent Push / Clean Up History

advanceddestructive
Undo a push to a shared branch
1 2 3 4 5 6 7
# Safe approach: revert the commit git revert HEAD git push # Destructive approach (only if no one else has pulled): git reset --hard HEAD~1 git push --force-with-lease
Force-pushing to shared branches rewrites history for all collaborators
Squash and clean before merging a PR
1 2 3 4 5 6 7
git fetch origin git rebase origin/main # rebase first git rebase -i origin/main # interactive: squash WIP commits # In editor: squash/fixup all WIP commits into one clean commit # Write a clear final commit message git push --force-with-lease # rewrite your remote branch

Syncing a Fork

intermediate
Keep your fork in sync with upstream
1 2 3 4 5 6 7
# One-time setup git remote add upstream <original-repo-url> # Sync regularly git fetch upstream git switch main git rebase upstream/main git push origin main

Most developers don't memorize every git command. They keep a reliable git cheat sheet nearby and look things up when needed. That's not a weakness. That's just practical.

Git has a lot of commands. The git commit and branch management basics are easy enough. But then you need to undo a merge, recover a lost commit with git reflog, or figure out the difference between git fetch vs git pull, and things get tricky fast.

This guide covers the most used git commands across the full workflow: from git init and git clone through staging, committing, branching, merging, rebasing, and working with remote repositories on GitHub or GitLab.

Quick reference. No fluff.

What Is a Git Cheat Sheet

A git cheat sheet is a condensed reference of the most common git commands, grouped by workflow stage so you can find what you need without digging through full documentation.

It's not a replacement for learning git. It's a practical tool for when you already know what you need to do but can't remember the exact syntax.

Git adoption rose from 87.1% in 2016 to 93.87% by 2025 (RhodeCode), making it by far the most widely used version control system in professional software development.

Use Case

Who Benefits Most

Daily workflow commands

Junior developers building habits

Branch and merge operations

Mid-level devs on multi-branch projects

Recovery and revert commands

Senior devs managing production repos

Remote sync (push/pull/fetch)

Teams working across GitHub or GitLab

The official Pro Git book (by Scott Chacon and Ben Straub) remains the most comprehensive reference, but it's not something you keep open mid-sprint. That's what this guide is for.

Git Setup and Configuration Commands

Before running a single git commit, your local environment needs to know who you are. Git uses this identity to attach to every commit you make.

Core setup commands:

Authentication setup:

50% of developers have run into SSH key or authentication issues at some point (Hutte, 2024). Getting this right upfront saves a lot of frustrating Permission denied errors later.

Setting git config --global init.defaultBranch main renames the default branch from master to main globally. Most teams now expect main as the default, so it's worth setting this early.

Repository Initialization and Cloning

Two ways to start working with Git: create a new repository locally, or copy an existing one from a remote source like GitHub or GitLab.

Starting a new repository

git init creates a .git folder in the current directory, turning it into a tracked repository.

Running git init my-project creates a new subfolder named my-project with Git already initialized inside it.

After init, connect to a remote:

git remote add origin https://github.com/user/repo.git
git branch -M main
git push -u origin main

Cloning an existing repository

git clone <url> copies the full remote repository to your machine, including all branches, tags, and commit history.

Useful clone variations:

GitHub hosts over 630 million repositories as of 2025 (CoinLaw). Most developers clone far more often than they init from scratch.

Once cloned, the remote is automatically named origin. You can verify this with git remote -v.

Staging, Committing, and Tracking Changes

This is the core daily loop. Stage changes, commit them with a message, repeat.

The three-state model:

State

What it means

Working directory

Files you've changed but not staged

Staging area (index)

Changes marked for the next commit

Repository

Committed history

git status shows exactly where each changed file sits across these three states.

git add <file> stages a specific file. git add . stages everything in the current directory. git add -p (patch mode) lets you stage specific chunks of a file, which is genuinely useful for keeping commits focused.

Committing:

80% of senior developers recommend committing frequently with small, incremental changes rather than large batches (Hutte, 2024). It keeps history readable and makes git bisect actually usable.

git diff shows unstaged changes. git diff --staged shows what's staged and about to be committed. Both are worth running before you commit.

How to undo changes in Git

Discarding working directory changes:

Unstaging files:

Undoing commits:

git revert <commit-hash> creates a new commit that reverses a previous one without rewriting history. This is the safe option on shared branches where others may have already pulled.

70% of developers have run a git command without fully understanding what it would do (Hutte, 2024). git reset --hard is one of the most dangerous to misuse, as it permanently removes uncommitted changes.

Git Branch Commands

Branching is how parallel work happens without stepping on anyone else's code. Every feature, bug fix, or experiment should live on its own git branch.

Viewing branches:

Creating and switching:

Renaming and deleting:

GitHub reached over 150 million developers by 2025, with over 5 billion contributions made in 2024 alone (electroiq). Most of that activity happens across branches.

45% of developers have had work affected by a colleague's force push to a shared branch (Hutte, 2024). Protecting main and develop branches at the repository level is standard practice for a reason.

Merging and Rebasing

Two approaches for bringing branch changes together. They produce the same end result but write very different histories.

git merge

git merge feature/login integrates changes from feature/login into the current branch.

Merge types:

Merge conflicts happen when two branches edit the same lines differently. Nearly 90% of developers have faced merge conflicts at some point (Hutte, 2024), and they consume an estimated 10-20% of developer time in collaborative projects.

Resolving a conflict:

# After git merge reports conflicts:
git status                    # see which files conflict
# Edit files to resolve markers
git add <resolved-file>
git merge --continue

git rebase

git rebase main replays your current branch's commits on top of main, creating a linear history.

When to use which:

git rebase -i HEAD~3 opens interactive rebase for the last 3 commits. From here you can squash, reword, reorder, or drop commits entirely.

Roughly 55% of developers find git rebase challenging and error-prone (Hutte, 2024). If you're new to it, always rebase on a local branch you haven't pushed, or use git push --force-with-lease instead of --force when you do push a rebased branch.

git cherry-pick <commit-hash> applies a single specific commit from any branch onto the current one. Useful for backporting a fix without merging an entire branch.

Remote Repository Commands

Working with remotes is where Git becomes a collaboration tool. These commands sync your local work with GitHub, GitLab, or Bitbucket.

75% of developers run git fetch or git pull at least once daily to stay in sync with remote changes (Hutte, 2024).

Command

What it does

When to use

git remote -v

Lists remotes with URLs

Verify origin setup

git fetch origin

Downloads without merging

Check changes before merging

git pull origin main

Fetch + merge in one step

Quick sync on trusted branches

git push origin main

Uploads local commits

After committing locally

git push --force-with-lease

Force push with safety check

After rebasing a branch

fetch vs pull

git fetch: downloads new commits, branches, and tags from the remote but makes no changes to your working directory.

Your local branches stay untouched. You review what came in, then decide whether to merge.

git pull: runs git fetch followed immediately by a merge (or rebase, if configured).

Use git pull --rebase to replay your local commits on top of the fetched changes instead of creating a merge commit. Most teams prefer this for keeping a cleaner history.

Learn more about what git fetch does and what git pull does if you want the full breakdown of each.

Pushing to remote

git push -u origin feature/login pushes the branch and sets it as the upstream, so future git push commands on that branch need no extra arguments.

git push --force-with-lease is the safer alternative to git push --force. It checks whether the remote has commits you haven't seen yet and rejects the push if it does, preventing you from accidentally overwriting someone else's work.

Only 30% of developers regularly prune stale remote-tracking branches using git remote prune origin (Hutte, 2024). Running it occasionally keeps git branch -r output clean.

Git Log and History Commands

git log is how you read a repository's story. Getting comfortable with its flags turns a wall of output into a useful audit trail.

Core log commands:

92% of Git projects enforce code review before merging (Hutte, 2024). Knowing how to read commit history is a practical skill for reviewing what changed and when.

git log -- path/to/file shows only commits that touched a specific file. Useful when you're debugging and want to trace a file's change history without reading through unrelated commits.

Inspecting and blaming

git show <commit-hash> displays the full diff and metadata for one specific commit.

git diff main..feature/login compares two branches directly, showing what's in feature/login that isn't in main.

For line-level accountability:

Around 40% of developers use git blame to trace changes to specific lines (Hutte, 2024).

git shortlog -sn summarizes commits per author across the entire repo, sorted by volume. Teams use this during retrospectives to get a quick sense of contribution distribution.

Git Stash Commands

Stash is for the exact moment when you're mid-task on one branch and need to switch to another without committing half-finished work.

Around 52% of developers use git stash regularly for saving uncommitted changes (Hutte, 2024), but 28% have lost work because of confusion about how stash pop and apply differ.

Saving and retrieving stashes

git stash saves both staged and unstaged changes, then reverts the working directory to match the last commit.

git stash push -m "WIP: login form validation" saves with a label, which matters once you have multiple stashes.

Retrieving:

The key difference: pop removes the stash after applying, apply keeps it. If you're unsure whether the apply worked cleanly, use apply first and manually drop it after confirming.

Managing and cleaning stashes

git stash show -p shows a full diff of the most recent stash before applying it.

Cleanup commands:

git stash -u (or --include-untracked) stashes untracked files too. Without this flag, newly created files that haven't been staged yet will stay in your working directory.

Stashes are stored on a stack. The most recent one is always stash@{0}.

Tags, Cherry-Pick, and Advanced Commands

These commands don't come up every sprint, but when you need them, they're hard to work around.

Approximately 15% of developers have used git bisect to locate the exact commit that introduced a bug (Hutte, 2024). It's underused, considering how much time it saves in large repos.

Tagging releases

Git tags mark specific commits as significant, usually for version releases. They don't move as branches do.

Tag type

Command

Use case

Lightweight

git tag v1.0.0

Quick local marker

Annotated

git tag -a v1.0.0 -m "Release 1.0"

Production releases, includes metadata

Push to remote

git push origin v1.0.0

Share a tag with the team

Push all tags

git push origin --tags

Sync all local tags

Semantic versioning conventions like MAJOR.MINOR.PATCH are the standard way to name annotated tags in most projects.

Cherry-pick and bisect

git cherry-pick: applies a single commit from another branch onto your current one.

Common use case: a bug fix lands on main and you need it in a hotfix/v2 branch without merging everything else.

git cherry-pick a1b2c3d

git bisect: binary searches through commit history to find where a bug was introduced.

git bisect start
git bisect bad              # current commit is broken
git bisect good v1.2.0      # this tag was working
# Git checks out the midpoint; you test, then run:
git bisect good             # or: git bisect bad
# Repeat until Git identifies the culprit commit
git bisect reset            # exit bisect mode

On large repositories with hundreds of commits, bisect narrows the search down to the exact bad commit in around 7 steps.

Git reflog

git reflog records every time HEAD moved, including resets and branch switches. It's the recovery tool for commits that seem lost.

After running git reset --hard by mistake, git reflog shows you the commit hash from before the reset. You can restore it with git checkout -b recovery-branch <hash>.

git clean removes untracked files from the working directory:

The Linux kernel repository, one of the oldest active Git projects in existence, uses git bisect as a standard debugging step during kernel release cycles (CommandLinux, 2025).

FAQ on Git Cheat Sheet

What is the most useful git command to know?

git status is the one command worth running constantly. It shows your working directory state, staged changes, and untracked files at a glance. Most developers check it before every commit to avoid staging the wrong files.

What is the difference between git fetch and git pull?

git fetch downloads remote changes without touching your working directory. git pull fetches and immediately merges. Use fetch when you want to review changes first, pull when you're ready to sync directly.

How do I undo the last git commit without losing my changes?

Run git reset --soft HEAD~1. This moves the commit back to staged, so your work stays intact. If you want it unstaged instead, use git reset --mixed HEAD~1. Both are safe on local branches.

What does git stash do?

git stash temporarily saves uncommitted changes and reverts your working directory to the last commit. Use it when switching branches mid-task. Retrieve saved work later with git stash pop or git stash apply.

How do I resolve a git merge conflict?

Open the conflicting file and look for <<<<<<<, =======, and >>>>>>> markers. Edit the file to keep the correct version, remove all markers, then run git add on the file and complete the merge with git merge --continue.

What is the difference between git merge and git rebase?

Both integrate branch changes, but git rebase rewrites history into a linear sequence while git merge preserves the full branch context with a merge commit. Use rebase on local feature branches, merge on shared ones.

How do I delete a local and remote branch in git?

Delete locally with git branch -d branch-name. Force delete with -D if the branch is unmerged. Remove the remote branch with git push origin --delete branch-name. You can learn more in the guide on how to delete a branch in Git.

What does git clone do?

git clone copies a full remote repository to your machine, including all branches, tags, and commit history. The remote is automatically named origin. Add a folder name after the URL to clone into a custom directory.

How do I view the commit history in git?

Run git log for the full history. Use git log --oneline for a compact view. Add --graph --decorate to visualize branches. Filter by author with --author="Name" or by date with --since and --until flags.

What is git reflog and when should I use it?

git reflog records every movement of HEAD, including resets and branch switches. Use it after accidentally running git reset --hard to recover the lost commit hash. It's essentially an undo log for your local repository.