Git Commands Every Developer Should Know (2026 Cheat Sheet)

Git is the single most important tool in a developer's daily workflow. Yet most developers use maybe 20% of Git's commands and reach for Stack Overflow when anything goes wrong. This cheat sheet covers everything from daily essentials to the commands that save you when things go sideways.

Initial Setup

git config --global user.name "Your Name"
git config --global user.email "you@example.com"
git config --global core.editor "code --wait"     # VS Code as default editor
git config --global init.defaultBranch main        # use "main" for new repos
git config --list                                  # view all config

Starting a Repository

git init                          # new repo in current directory
git init my-project               # new repo in a new directory
git clone https://github.com/org/repo.git          # clone remote
git clone https://... my-dir      # clone into custom directory
git clone --depth 1 https://...   # shallow clone (no history — faster)

The Daily Workflow

# 1. Check what's changed
git status                        # show working tree status
git status -s                     # short format (M=modified, A=added, ?=untracked)
git diff                          # unstaged changes
git diff --staged                 # staged changes (what will be committed)
git diff HEAD                     # all changes since last commit

# 2. Stage changes
git add file.txt                  # stage one file
git add src/                      # stage entire directory
git add -p                        # interactively stage hunks (pick which lines to add)
git add .                         # stage everything in current directory (use carefully)

# 3. Commit
git commit -m "feat: add user authentication"
git commit                        # opens editor for multi-line message
git commit -am "fix: typo"        # stage all tracked files + commit in one step (skips untracked)

# 4. Push
git push                          # push to tracked upstream
git push origin main              # explicit remote and branch
git push -u origin feature/auth   # set upstream tracking for new branch

Branching

# View branches
git branch                        # local branches (* = current)
git branch -a                     # local + remote branches
git branch -v                     # show last commit on each branch

# Create and switch
git switch -c feature/payments    # create + switch (modern syntax)
git checkout -b feature/payments  # same, older syntax

# Switch branches
git switch main
git checkout main                 # equivalent

# Rename
git branch -m old-name new-name   # rename local branch

# Delete
git branch -d feature/done        # safe delete (refuses if unmerged)
git branch -D feature/abandoned   # force delete (even if unmerged)
git push origin --delete feature/done  # delete remote branch

Merging and Rebasing

# Merge (preserves history, creates a merge commit)
git switch main
git merge feature/auth            # merge feature into main
git merge --no-ff feature/auth    # always create merge commit (even if fast-forward possible)
git merge --squash feature/auth   # squash all feature commits into one staged change

# Rebase (rewrites history — linear history, no merge commits)
git switch feature/auth
git rebase main                   # replay feature commits on top of main

# Interactive rebase — edit, squash, reorder commits
git rebase -i HEAD~3              # interactive rebase of last 3 commits
# In the editor: pick, squash (s), fixup (f), reword (r), drop (d)

# Abort a rebase if it goes wrong
git rebase --abort

# After resolving conflicts during rebase
git add conflicted-file.txt
git rebase --continue

Working with Remotes

git remote -v                          # list remotes
git remote add origin https://...      # add remote
git remote set-url origin https://...  # change remote URL

git fetch                              # download remote changes (no merge)
git fetch origin                       # explicit remote
git pull                               # fetch + merge (or rebase with --rebase)
git pull --rebase                      # fetch + rebase instead of merge

git push                               # push current branch
git push --force-with-lease            # force push safely (fails if someone else pushed)
# Never: git push --force (overwrites others' work without warning)

Viewing History

git log                            # full history
git log --oneline                  # one line per commit
git log --oneline --graph          # ASCII branch graph
git log --oneline -10              # last 10 commits
git log --author="Alice"           # commits by author
git log --since="2 weeks ago"      # commits since date
git log -p                         # show diff for each commit
git log -- src/auth/               # commits that touched this path
git log main..feature/auth         # commits in feature not in main

git show abc1234                   # show a specific commit
git show HEAD                      # show last commit
git show HEAD:src/index.ts         # show file as it was at HEAD

git blame src/index.ts             # show who changed each line
git blame -L 10,25 src/index.ts   # specific line range

Stashing

Stash saves your uncommitted changes temporarily so you can switch branches or pull without losing work:

git stash                          # stash all uncommitted changes
git stash push -m "WIP: auth form" # stash with a message
git stash push -p                  # interactively choose what to stash
git stash --include-untracked      # also stash new files

git stash list                     # list all stashes
git stash pop                      # apply latest stash and remove it
git stash apply stash@{2}          # apply specific stash (keep it in the list)
git stash drop stash@{0}           # delete a specific stash
git stash clear                    # delete all stashes

# Create a branch from a stash
git stash branch feature/from-stash stash@{0}

Undoing Mistakes

This section is the most important — knowing how to undo things safely prevents data loss:

# Undo staging (keep changes in working directory)
git restore --staged file.txt      # unstage a file
git restore --staged .             # unstage everything

# Discard working directory changes (IRREVERSIBLE)
git restore file.txt               # discard changes to a tracked file
git restore .                      # discard all working directory changes
git clean -fd                      # delete untracked files and directories

