← Tech Guides

Quick Reference

The essential commands every practitioner should know by heart.

Getting Started

git init
Initialize a new repository
git clone <url>
Clone a remote repository
git config --global user.name "Name"
Set your identity
git config --global user.email "email"
Set your email

Daily Workflow

git status
Check working tree status
git add <file>
Stage changes
git add -A
Stage everything
git commit -m "msg"
Commit staged changes
git pull
Fetch and merge remote
git push
Push commits to remote

Branching

git branch
List local branches
git switch -c <name>
Create and switch to branch
git switch <branch>
Switch branches
git merge <branch>
Merge branch into current
git branch -d <name>
Delete merged branch

Inspecting

git log --oneline
Compact commit history
git diff
Show unstaged changes
git diff --staged
Show staged changes
git blame <file>
Line-by-line authorship
git show <commit>
Show commit details

Undoing

git restore <file>
Discard working changes
git restore --staged <file>
Unstage a file
git reset --soft HEAD~1
Undo commit, keep staged
git revert <commit>
Create inverse commit
git stash
Shelve changes temporarily

Remote Operations

git remote -v
Show remote URLs
git fetch
Download remote changes
git pull --rebase
Pull with rebase
git push -u origin <branch>
Push and set upstream
git push --force-with-lease
Safer force push
Chapter I

Setup & Configuration

Laying the foundation. Every repository begins with proper configuration -- identity, preferences, and the tools of the trade.

Identity & Preferences

# Set your identity (required for commits)
git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"

# Set default editor
git config --global core.editor "code --wait"    # VS Code
git config --global core.editor "vim"             # Vim
git config --global core.editor "nano"            # Nano

# Configure line endings
git config --global core.autocrlf true     # Windows: CRLF on checkout, LF on commit
git config --global core.autocrlf input    # Mac/Linux: LF only

# Set default branch name
git config --global init.defaultBranch main

# View all settings (and where they come from)
git config --list
git config --list --show-origin

Credential Helpers

# Store credentials permanently (Linux/Mac)
git config --global credential.helper store

# Cache credentials for 1 hour
git config --global credential.helper 'cache --timeout=3600'

# Windows credential manager
git config --global credential.helper manager-core

# Unset credential helper
git config --global --unset credential.helper

Initialize & Clone

# Initialize a new repository
git init
git init <directory>

# Clone an existing repository
git clone <url>
git clone <url> <directory>
git clone --depth 1 <url>             # Shallow clone (latest only)
git clone --branch <branch> <url>     # Clone specific branch
git clone --single-branch <url>        # Clone only one branch
Configuration Scopes

Git config has three scopes: --system (all users), --global (your user), and --local (current repo, the default). Local settings override global, which override system.

Chapter II

Basic Workflow

The daily rhythm of version control -- staging, committing, inspecting, and understanding the state of your work.

Status & Information

git status                  # Full working tree status
git status -s                # Short format
git status -sb               # Short format with branch info
git status --ignored         # Show ignored files too

Staging Changes

git add <file>              # Stage specific file
git add <file1> <file2>     # Stage multiple files
git add -A                   # Stage all changes (new, modified, deleted)
git add .                    # Stage all in current directory
git add -u                   # Stage modified and deleted (not new files)
git add -p                   # Patch mode -- stage chunks interactively

Committing

git commit -m "Commit message"
git commit -m "Title" -m "Description"   # Multi-line message
git commit -am "message"                    # Stage tracked files + commit
git commit --amend                           # Amend last commit
git commit --amend -m "New message"         # Amend with new message
git commit --amend --no-edit                 # Amend without changing message
git commit --author="Name <email>"          # Commit with specific author

Viewing Differences

git diff                    # Unstaged changes (working tree vs index)
git diff --staged             # Staged changes (index vs HEAD)
git diff --cached             # Same as --staged
git diff HEAD                 # All local changes (working tree vs HEAD)
git diff <commit1> <commit2> # Between two commits
git diff <file>              # Changes in specific file
git diff --word-diff          # Word-level diff
git diff --stat               # Statistics only

Viewing History

git log                                 # Full log
git log -n 5                            # Last 5 commits
git log --oneline                        # Compact one-line view
git log --graph --oneline --all          # ASCII branch graph
git log -p                               # Show patches (full diffs)
git log --author="John"                  # Filter by author
git log --since="2 weeks ago"            # Filter by date
git log --grep="keyword"                  # Search commit messages
git log --follow <file>                  # File history (follow renames)
git log --pretty=format:"%h - %an: %s"  # Custom format

# Show specific commit details
git show <commit>
git show <commit>:<file>               # File at specific commit
Chapter III

