Git
Updated: May 20, 2026Categories: Git
Printed from:
Complete Git Cheatsheet
Table of Contents
- Git Configuration
- Repository Creation & Cloning
- Basic Workflow
- Branching & Merging
- Remote Repositories
- Git Tree & History
- Inspecting Code (blame, grep, pickaxe)
- Undoing Changes
- Stashing
- Tags
- .gitignore & File Tracking
- Git Hooks
- Signing Commits & Tags (GPG / SSH)
- Git LFS (Large File Storage)
- Sparse Checkout & Partial Clone
- Advanced Commands
- Git Aliases
- Troubleshooting
- Quick Reference Commands
Git Configuration
Initial Setup
Bash
1234567891011121314151617181920212223242526# Set global username and email
git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"
# Set default branch name
git config --global init.defaultBranch main
# Set default editor
git config --global core.editor "code --wait" # VS Code
git config --global core.editor "vim" # Vim
# Enable colored output
git config --global color.ui auto
# Set default pull strategy (Git 2.27+)
git config --global pull.rebase false # merge (default)
git config --global pull.rebase true # rebase
git config --global pull.ff only # fast-forward only
# Cache credentials (HTTPS)
git config --global credential.helper cache # in-memory (15 min)
git config --global credential.helper 'cache --timeout=3600'
git config --global credential.helper store # plaintext (use with care)
git config --global credential.helper osxkeychain # macOS
git config --global credential.helper manager # Windows / Git Credential Manager
View Configuration
Bash
1234567891011121314# List all configuration
git config --list
# View specific config
git config user.name
git config user.email
# View config with location (system / global / local)
git config --list --show-origin
git config --list --show-scope
# Edit config interactively
git config --global --edit
Repository Creation & Cloning
Create New Repository
Bash
12345678# Initialize new repository
git init
git init <directory-name>
# Initialize with specific branch
git init --initial-branch=main
git init -b main
Clone Repository
Bash
1234567891011121314151617181920# Clone repository
git clone <url>
git clone <url> <directory-name>
# Clone specific branch
git clone -b <branch-name> <url>
# Shallow clone (limited history)
git clone --depth 1 <url>
# Clone with submodules
git clone --recurse-submodules <url>
# Partial clone (Git 2.19+) - fetch blobs on demand
git clone --filter=blob:none <url>
# Bare clone (no working tree, for mirrors)
git clone --bare <url>
git clone --mirror <url>
Basic Workflow
Check Status & Add Files
Bash
1234567891011121314# Check repository status
git status
git status -s # Short format
git status -sb # Short + branch info
# Add files to staging area
git add <file>
git add . # Add all files in current dir
git add *.js # Add all JS files
git add -A # Add all files (including deleted)
git add -u # Add only modified/deleted (no new)
git add -p # Interactive: review each hunk
git add -N <file> # Track file without staging contents
Commit Changes
Bash
1234567891011121314151617181920# Commit staged changes
git commit -m "Commit message"
# Commit with title + body
git commit -m "Title" -m "Description"
# Add and commit in one step (tracked files only)
git commit -am "Commit message"
# Amend last commit (message and/or contents)
git commit --amend
git commit --amend -m "New message"
git commit --amend --no-edit # Keep message, update contents
# Empty commit (useful for triggering CI)
git commit --allow-empty -m "Trigger CI"
# Signed commit (GPG/SSH - see Signing section)
git commit -S -m "Signed commit"
View Changes
Bash
123456789101112131415161718192021# Show differences
git diff # Working dir vs staging
git diff --staged # Staging vs last commit (alias: --cached)
git diff HEAD # Working dir vs last commit
git diff <commit1> <commit2> # Between two commits
git diff <branch1>..<branch2> # Between branches
# Show changes in specific file
git diff <file>
git diff --staged <file>
# Word-level / character-level diff
git diff --word-diff
git diff --word-diff=color
# Stat summaries
git diff --stat
git diff --shortstat
git diff --name-only
git diff --name-status
Branching & Merging
Branch Operations
Bash
123456789101112131415161718192021222324252627282930# List branches
git branch # Local branches
git branch -r # Remote branches
git branch -a # All branches
git branch -vv # Show upstream tracking
git branch --merged # Branches merged into current
git branch --no-merged # Branches not yet merged
# Create branch
git branch <branch-name>
git branch <branch-name> <commit-hash>
# Switch branches
git checkout <branch-name>
git switch <branch-name> # Git 2.23+ (preferred)
# Create and switch to new branch
git checkout -b <branch-name>
git switch -c <branch-name> # Git 2.23+
git switch -c <branch> --track origin/<branch>
# Rename branch
git branch -m <new-name> # Rename current
git branch -m <old-name> <new-name>
# Delete branch
git branch -d <branch-name> # Safe delete (must be merged)
git branch -D <branch-name> # Force delete
git push origin --delete <branch> # Delete remote branch
Merging
Bash
12345678910111213141516# Merge branch into current branch
git merge <branch-name>
# Merge with no fast-forward (always create merge commit)
git merge --no-ff <branch-name>
# Squash merge (combine all commits into one)
git merge --squash <branch-name>
# Fast-forward only (fail if merge needed)
git merge --ff-only <branch-name>
# Abort / continue merge
git merge --abort
git merge --continue
Rebasing
Bash
12345678910111213141516171819202122# Rebase current branch onto another
git rebase <branch-name>
# Interactive rebase (reorder, squash, edit, drop)
git rebase -i <commit-hash>
git rebase -i HEAD~3 # Last 3 commits
# Rebase onto a different base
git rebase --onto <new-base> <old-base> <branch>
# Update feature branch with main (preserve merges)
git rebase --rebase-merges main
# Auto-squash fixup! / squash! commits
git commit --fixup=<commit>
git rebase -i --autosquash <base>
# Continue / abort / skip rebase
git rebase --continue
git rebase --abort
git rebase --skip
Remote Repositories
Remote Management
Bash
123456789101112131415161718192021# List remotes
git remote
git remote -v # Verbose (shows URLs)
git remote show origin # Detailed info
# Add remote
git remote add <name> <url>
git remote add origin <url>
# Remove remote
git remote remove <name>
# Rename remote
git remote rename <old-name> <new-name>
# Change remote URL
git remote set-url <name> <new-url>
# Set multiple push URLs (push to multiple remotes)
git remote set-url --add --push <name> <url2>
Push & Pull
Bash
12345678910111213141516171819202122232425262728293031# Push to remote
git push <remote> <branch>
git push origin main
git push -u origin main # Set upstream tracking
# Push all branches / tags
git push --all origin
git push --tags
git push --follow-tags # Push commits + annotated tags
# Safer force push (refuses if remote moved)
git push --force-with-lease
git push --force-with-lease=<ref>:<expected-sha>
# Delete remote branch
git push origin --delete <branch>
git push origin :<branch> # Old syntax
# Pull from remote
git pull # Fetch + merge
git pull --rebase # Fetch + rebase
git pull --ff-only # Fail unless fast-forward
git pull <remote> <branch>
# Fetch without merging
git fetch
git fetch <remote>
git fetch --all
git fetch --prune # Remove deleted remote refs
git fetch origin <branch>:<local-branch> # Fetch into new local branch
Git Tree & History
Viewing Commit History
Bash
123456789101112131415161718192021222324# Basic log
git log
git log --oneline # Condensed format
git log --graph # Show branch graph
git log --all # All branches
git log -n 5 # Last 5 commits
# Pretty formats
git log --pretty=format:"%h - %an, %ar : %s"
git log --pretty=oneline
git log --pretty=short
git log --pretty=full
git log --pretty=fuller
# Custom format with colors
git log --pretty=format:"%C(yellow)%h%C(reset) - %C(green)%an%C(reset), %C(blue)%ar%C(reset) : %s"
# Patch / stats per commit
git log -p # Show diffs
git log --stat # Files changed + insertions/deletions
git log --shortstat
git log --name-only
git log --name-status
Git Tree Visualization
Bash
123456789101112131415# Tree view with graph
git log --graph --pretty=oneline --abbrev-commit
git log --graph --all --decorate --oneline
# Compact tree view
git log --oneline --graph --all
# Show branch structure
git show-branch
git show-branch --all
# Rich tree visualization
git log --graph --abbrev-commit --decorate --all \
--format=format:'%C(bold blue)%h%C(reset) - %C(bold cyan)%aD%C(reset) %C(bold green)(%ar)%C(reset)%C(bold yellow)%d%C(reset)%n %C(white)%s%C(reset) %C(dim white)- %an%C(reset)'
Filtering History
Bash
12345678910111213141516171819202122232425# Filter by author / committer
git log --author="John Doe"
git log --committer="John Doe"
# Filter by date
git log --since="2025-01-01"
git log --until="2025-12-31"
git log --since="2 weeks ago"
git log --after="yesterday"
# Filter by commit message
git log --grep="bug fix"
git log --grep="fix" -i # Case-insensitive
git log --grep="A" --grep="B" --all-match
# Filter by file or path
git log <file>
git log -p <file> # Show changes
git log --follow <file> # Follow renames
git log -- <path>
# Show commits that changed specific lines / function
git log -L <start>,<end>:<file>
git log -L :<function>:<file>
Show Specific Commits
Bash
123456789101112131415# Show commit details
git show <commit-hash>
git show HEAD
git show HEAD~1 # Previous commit
git show HEAD^ # Same as HEAD~1
git show HEAD^^ # 2 commits back
# Show only files changed
git show --name-only <commit-hash>
git show --stat <commit-hash>
# Show tree structure of a commit
git ls-tree <commit-hash>
git ls-tree -r <commit-hash> # Recursive
Inspecting Code
git blame — who changed what
Bash
12345678910# Annotate every line with last author/commit
git blame <file>
git blame -L 10,30 <file> # Only lines 10–30
git blame -L :<function>:<file> # Lines of a function (with regex)
git blame -w <file> # Ignore whitespace changes
git blame -C <file> # Detect copy/move within file
git blame -CCC <file> # Detect copy/move across files
git blame --ignore-rev <sha> # Skip noisy refactor commits
git config blame.ignoreRevsFile .git-blame-ignore-revs
git grep — search the tree
Bash
1234567git grep "pattern"
git grep -n "pattern" # Show line numbers
git grep -i "pattern" # Case-insensitive
git grep -l "pattern" # Filenames only
git grep "pattern" <commit> # Search a specific revision
git grep -e "A" --and -e "B"
Pickaxe — find when text was introduced or removed
Bash
12345git log -S"text" # Commits that add/remove "text"
git log -G"regex" # Commits whose diff matches regex
git log -S"text" --source --all
git log -p -S"text" -- <path>
Undoing Changes
Working Directory
Bash
1234567891011# Discard changes in working directory
git checkout -- <file>
git restore <file> # Git 2.23+ (preferred)
# Discard all changes
git checkout -- .
git restore .
# Restore file from a specific commit
git restore --source=<commit> <file>
Staging Area
Bash
12345678# Unstage files
git reset HEAD <file>
git restore --staged <file> # Git 2.23+
# Unstage all files
git reset HEAD
git restore --staged .
Commits
Bash
12345678910111213141516171819202122# Soft reset (keep changes staged)
git reset --soft HEAD~1
# Mixed reset (keep changes, unstaged) — default
git reset HEAD~1
git reset --mixed HEAD~1
# Hard reset (discard all changes)
git reset --hard HEAD~1
# Keep reset (refuses if local changes would be lost)
git reset --keep <commit>
# Reset to specific commit
git reset --hard <commit-hash>
# Revert commit (create new commit that undoes changes)
git revert <commit-hash>
git revert HEAD
git revert -n <commit> # Stage revert without committing
git revert <a>..<b> # Revert a range
Stashing
Basic Stashing
Bash
1234567891011121314151617181920212223242526# Stash changes
git stash
git stash push -m "Work in progress"
# List stashes
git stash list
# Show stash diff
git stash show stash@{0}
git stash show -p stash@{0}
# Apply stash (keeps it in the list)
git stash apply # Apply latest stash
git stash apply stash@{1} # Apply specific stash
# Pop stash (apply and remove)
git stash pop
git stash pop stash@{1}
# Drop stash
git stash drop
git stash drop stash@{1}
# Clear all stashes
git stash clear
Advanced Stashing
Bash
123456789101112131415# Stash including untracked files
git stash -u
git stash push -u -m "WIP with new files"
# Stash including ignored files
git stash -a
# Stash specific files / paths
git stash push <file1> <file2>
git stash push -p # Interactive (per-hunk)
# Create branch from stash
git stash branch <branch-name>
git stash branch <branch-name> stash@{1}
Tags
Creating Tags
Bash
1234567891011121314# Lightweight tag
git tag <tag-name>
git tag v1.0.0
# Annotated tag
git tag -a <tag-name> -m "Tag message"
git tag -a v1.0.0 -m "Release version 1.0.0"
# Signed tag (GPG/SSH)
git tag -s v1.0.0 -m "Signed release"
# Tag specific commit
git tag <tag-name> <commit-hash>
Managing Tags
Bash
12345678910111213141516171819# List tags
git tag
git tag -l "v1.*" # Pattern matching
git tag --sort=-creatordate # Newest first
# Show tag details
git show <tag-name>
git tag -v <tag-name> # Verify signature
# Delete tag
git tag -d <tag-name> # Local
git push origin --delete <tag-name> # Remote
git push origin :refs/tags/<tag> # Older syntax
# Push tags
git push origin <tag-name> # Single tag
git push origin --tags # All tags
git push --follow-tags # Only annotated tags reachable from pushed commits
.gitignore & File Tracking
.gitignore basics
Bash
123456789# Patterns (one per line) — placed in .gitignore at any level
# Comments start with #
*.log # Ignore all .log files
build/ # Ignore build directories
!important.log # Negation — re-include
/secrets.env # Anchored to .gitignore location
**/temp # Match at any depth
docs/*.pdf # Only PDFs at this level
Useful tracking commands
Bash
12345678910111213141516171819# Check why a file is ignored
git check-ignore -v <file>
# Stop tracking a file but keep it locally
git rm --cached <file>
git rm -r --cached <directory>
# Globally ignore (across all repos)
git config --global core.excludesfile ~/.gitignore_global
# Don't track local changes to a tracked file (use sparingly)
git update-index --assume-unchanged <file>
git update-index --no-assume-unchanged <file>
git ls-files -v | grep '^h' # List assume-unchanged files
# Mark a file as intentionally locally modified
git update-index --skip-worktree <file>
git update-index --no-skip-worktree <file>
Git Hooks
Hooks live in .git/hooks/ (per-repo). Make them executable (chmod +x).
Bash
1234567891011121314151617181920# Common client-side hooks
.git/hooks/pre-commit # Before commit is created (lint, tests)
.git/hooks/prepare-commit-msg # Edit commit message template
.git/hooks/commit-msg # Validate commit message (e.g. conventional commits)
.git/hooks/post-commit # After commit succeeds
.git/hooks/pre-push # Before push (run tests)
.git/hooks/pre-rebase # Before rebase starts
# Server-side hooks
.git/hooks/pre-receive
.git/hooks/update
.git/hooks/post-receive
# Bypass hooks for one command
git commit --no-verify -m "skip hooks"
git push --no-verify
# Share hooks across team (Git 2.9+) — set a hooks path
git config core.hooksPath .githooks
Signing Commits & Tags
GPG signing
Bash
123456789101112131415161718# Generate / list keys
gpg --full-generate-key
gpg --list-secret-keys --keyid-format=long
# Configure Git to sign with GPG
git config --global user.signingkey <KEY-ID>
git config --global commit.gpgsign true
git config --global tag.gpgsign true
# Sign one commit / tag explicitly
git commit -S -m "Signed commit"
git tag -s v1.0.0 -m "Signed tag"
# Verify
git log --show-signature
git verify-commit <commit>
git verify-tag <tag>
SSH signing (Git 2.34+)
Bash
1234567git config --global gpg.format ssh
git config --global user.signingkey ~/.ssh/id_ed25519.pub
git config --global commit.gpgsign true
# Allowed signers file (to verify others' commits)
git config --global gpg.ssh.allowedSignersFile ~/.ssh/allowed_signers
Git LFS
Bash
12345678910111213141516171819# One-time install
git lfs install
# Track large file types
git lfs track "*.psd"
git lfs track "*.zip"
git add .gitattributes
# Normal workflow — LFS handles big files transparently
git add design.psd
git commit -m "Add design"
git push
# Inspect / migrate
git lfs ls-files
git lfs status
git lfs migrate import --include="*.psd"
git lfs prune
Sparse Checkout & Partial Clone
Bash
1234567891011121314# Partial clone (don't download all blobs)
git clone --filter=blob:none <url>
git clone --filter=tree:0 <url>
# Sparse checkout (only check out a subset of paths)
git sparse-checkout init --cone
git sparse-checkout set src/app docs
git sparse-checkout list
git sparse-checkout disable
# Non-cone mode (gitignore-style patterns)
git sparse-checkout init --no-cone
git sparse-checkout set "/*" "!/build/"
Advanced Commands
Cherry Pick
Bash
123456789101112131415161718# Apply commit to current branch
git cherry-pick <commit-hash>
# Cherry pick multiple commits
git cherry-pick <commit1> <commit2>
# Cherry pick range (exclusive..inclusive)
git cherry-pick <start-commit>..<end-commit>
git cherry-pick <start>^..<end> # Inclusive both ends
# Stage without committing
git cherry-pick -n <commit>
# Continue / abort / skip
git cherry-pick --continue
git cherry-pick --abort
git cherry-pick --skip
Bisect (Find Bug)
Bash
123456789101112131415# Start bisecting
git bisect start
git bisect bad # Current commit is bad
git bisect good <commit> # Known good commit
# Continue bisecting
git bisect good # Current commit is good
git bisect bad # Current commit is bad
# Automate with a script (exit 0 = good, non-zero = bad)
git bisect run ./test.sh
# End bisecting
git bisect reset
Submodules
Bash
12345678910111213141516171819202122# Add submodule
git submodule add <repository-url> <path>
# Initialize submodules
git submodule init
# Update submodules
git submodule update
git submodule update --init --recursive
git submodule update --remote # Pull latest from submodule's branch
# Clone repository with submodules
git clone --recurse-submodules <url>
# Run a command in every submodule
git submodule foreach 'git pull origin main'
# Remove a submodule
git submodule deinit -f <path>
git rm -f <path>
rm -rf .git/modules/<path>
Worktree
Bash
12345678910111213# Add worktree (work on multiple branches at once, no re-clone)
git worktree add <path> <branch>
git worktree add -b <new-branch> <path> <base>
# List worktrees
git worktree list
# Move / lock / remove worktree
git worktree move <path> <new-path>
git worktree lock <path>
git worktree remove <path>
git worktree prune
Reflog (your safety net)
Bash
1234567891011121314# Show local ref history (also for HEAD)
git reflog
git reflog show <branch>
git reflog --date=iso
# Recover a "lost" commit
git checkout <sha-from-reflog>
git branch recover <sha-from-reflog>
git reset --hard HEAD@{2} # Go back 2 ref moves
# Expire old reflog entries
git reflog expire --expire=now --all
git gc --prune=now
Notes
Bash
12345678# Attach metadata to a commit without changing it
git notes add -m "Reviewed by Alice" <commit>
git notes show <commit>
git notes list
git notes remove <commit>
git push origin refs/notes/*
git fetch origin refs/notes/*:refs/notes/*
Rerere (reuse recorded resolution)
Bash
12345# Remember how you resolved conflicts so Git can replay it
git config --global rerere.enabled true
git rerere status
git rerere diff
Maintenance (Git 2.29+)
Bash
1234git maintenance start # Schedule background optimization
git maintenance run --task=gc
git maintenance stop
Git Aliases
Useful Aliases
Bash
12345678910111213141516# Set up common aliases
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.st status
git config --global alias.unstage 'reset HEAD --'
git config --global alias.last 'log -1 HEAD'
git config --global alias.visual '!gitk'
# Advanced aliases
git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"
git config --global alias.tree "log --graph --pretty=oneline --abbrev-commit --all"
git config --global alias.amend "commit --amend --no-edit"
git config --global alias.uncommit "reset --soft HEAD~1"
git config --global alias.cleanup "!git branch --merged | grep -vE '^\\*|main$|master$|develop$' | xargs -n 1 git branch -d"
Troubleshooting
Common Issues
Bash
12345678910111213141516171819202122232425262728293031# Check repository integrity
git fsck
git fsck --full --strict
# Garbage collection
git gc
git gc --aggressive --prune=now
# Clean untracked files
git clean -f # Files
git clean -fd # Files and directories
git clean -fdx # Also remove ignored files
git clean -n # Dry run
# Resolve merge conflicts
# 1. Edit conflicted files (look for <<<<<<< / ======= / >>>>>>>)
# 2. git add <resolved-files>
# 3. git commit (or git merge --continue / git rebase --continue)
git mergetool # Launch configured merge tool
git checkout --ours <file> # Keep our version
git checkout --theirs <file># Keep their version
# Find lost commits
git reflog
git reflog show <branch>
git fsck --lost-found
# Recover lost commits
git checkout <commit-hash>
git branch <new-branch-name> <commit-hash>
Configuration Issues
Bash
1234567891011121314151617# Fix line ending issues
git config --global core.autocrlf true # Windows
git config --global core.autocrlf input # Linux/Mac
git config --global core.autocrlf false # Disable
# Ignore file permissions
git config core.fileMode false
# Set default merge tool
git config --global merge.tool vimdiff
git config --global merge.tool vscode
git config --global mergetool.vscode.cmd 'code --wait $MERGED'
# Set default diff tool
git config --global diff.tool vscode
git config --global difftool.vscode.cmd 'code --wait --diff $LOCAL $REMOTE'
Performance
Bash
123456789101112131415161718# Pack references
git pack-refs --all
# Optimize repository
git repack -ad
# Prune remote branches
git remote prune origin
git fetch --prune
# Check repository size
git count-objects -vH
# Find biggest objects in history
git rev-list --objects --all \
| git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' \
| awk '$1=="blob"' | sort -k3 -n | tail -20
Quick Reference Commands
Daily Workflow
Bash
123456git status # Check status
git add . # Stage all changes
git commit -m "message" # Commit changes
git push # Push to remote
git pull # Pull from remote
Branch Workflow
Bash
123456git switch -c feature-branch # Create + switch
git switch feature-branch # Switch to branch
git merge feature-branch # Merge branch (from target)
git branch -d feature-branch # Delete branch
git push -u origin feature-branch # Push + track upstream
Emergency Commands
Bash
12345678git stash # Quick save
git reset --hard HEAD # Undo all changes
git clean -fd # Remove untracked files
git reflog # Find lost commits
git restore <file> # Discard file changes
git restore --staged <file> # Unstage file
git push --force-with-lease # Safer force push
Conventional Commits (popular convention)
text
12345678910111213<type>(<scope>): <subject> feat: a new feature fix: a bug fix docs: documentation only style: formatting (no code change) refactor: code change that is neither feature nor fix perf: performance improvement test: adding or fixing tests chore: tooling, build, deps ci: CI configuration revert: reverts a previous commit
Note: Replace
<placeholder>values with actual names, URLs, or commit hashes as needed. Commands marked "Git 2.x+" require a minimum Git version.
Continue Learning
Discover more cheatsheets to boost your productivity