# Amend the last commit (title or content — only if not pushed)
git commit --amend -m "corrected message"
git commit --amend --no-edit      # add staged changes to last commit, keep message

# Undo the last commit (keep changes staged)
git reset --soft HEAD~1

# Undo the last commit (keep changes unstaged)
git reset HEAD~1

# Undo the last commit and discard changes (IRREVERSIBLE)
git reset --hard HEAD~1

# Undo a pushed commit safely (creates a new "undo" commit)
git revert HEAD                    # revert last commit
git revert abc1234                 # revert a specific commit
git revert HEAD~3..HEAD            # revert last 3 commits

# Find a deleted commit or file
git reflog                         # history of all HEAD movements
git checkout abc1234 -- src/lost.ts  # restore a specific file from any commit

Tags

git tag v1.0.0                     # lightweight tag on current commit
git tag -a v1.0.0 -m "Release 1.0"  # annotated tag (preferred — includes metadata)
git tag -a v1.0.0 abc1234          # tag a specific commit

git tag                            # list tags
git show v1.0.0                    # show tag details

git push origin v1.0.0             # push a specific tag
git push origin --tags             # push all tags

git tag -d v1.0.0                  # delete local tag
git push origin --delete v1.0.0    # delete remote tag

Useful Everyday Shortcuts

# Find which commit introduced a bug (binary search)
git bisect start
git bisect bad                     # current commit is broken
git bisect good v1.0.0             # last known good commit
# Git checks out midpoints — test each one, then:
git bisect good   # or git bisect bad
git bisect reset  # when done

# Find what changed in a file between two commits
git diff v1.0.0 v2.0.0 -- src/auth.ts

# Copy a commit from another branch (without merging the whole branch)
git cherry-pick abc1234

# See the file tree at a specific commit
git ls-tree HEAD src/

# Show all files Git is tracking
git ls-files

# Remove a file from Git tracking without deleting it
git rm --cached .env               # stops tracking .env but keeps the file on disk

# Ignore whitespace when diffing or merging
git diff -w
git merge -X ignore-space-change

The .gitignore File

# .gitignore — files/patterns Git will not track
node_modules/
dist/
.env
.env.local
*.log
.DS_Store
.vscode/
coverage/

# Check why a file is ignored
git check-ignore -v file.txt

# Force-add an ignored file (use sparingly)
git add -f .env.example

# Refresh after updating .gitignore (stop tracking files that are now ignored)
git rm -r --cached .
git add .
git commit -m "chore: update gitignore"

Commit Message Conventions

A consistent commit message format makes git log useful. The most widely adopted convention is Conventional Commits:

# Format: <type>(optional scope): <description>
feat: add user authentication
fix: prevent duplicate email registration
docs: update API endpoint documentation
style: format with prettier
refactor: extract user service from controller
test: add unit tests for auth middleware
chore: upgrade dependencies to latest
perf: add Redis caching to product listing endpoint
ci: add GitHub Actions deployment workflow

Summary

The commands you'll use 90% of the time: status, add, commit, push, pull, switch, merge, and log --oneline. The commands that save you when things go wrong: stash, reset --soft HEAD~1, revert, and reflog. Bookmark this page and refer back to the undoing-mistakes section whenever you need to dig yourself out of a Git situation.

Frequently Asked Questions

What's the difference between git merge and git rebase?

git merge integrates changes by creating a merge commit — the branch history is preserved, showing exactly when branches diverged and reconnected. git rebase replays your commits on top of the target branch, creating a linear history with no merge commits. Merge is safer for shared branches (doesn't rewrite history). Rebase is better for keeping feature branch history clean before merging to main. Never rebase commits that have been pushed to a shared remote branch — it rewrites history and will conflict with everyone else's copy.

How do I resolve a merge conflict?

When a conflict occurs, Git marks the conflicting sections in the file with <<<<<<< HEAD, =======, and >>>>>>> markers. Open the file, decide which version to keep (or combine them), remove the markers, and save. Then git add the-file.txt and git commit (for merge) or git rebase --continue (for rebase). VS Code's built-in merge editor shows "Accept Current", "Accept Incoming", and "Accept Both" buttons — easier than editing markers manually. You can also use git mergetool to open a configured visual merge tool.

How do I undo a git push?

If only you pushed the commit and no one else has pulled it: git reset HEAD~1 (undo locally), then git push --force-with-lease. If others have already pulled the commit, use git revert HEAD instead — this creates a new commit that undoes the changes, preserving the history that others have already synced. Never git push --force on a shared branch — it will corrupt other developers' git history.

What is git reflog and when should I use it?

git reflog shows a chronological history of where HEAD has pointed — every checkout, commit, rebase, reset, and merge. It's your safety net when you've lost commits. If you accidentally did git reset --hard and lost commits, git reflog shows the commit hash from before the reset. Then git reset --hard abc1234 gets you back. Reflog entries are kept for 90 days by default. This is why "I accidentally deleted my commits" is almost always recoverable if you act within 90 days.