Branching & Merging

The true power of Git lies in its branching model -- lightweight, fast, and designed for parallel lines of development.

Branch Management

# List branches
git branch                  # Local branches
git branch -a               # All (local + remote)
git branch -r               # Remote branches only
git branch -v               # Show last commit per branch
git branch -vv              # Show tracking branches

# Create branch
git branch <name>
git branch <name> <start-point>

# Switch branches (modern)
git switch <branch>
git switch -c <new-branch>       # Create and switch

# Switch branches (classic)
git checkout <branch>
git checkout -b <new-branch>    # Create and switch

# Rename branch
git branch -m <old> <new>
git branch -m <new-name>          # Rename current branch

# Delete branch
git branch -d <branch>            # Safe delete (merged only)
git branch -D <branch>            # Force delete
git push origin --delete <branch> # Delete remote branch

Merging

git merge <branch>                  # Merge into current branch
git merge <branch> -m "message"    # Merge with message
git merge --no-ff <branch>          # Force merge commit (no fast-forward)
git merge --ff-only <branch>        # Fast-forward only, fail otherwise
git merge --squash <branch>         # Squash all commits into one
git merge --abort                    # Abort a conflicted merge

Rebasing

git rebase <branch>                 # Rebase current onto branch
git rebase main                      # Rebase onto main
git rebase -i HEAD~3                # Interactive rebase last 3 commits
git rebase -i --autosquash <branch> # Auto-arrange fixup commits
git rebase --continue               # Continue after conflict resolution
git rebase --skip                    # Skip current commit
git rebase --abort                   # Abort rebase entirely

Conflict Resolution

# View conflicts
git status                           # See conflicted files
git diff                             # View conflict markers

# Choose a version
git checkout --ours <file>          # Keep current branch version
git checkout --theirs <file>        # Keep incoming branch version

# After resolving manually
git add <resolved-files>
git merge --continue                # or: git rebase --continue

# Visual merge tool
git mergetool
Rebase vs. Merge

Merge preserves the full history with a merge commit. Rebase creates a linear history by replaying commits. Never rebase commits that have been pushed to a shared branch -- this rewrites public history and can cause serious problems for collaborators.

Chapter IV

Remote Operations

Collaboration requires coordination with remote repositories -- fetching, pulling, pushing, and tracking distributed branches.

Remote Management

git remote                          # List remotes
git remote -v                        # Show remote URLs
git remote add <name> <url>         # Add new remote
git remote remove <name>            # Remove remote
git remote rename <old> <new>      # Rename remote
git remote set-url <name> <url>    # Change remote URL
git remote show origin              # Detailed remote info

Fetching & Pulling

# Fetch (download without merging)
git fetch                            # Fetch all remotes
git fetch <remote>                   # Fetch specific remote
git fetch <remote> <branch>         # Fetch specific branch
git fetch --all                      # Fetch all remotes
git fetch --prune                    # Remove stale remote-tracking branches

# Pull (fetch + merge)
git pull                             # Pull current branch
git pull <remote> <branch>          # Pull specific branch
git pull --rebase                    # Pull with rebase instead of merge
git pull --ff-only                   # Fast-forward only

Pushing

git push                             # Push to tracked remote
git push <remote> <branch>          # Push specific branch
git push -u origin <branch>         # Push and set upstream tracking
git push --all                       # Push all branches
git push --tags                      # Push all tags
git push --force-with-lease          # Safer force push
git push origin --delete <branch>  # Delete remote branch

Tracking Branches

git branch -u <remote>/<branch>    # Set upstream
git branch --set-upstream-to=origin/main
git branch -vv                      # View tracking info
git branch --unset-upstream         # Remove upstream tracking
Chapter V

Stashing

A place to temporarily shelve changes -- like tucking a draft into a desk drawer to return to later.

Saving to Stash

git stash                            # Stash staged and unstaged changes
git stash push -m "message"          # Stash with description
git stash -u                          # Include untracked files
git stash --include-untracked        # Same as -u
git stash -a                          # Include ignored files too
git stash push <file>                # Stash specific file
git stash -p                          # Interactive: choose hunks to stash
git stash --keep-index               # Stash but keep staged changes staged

Retrieving & Managing

git stash list                       # List all stashes
git stash show                        # Show latest stash summary
git stash show -p                     # Show full diff of latest stash
git stash show stash@{2} -p          # Show specific stash diff

# Apply stash (keep in list)
git stash apply                       # Apply latest
git stash apply stash@{2}             # Apply specific stash

# Pop stash (apply and remove from list)
git stash pop                         # Pop latest
git stash pop stash@{2}               # Pop specific stash

