Git Cheat Sheet
Configuration
Section titled “Configuration”# Set identitygit config --global user.name "Your Name"git config --global user.email "you@example.com"
# Set default branch namegit config --global init.defaultBranch main
# Set default editorgit config --global core.editor "nvim"
# Enable colorgit config --global color.ui auto
# Set aliasesgit config --global alias.co checkoutgit config --global alias.br branchgit config --global alias.ci commitgit config --global alias.st statusgit config --global alias.lg "log --oneline --graph --all"
# View configgit config --listgit config --global --listgit config user.nameCreating Repositories
Section titled “Creating Repositories”# Initialize new repogit initgit init my-project
# Clone existing repogit clone https://github.com/user/repo.gitgit clone git@github.com:user/repo.gitgit clone https://github.com/user/repo.git my-foldergit clone --depth 1 https://... # Shallow clone (latest commit only)git clone --branch dev https://... # Clone specific branchBasic Workflow
Section titled “Basic Workflow”Staging & Committing
Section titled “Staging & Committing”# Check statusgit statusgit status -s # Short format
# Stage filesgit add file.txt # Single filegit add file1.txt file2.txtgit add *.js # By patterngit add src/ # Directorygit add . # All changes in current dirgit add -A # All changes in repogit add -p # Interactive staging (hunks)
# Unstage filesgit reset file.txt # Unstage, keep changesgit restore --staged file.txt # Same (Git 2.23+)
# Discard changesgit checkout -- file.txt # Old waygit restore file.txt # Git 2.23+
# Commitgit commit -m "Message"git commit # Opens editorgit commit -am "Message" # Stage tracked + commitgit commit --amend # Modify last commitgit commit --amend --no-edit # Amend without changing messagegit commit --allow-empty -m "Empty commit"Viewing Changes
Section titled “Viewing Changes”# Differencesgit diff # Unstaged changesgit diff --staged # Staged changesgit diff HEAD # All uncommitted changesgit diff branch1..branch2 # Between branchesgit diff commit1..commit2 # Between commitsgit diff HEAD~3..HEAD # Last 3 commitsgit diff --stat # Summary onlygit diff --name-only # File names only
# Loggit loggit log --oneline # Compactgit log --oneline -10 # Last 10 commitsgit log --graph # ASCII graphgit log --all # All branchesgit log --oneline --graph --all # Combinedgit log -p # With diffsgit log --stat # With file statsgit log --author="Name" # By authorgit log --since="2024-01-01"git log --until="2024-12-31"git log --grep="bug" # Search commit messagesgit log -- file.txt # History of specific filegit log -S "searchterm" # Commits changing stringgit log branch1..branch2 # Commits in branch2 not in branch1
# Show specific commitgit show abc123git show HEADgit show HEAD~2 # 2 commits agogit show HEAD:file.txt # File at commit
# Blame (who changed what)git blame file.txtgit blame -L 10,20 file.txt # Lines 10-20Branches
Section titled “Branches”Basic Operations
Section titled “Basic Operations”# List branchesgit branch # Localgit branch -r # Remotegit branch -a # Allgit branch -v # With last commitgit branch --merged # Merged into currentgit branch --no-merged # Not merged
# Create branchgit branch feature # Create onlygit checkout -b feature # Create and switchgit switch -c feature # Git 2.23+
# Switch branchesgit checkout maingit switch main # Git 2.23+
# Rename branchgit branch -m old-name new-namegit branch -m new-name # Rename current
# Delete branchgit branch -d feature # Safe delete (must be merged)git branch -D feature # Force delete
# Set upstreamgit branch -u origin/maingit branch --set-upstream-to=origin/mainMerging
Section titled “Merging”# Merge branch into currentgit merge feature
# Merge with commit messagegit merge feature -m "Merge feature branch"
# Merge without fast-forward (always create commit)git merge --no-ff feature
# Squash merge (combine all commits)git merge --squash featuregit commit -m "Squashed feature"
# Abort mergegit merge --abortRebasing
Section titled “Rebasing”# Rebase current branch onto maingit rebase main
# Interactive rebase (edit, squash, reorder commits)git rebase -i HEAD~5 # Last 5 commitsgit rebase -i main # Since branching from main
# Continue/abort rebasegit rebase --continuegit rebase --abortgit rebase --skip # Skip current commit
# Rebase options in interactive mode:# pick = use commit# reword = use commit, edit message# edit = use commit, stop for amending# squash = meld into previous commit# fixup = like squash, discard message# drop = remove commitCherry-pick
Section titled “Cherry-pick”# Apply specific commit to current branchgit cherry-pick abc123git cherry-pick abc123 def456 # Multiplegit cherry-pick abc123..def456 # Rangegit cherry-pick --no-commit abc123 # Stage only
# Abort/continuegit cherry-pick --abortgit cherry-pick --continueRemote Repositories
Section titled “Remote Repositories”Managing Remotes
Section titled “Managing Remotes”# List remotesgit remotegit remote -v # With URLs
# Add remotegit remote add origin https://github.com/user/repo.gitgit remote add upstream https://github.com/original/repo.git
# Remove remotegit remote remove origin
# Rename remotegit remote rename origin upstream
# Change URLgit remote set-url origin https://new-url.git
# Show remote infogit remote show originFetching & Pulling
Section titled “Fetching & Pulling”# Fetch (download without merging)git fetch # From default remotegit fetch origin # From specific remotegit fetch --all # From all remotesgit fetch --prune # Remove deleted remote branches
# Pull (fetch + merge)git pullgit pull origin maingit pull --rebase # Fetch + rebase instead of mergegit pull --rebase origin mainPushing
Section titled “Pushing”# Pushgit pushgit push origin maingit push -u origin main # Set upstream and pushgit push --all # All branchesgit push --tags # All tags
# Force push (use with caution!)git push --force # Overwrite remotegit push --force-with-lease # Safer: fails if remote changed
# Delete remote branchgit push origin --delete featuregit push origin :feature # Older syntaxStashing
Section titled “Stashing”# Stash changesgit stash # Stash tracked filesgit stash -u # Include untrackedgit stash -a # Include ignoredgit stash push -m "message"git stash push file.txt # Specific file
# List stashesgit stash list
# Apply stashgit stash apply # Most recent, keep in stashgit stash apply stash@{2} # Specific stashgit stash pop # Apply and removegit stash pop stash@{2}
# View stash contentsgit stash show # Summarygit stash show -p # Full diffgit stash show stash@{1}
# Delete stashgit stash drop # Most recentgit stash drop stash@{2} # Specificgit stash clear # All stashes
# Create branch from stashgit stash branch new-branch stash@{0}Undoing Changes
Section titled “Undoing Changes”Uncommitted Changes
Section titled “Uncommitted Changes”# Discard changes in working directorygit checkout -- file.txt # Old waygit restore file.txt # Git 2.23+git restore . # All files
# Unstage filesgit reset HEAD file.txt # Old waygit restore --staged file.txt # Git 2.23+
# Discard all uncommitted changesgit reset --hard HEADgit checkout .Committed Changes
Section titled “Committed Changes”# Undo last commit, keep changes stagedgit reset --soft HEAD~1
# Undo last commit, keep changes unstagedgit reset HEAD~1git reset --mixed HEAD~1 # Same
# Undo last commit, discard changesgit reset --hard HEAD~1
# Undo specific commit (creates new commit)git revert abc123git revert HEAD # Revert last commitgit revert HEAD~3..HEAD # Revert range
# Undo merge commitgit revert -m 1 merge-commit-hashRecovering
Section titled “Recovering”# Find lost commitsgit refloggit reflog show feature # Specific branch
# Recover deleted branchgit checkout -b recovered abc123 # Use hash from reflog
# Recover deleted commitgit cherry-pick abc123 # From reflog# List tagsgit taggit tag -l "v1.*" # Pattern match
# Create taggit tag v1.0.0 # Lightweightgit tag -a v1.0.0 -m "Release v1.0.0" # Annotatedgit tag -a v1.0.0 abc123 # Tag specific commit
# Show taggit show v1.0.0
# Push tagsgit push origin v1.0.0 # Single taggit push origin --tags # All tags
# Delete taggit tag -d v1.0.0 # Localgit push origin --delete v1.0.0 # Remote
# Checkout taggit checkout v1.0.0 # Detached HEADgit checkout -b release-1.0 v1.0.0 # New branchAdvanced Operations
Section titled “Advanced Operations”Worktrees
Section titled “Worktrees”# Add worktree (work on multiple branches simultaneously)git worktree add ../project-feature featuregit worktree add -b new-branch ../project-new main
# List worktreesgit worktree list
# Remove worktreegit worktree remove ../project-featuregit worktree prune # Clean up stale worktreesBisect (Find Bug-Introducing Commit)
Section titled “Bisect (Find Bug-Introducing Commit)”git bisect startgit bisect bad # Current commit is badgit bisect good v1.0.0 # Known good commit# Git checks out middle commit, test it, then:git bisect good # orgit bisect bad# Repeat until foundgit bisect reset # Return to original state
# Automated bisectgit bisect start HEAD v1.0.0git bisect run ./test.sh # Script returns 0=good, 1=badSubmodules
Section titled “Submodules”# Add submodulegit submodule add https://github.com/user/lib.git libs/lib
# Clone repo with submodulesgit clone --recurse-submodules https://...# Or after cloning:git submodule update --init --recursive
# Update submodulesgit submodule update --remote
# Remove submodulegit submodule deinit libs/libgit rm libs/librm -rf .git/modules/libs/lib# Remove untracked filesgit clean -n # Dry run (show what would be deleted)git clean -f # Force deletegit clean -fd # Include directoriesgit clean -fx # Include ignored filesgit clean -fdx # Everything untrackedBuilt-in Hooks
Section titled “Built-in Hooks”Hooks live in .git/hooks/. Make executable with chmod +x.
# List available hook templatesls .git/hooks/*.sample
# Enable a hook (remove .sample suffix)cp .git/hooks/pre-commit.sample .git/hooks/pre-commitchmod +x .git/hooks/pre-commit| Hook | Trigger | Use for |
|---|---|---|
pre-commit | Before commit is created | Lint, format, secrets detection |
commit-msg | After message is entered | Validate conventional commit style |
pre-push | Before push to remote | Run tests, type-check |
prepare-commit-msg | Before editor opens | Inject branch name or template |
post-commit | After commit is created | Notifications, local CI trigger |
post-merge | After merge completes | Reinstall deps if lockfile changed |
post-checkout | After checkout/switch | Rebuild assets, warn env changes |
Hook Managers
Section titled “Hook Managers”Raw .git/hooks/ scripts aren’t version-controlled. Use a manager instead.
# .pre-commit-config.yaml (pre-commit framework)repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.6.0 hooks: - id: trailing-whitespace - id: check-merge-conflict - id: detect-private-key - id: end-of-file-fixer - repo: https://github.com/gitleaks/gitleaks rev: v8.18.4 hooks: - id: gitleaks# Install pre-commit frameworkpip install pre-commit # or brew install pre-commitpre-commit install # writes .git/hooks/pre-commitpre-commit run --all-files # test against entire repopre-commit autoupdate # bump hook versions| Manager | Language | Config file | Notes |
|---|---|---|---|
| pre-commit | Python | .pre-commit-config.yaml | Largest hook ecosystem |
| husky | Node | .husky/ | Pairs with lint-staged |
| lefthook | Go | lefthook.yml | Fast, no runtime dependency |
Writing a Custom Hook
Section titled “Writing a Custom Hook”#!/usr/bin/env bash# .git/hooks/commit-msg — enforce conventional commitscommit_msg=$(cat "$1")pattern='^(feat|fix|docs|refactor|test|chore|ci|style|perf|build)(\(.+\))?: .+'
if ! echo "$commit_msg" | grep -qE "$pattern"; then echo "ERROR: Commit message must match conventional format" echo " e.g., feat: Add user authentication" exit 1fi#!/usr/bin/env bash# .git/hooks/post-merge — reinstall deps when lockfile changeschanged_files=$(git diff-tree -r --name-only --no-commit-id ORIG_HEAD HEAD)
if echo "$changed_files" | grep -q "package-lock.json"; then echo "lockfile changed — running npm install" npm installfiBest Practices
Section titled “Best Practices”- Keep pre-commit hooks under 5 seconds. Slow hooks train
--no-verifyhabits. - Lint staged files, not the whole repo. Use
lint-staged(Node) orpre-commit’s built-in staging support. - Hooks are convenience, not security. Anyone can
--no-verify. CI is the authoritative gate. - Ship a setup command.
make setupornpm preparethat installs hooks automatically. - Fail with actionable messages. Print what broke and how to fix it.
- Layer by speed: pre-commit (fast: format, lint) → pre-push (slow: tests, type-check) → CI (authoritative).
Useful Aliases
Section titled “Useful Aliases”Add to ~/.gitconfig:
[alias] # Status st = status -s
# Logging lg = log --oneline --graph --all --decorate ll = log --oneline -15 last = log -1 HEAD --stat
# Branches br = branch co = checkout sw = switch
# Commits ci = commit ca = commit --amend can = commit --amend --no-edit
# Diff df = diff dfs = diff --staged
# Undo unstage = reset HEAD -- undo = reset --soft HEAD~1
# Stash sl = stash list sp = stash pop ss = stash push -m
# Find find = log --all --full-history -- search = log -S
# Aliases aliases = config --get-regexp aliasCommon Workflows
Section titled “Common Workflows”Feature Branch
Section titled “Feature Branch”git checkout maingit pullgit checkout -b feature/my-feature# ... make changes ...git add .git commit -m "Add feature"git push -u origin feature/my-feature# Create PR, after merge:git checkout maingit pullgit branch -d feature/my-featureSync Fork with Upstream
Section titled “Sync Fork with Upstream”git remote add upstream https://github.com/original/repo.gitgit fetch upstreamgit checkout maingit merge upstream/maingit push origin mainSquash Commits Before PR
Section titled “Squash Commits Before PR”git rebase -i main# Mark commits as 'squash' or 'fixup'# Edit combined commit messagegit push --force-with-leaseFix Detached HEAD
Section titled “Fix Detached HEAD”# If you made commits in detached HEAD:git branch temp-branch # Save commitsgit checkout maingit merge temp-branchgit branch -d temp-branchQuick Reference
Section titled “Quick Reference”| Task | Command |
|---|---|
| Initialize repo | git init |
| Clone repo | git clone <url> |
| Check status | git status |
| Stage all | git add . |
| Commit | git commit -m "msg" |
| Push | git push |
| Pull | git pull |
| Create branch | git checkout -b name |
| Switch branch | git checkout name |
| Merge branch | git merge name |
| View log | git log --oneline |
| View diff | git diff |
| Stash changes | git stash |
| Apply stash | git stash pop |
| Undo last commit | git reset --soft HEAD~1 |
| Discard changes | git restore file |
See Also
Section titled “See Also”- Git Lesson Plan — 8 lessons from commits to workflows
- GitHub Lesson Plan — Repos, PRs, Actions, and API
- CI/CD — GitHub Actions, caching, matrix builds
- AI CLI Patterns — Version control discipline with AI agents
- Neovim Commands (LazyVim)
- Debugging