# Remove stashes
git stash drop                        # Drop latest
git stash drop stash@{2}              # Drop specific stash
git stash clear                       # Remove all stashes

# Create branch from stash
git stash branch <branch-name>        # New branch from latest stash
Stash Tip

Stashes are local only -- they are never transferred to the server when you push. Use git stash push -m "description" to name your stashes so you can identify them later in git stash list.

Chapter VI

History & Inspection

The archaeological tools of version control -- tracing authorship, hunting bugs, and recovering from the unrecoverable.

Advanced Log

# Graph views
git log --graph --oneline --all
git log --graph --decorate --oneline

# Filter by author
git log --author="John Doe"
git log --author="john\|jane"        # Multiple authors

# Filter by date
git log --since="2 weeks ago"
git log --after="2024-01-01" --before="2024-12-31"

# Search content
git log --grep="fix"                # Search commit messages
git log -S "function_name"           # Search for string in diffs (pickaxe)
git log -G "regex"                   # Search diffs with regex

# Merge-specific
git log --merges                     # Show only merge commits
git log --no-merges                  # Exclude merge commits

# Statistics
git log --stat                       # File change statistics
git log --shortstat                  # Summary only
git log --name-only                  # List changed files
git log --name-status                # Files with add/modify/delete status

# Custom formatting
git log --pretty=format:"%h %an %ad %s" --date=short
git log --pretty=format:"%C(yellow)%h%Creset %C(blue)%an%Creset %s"

Blame

git blame <file>                   # Who changed each line
git blame -L 10,20 <file>          # Lines 10 through 20
git blame -L 10,+5 <file>          # 5 lines starting at line 10
git blame -e <file>                 # Show email instead of name
git blame -w <file>                 # Ignore whitespace changes

Bisect

Binary search through commit history to find the commit that introduced a bug.

git bisect start                    # Begin bisect session
git bisect bad                       # Current commit has the bug
git bisect good <commit>             # Known good commit

# Git checks out middle commit. Test and mark:
git bisect good                      # This commit is fine
git bisect bad                       # This commit has the bug
git bisect skip                      # Can't test this one, skip

# Automate with a test script
git bisect run <test-script>

git bisect reset                     # End bisect, return to original HEAD

Reflog

The safety net -- a log of every position HEAD has pointed to. Invaluable for recovering lost work.

git reflog                           # Show reflog for HEAD
git reflog show <branch>             # Reflog for specific branch
git reflog --date=relative           # Show with relative dates
git reflog --date=iso                # Show with ISO dates

# Recover lost commits
git reflog                           # Find the commit hash
git branch <recovery-branch> <hash>  # Create branch at lost commit
Recovery Lifeline

Almost nothing in Git is truly lost. If you committed it (or even just staged it), git reflog and git fsck --lost-found can help you recover it. The reflog keeps entries for about 90 days by default.

Chapter VII

Undoing Changes

The art of reversal -- from a gentle unstage to a complete rewrite. Choose the right tool for the severity of the situation.

Command Scope Rewrites History? Safe for Shared?
git restore Working tree / staging No Yes
git revert Commits (creates inverse) No Yes
git reset --soft Commit pointer only Yes Local only
git reset --mixed Commit pointer + staging Yes Local only
git reset --hard Everything Yes Dangerous
git clean Untracked files No Permanent

Restore (Working Tree & Staging)

git restore <file>                  # Discard working tree changes
git restore .                        # Discard all working tree changes
git restore --staged <file>         # Unstage file (keep changes)
git restore --staged --worktree <file>  # Unstage and discard changes
git restore --source=HEAD~2 <file>  # Restore file from 2 commits ago

Reset (Move Branch Pointer)

# Soft: uncommit, keep changes staged
git reset --soft HEAD~1

# Mixed (default): uncommit, unstage changes
git reset HEAD~1
git reset --mixed HEAD~1

# Hard: discard everything (DANGEROUS)
git reset --hard HEAD~1
git reset --hard origin/main         # Match remote exactly

# Unstage a file
git reset HEAD <file>                 # Legacy way to unstage

Revert (Safe Undo)

git revert <commit>                  # Create inverse commit
git revert -n <commit>               # Revert without committing
git revert -m 1 <merge-commit>      # Revert a merge commit
git revert <commit1>..<commit2>     # Revert range of commits
git revert --continue                # Continue after conflict
git revert --abort                   # Abort revert

Clean (Remove Untracked Files)

git clean -n                        # Dry run -- preview what would be removed
git clean -f                        # Remove untracked files
git clean -fd                       # Remove untracked files and directories
git clean -fx                       # Remove untracked + ignored files
git clean -fdx                      # Remove everything untracked (NUCLEAR)
git clean -i                        # Interactive mode
Point of No Return

git reset --hard and git clean -f permanently destroy uncommitted work. Always run git stash or git clean -n (dry run) first. Committed work can almost always be recovered via git reflog.

Chapter VIII

Advanced Operations

The master craftsman's toolkit -- cherry-picking commits, managing multiple working trees, and composing repositories.

Cherry-Pick

Apply specific commits from one branch to another, without merging the entire branch.

git cherry-pick <commit>             # Apply commit to current branch
git cherry-pick -n <commit>          # Apply without committing
git cherry-pick <c1> <c2> <c3>     # Cherry-pick multiple commits
git cherry-pick <c1>..<c2>          # Cherry-pick range (exclusive of c1)
git cherry-pick -e <commit>          # Edit commit message
git cherry-pick --continue           # Continue after conflict
git cherry-pick --abort              # Abort cherry-pick
git cherry-pick --skip               # Skip current commit

Interactive Rebase

Rewrite, reorder, squash, or drop commits before sharing your work.

git rebase -i HEAD~3                # Rebase last 3 commits interactively
git rebase -i <commit>               # Rebase from commit forward

# Editor commands:
#   pick   = use commit as-is
#   reword = edit commit message
#   edit   = stop to amend commit
#   squash = meld into previous, keep message
#   fixup  = meld into previous, discard message
#   drop   = remove commit entirely
#   exec   = run shell command

# Auto-squash workflow
git commit --fixup <commit>          # Create fixup commit
git rebase -i --autosquash <base>   # Auto-arrange fixup commits

Worktree

Work on multiple branches simultaneously without stashing or switching.

git worktree list                    # Show all worktrees
git worktree add <path> <branch>     # Check out branch in new directory
git worktree add -b <new> <path>    # Create new branch in new directory
git worktree remove <path>           # Remove worktree
git worktree prune                   # Clean up stale worktrees
git worktree lock <path>             # Prevent worktree from being pruned

Submodules

git submodule add <url> <path>      # Add a submodule
git submodule init                   # Initialize submodule config
git submodule update                 # Fetch submodule content
git submodule update --init --recursive  # Init + update all nested
git clone --recurse-submodules <url>  # Clone with submodules
git pull --recurse-submodules        # Pull including submodules
git submodule foreach <command>       # Run command in each submodule

# Remove submodule
git submodule deinit <path>
git rm <path>

Subtree & Filter-Repo

# Subtree (alternative to submodules)
git subtree add --prefix=<dir> <repo> <branch> --squash
git subtree pull --prefix=<dir> <repo> <branch> --squash
git subtree push --prefix=<dir> <repo> <branch>

# Filter-Repo (modern history rewriting, replaces filter-branch)
# Install: pip install git-filter-repo
git filter-repo --path <file> --invert-paths     # Remove file from all history
git filter-repo --path <dir>/ --invert-paths    # Remove directory from all history
Chapter IX

Tags

Bookmarks in the timeline -- marking releases, milestones, and significant moments in a project's life.

Creating Tags

# Lightweight tag (just a pointer)
git tag v1.0.0

# Annotated tag (recommended -- includes metadata)
git tag -a v1.0.0 -m "Release version 1.0.0"

# Signed tag (GPG verified)
git tag -s v1.0.0 -m "Signed release"

# Tag a specific commit (not HEAD)
git tag v1.0.0 <commit-hash>
git tag -a v1.0.0 <commit-hash> -m "message"

Managing Tags

git tag                              # List all tags
git tag -l "v1.*"                    # Filter tags by pattern
git show v1.0.0                      # Show tag details
git tag -v v1.0.0                    # Verify signed tag
git tag -d v1.0.0                    # Delete local tag
git push origin --delete v1.0.0     # Delete remote tag

Pushing Tags

git push origin v1.0.0              # Push specific tag
git push --tags                      # Push all tags
git push --follow-tags               # Push annotated tags only
git fetch --tags                     # Fetch all remote tags
Lightweight vs. Annotated

Annotated tags (-a) store the tagger name, email, date, and message -- use these for releases. Lightweight tags are just pointers to a commit -- suitable for temporary or personal bookmarks. Signed tags (-s) add cryptographic verification.

Chapter X

Useful Aliases

A well-configured set of aliases transforms a lengthy command into a swift keystroke -- the mark of a seasoned practitioner.

Add these to your ~/.gitconfig under the [alias] section, or use git config --global alias.<name> <command>.

Everyday Shortcuts
[alias]
  st = status
  s  = status -sb
  co = checkout
  sw = switch
  br = branch
  ci = commit
  cm = commit -m
  ca = commit --amend
  cane = commit --amend --no-edit
  a  = add
  aa = add -A
  ap = add -p
  d  = diff
  ds = diff --staged
  dw = diff --word-diff
Log & History
[alias]
  l    = log --oneline
  lg   = log --graph --oneline --decorate --all
  ll   = log --pretty=format:'%h %ad %an: %s' --date=short
  lol  = log --graph --pretty=oneline --abbrev-commit
  lola = log --graph --pretty=oneline --abbrev-commit --all
  last = log -1 HEAD --stat
Remote & Stash
[alias]
  pl  = pull
  ps  = push
  psu = push -u origin HEAD
  pf  = push --force-with-lease
  ss  = stash
  sp  = stash pop
  sl  = stash list
Undo & Workflow
[alias]
  undo    = reset HEAD~1 --mixed
  unstage = reset HEAD --
  wip     = commit -am "WIP"
  unwip   = reset HEAD~1
  cont    = rebase --continue
  abort   = rebase --abort
  aliases = config --get-regexp alias
Chapter XI

Pro Tips

The accumulated wisdom of the trade -- patterns, hooks, performance tuning, and the finer points of the craft.

.gitignore Patterns

# Common patterns
*.log                   # Ignore all .log files
/todo.txt               # Ignore file in root only
build/                  # Ignore entire directory
doc/*.txt               # Ignore .txt in doc/ (not subdirs)
**/logs                 # Ignore logs dir anywhere in tree
!important.log          # Exception: do NOT ignore this file

# OS files
.DS_Store
Thumbs.db

# Dependencies
node_modules/
vendor/

# Environment & secrets
.env
.env.local
*.env

# IDE
.vscode/
.idea/
*.swp

# Build output
dist/
build/
*.min.js
*.min.css

Set up a global gitignore for patterns common across all your projects:

git config --global core.excludesfile ~/.gitignore_global

Git Hooks

Scripts that run automatically at key points in the Git workflow. Located in .git/hooks/.

Hook When It Runs Common Use
pre-commit Before commit is created Lint, format, run tests
prepare-commit-msg Before message editor opens Template commit messages
commit-msg After message is saved Validate message format
pre-push Before push executes Run full test suite
post-checkout After checkout completes Install deps, rebuild
post-merge After merge completes Install deps, migrations

Sparse Checkout

Work with only a subset of files in large repositories.

git sparse-checkout init             # Enable sparse checkout
git sparse-checkout set <directory>   # Set directories to include
git sparse-checkout add <directory>   # Add directory to checkout
git sparse-checkout list             # List included paths
git sparse-checkout disable          # Disable (restore full tree)

Partial & Shallow Clones

git clone --filter=blob:none <url>   # Blobless clone (download blobs on demand)
git clone --filter=tree:0 <url>     # Treeless clone (most aggressive)
git clone --depth=1 <url>           # Shallow clone (latest commit only)
git fetch --unshallow                # Convert shallow to full clone

Signing Commits

# Configure GPG signing
git config --global user.signingkey <key-id>
git config --global commit.gpgsign true   # Always sign

# Sign individual commits
git commit -S -m "Signed commit"

# Verify signatures
git log --show-signature
git verify-commit <commit>

Searching

git grep "search term"               # Search in working tree
git grep -n "search term"            # With line numbers
git grep -i "search term"            # Case insensitive
git grep "term" <commit>             # Search in specific commit
git grep -p "term"                   # Show function context
git grep -E "regex.*pattern"         # Extended regex search

Maintenance & Performance

# Repository maintenance
git gc                               # Garbage collection
git gc --aggressive                  # Aggressive optimization
git prune                            # Remove unreachable objects
git fsck                             # Verify repository integrity
git count-objects -v                 # Count and size objects

# Performance settings
git config core.preloadindex true    # Parallel index preload
git config core.fsmonitor true       # File system monitor
git config core.commitGraph true     # Enable commit graph
git commit-graph write --reachable   # Build commit graph

Archive & Bundle

# Create archives
git archive HEAD --format=zip > repo.zip
git archive HEAD --prefix=project/ --format=zip > project.zip

# Bundles (offline transfer)
git bundle create repo.bundle --all  # Create bundle
git clone repo.bundle                # Clone from bundle
git bundle verify repo.bundle        # Verify bundle

Environment Variables

# Useful environment overrides
export GIT_EDITOR=vim                # Override editor
export GIT_PAGER=less                # Set pager
export GIT_PAGER=cat                 # Disable pager
export GIT_SSH_COMMAND="ssh -i ~/.ssh/custom_key"
§