Git logoGitv2.55BEGINNER

Git

Git cheat sheet with commands for branching, merging, rebasing, stashing, cherry-picking, and advanced version control techniques.

8 min read
gitversion-controlgithubcommandsworkflow

Sign in to mark items as known and track your progress.

Sign in

Getting Started

Initial Setup

Configure Git for first time use with your identity

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

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

# Check settings
git config --list
💡 Use --global for system-wide settings
📌 Local config overrides global settings
⚡ Set your editor for commit messages and conflicts

Create & Clone Repositories

Start a new project or get an existing one

bash
# Create new repository
git init
git init <directory>

# Clone existing repository
git clone <url>
git clone <url> <directory>

# Clone specific branch
git clone -b <branch> <url>
💡 Clone creates a full copy with history
⚡ Use shallow clone for faster downloads
📌 Init creates a new .git directory

.gitignore

Tell Git which files and directories to ignore

bash
# Create .gitignore in repo root
# Common patterns:
node_modules/
.env
.env.local
dist/
build/
*.log
.DS_Store
.vscode/
.idea/

# Stop tracking a file that's already committed
git rm --cached <file>
git rm -r --cached <directory>
💡 .gitignore only affects untracked files
⚠️ Already-tracked files keep being tracked — use git rm --cached to stop
✅ Use a global ignore for OS/editor junk (.DS_Store, .vscode/)
📌 Commit .gitignore so the whole team shares it

Making Changes

Check Status & Differences

See what has changed in your working directory

bash
# Check status
git status
git status -s  # Short format

# View changes
git diff              # Unstaged changes
git diff --staged     # Staged changes
git diff HEAD         # All changes
git diff <branch>     # Compare with branch
💡 Status shows staged, modified, and untracked files
⚡ Use -s for compact status output
📌 Diff shows line-by-line changes

Stage & Commit Changes

Save your work to the repository history

bash
# Stage files
git add <file>
git add .              # All files
git add -A             # All including deletions
git add -p             # Interactive staging

# Commit
git commit -m "message"
git commit -am "message"  # Add + commit tracked files
git commit --amend       # Modify last commit
💡 Stage files before committing
⚠️ Amend rewrites history - don't amend pushed commits
✅ Write clear, descriptive commit messages
⚡ Use -p for selective staging

Branching

Branch Management

Create, list, and delete branches for parallel development

bash
# List branches
git branch            # Local
git branch -r         # Remote
git branch -a         # All

# Create and switch (modern, Git 2.23+)
git switch -c <name>
git switch <branch>

# Older equivalents
git checkout -b <name>
git checkout <branch>

# Delete branch
git branch -d <branch>  # Safe (merged only)
git branch -D <branch>  # Force delete
💡 git switch is the modern verb for branches (Git 2.23+)
⚠️ -D force-deletes unmerged branches
✅ Delete branches after merging
⚡ Use descriptive prefixes (feature/, fix/, chore/)

Merging

Combine changes from one branch into another

bash
# Merge a branch into current
git merge <branch>

# Common variants
git merge --no-ff <branch>     # Always create a merge commit
git merge --ff-only <branch>   # Fail if can't fast-forward
git merge --squash <branch>    # Squash into one commit (then commit)

# Bail out of a merge in progress
git merge --abort
💡 Fast-forward keeps history linear; --no-ff records the merge explicitly
⚡ Use --squash when you want a clean single-commit history
✅ Test after merging before pushing
🔧 --abort returns to the pre-merge state

Rebasing

Replay commits on top of another base for a linear history

bash
# Rebase current branch onto another
git rebase <branch>
git rebase main

# Interactive rebase (rewrite, reorder, squash)
git rebase -i HEAD~3

# Inside the interactive editor:
# pick    = keep commit
# reword  = change message
# edit    = stop to amend
# squash  = combine with previous (keep both messages)
# fixup   = combine with previous (drop this message)
# drop    = remove commit

# During a rebase
git rebase --continue   # After resolving conflicts
git rebase --skip       # Skip the current commit
git rebase --abort      # Cancel and reset
⚠️ Never rebase commits that are already pushed to a shared branch
💡 Rebase rewrites history; merge preserves it
✅ Use rebase locally to clean up before opening a PR
🔧 If you mess up, reflog has your back

Cherry-pick

Apply specific commits from another branch onto the current one

bash
# Apply a single commit
git cherry-pick <commit>

# Apply a range (exclusive..inclusive)
git cherry-pick <start>..<end>

# Apply without committing (stage only)
git cherry-pick -n <commit>

# After resolving conflicts
git cherry-pick --continue
git cherry-pick --abort
git cherry-pick --skip
💡 Cherry-pick copies a commit; it does not move it
⚡ Great for backporting fixes to release branches
⚠️ Creates a new commit with a different SHA than the source
✅ Use -x to leave a breadcrumb back to the original commit

Working with Remotes

Remote Repositories

Connect and sync with remote repositories

bash
# Show remotes
git remote
git remote -v

# Add remote
git remote add origin <url>

# Change remote URL
git remote set-url origin <new-url>

# Remove remote
git remote remove origin

# Rename remote
git remote rename origin upstream
💡 Origin is the default remote name
⚠️ Force push can overwrite others' work
✅ Use --force-with-lease for safer force pushing
⚡ Fetch updates remote tracking branches

Stashing Changes

Save Work Temporarily

Store uncommitted changes for later without committing

bash
# Stash changes
git stash
git stash push -m "description"

# View stashes
git stash list

# Apply stash
git stash apply         # Apply latest
git stash apply stash@{n}  # Apply specific
git stash pop           # Apply and delete

# Delete stash
git stash drop stash@{n}
git stash clear         # Delete all
💡 Stash is a stack - newest on top
⚡ Use stash to quickly switch branches
✅ Pop removes stash after applying
📌 Apply keeps stash for reuse

Fixing Mistakes

Undo Changes

Revert uncommitted changes in your working directory

bash
# Discard changes to a file (modern, Git 2.23+)
git restore <file>
git restore .             # All files

# Unstage a file (keep edits)
git restore --staged <file>

# Older equivalents
git checkout -- <file>
git reset HEAD <file>

# Nuke all local changes
git reset --hard HEAD
git clean -fd             # Remove untracked files/dirs
💡 git restore is the modern verb for files (Git 2.23+)
⚠️ --hard reset and clean -fdx are destructive — no undo
✅ Always git status first to confirm what you are discarding
📌 Soft reset keeps changes for recommit

Revert Commits

Undo committed changes by creating new commits

bash
# Revert a commit (safe — creates an inverse commit)
git revert <commit>
git revert HEAD          # Revert last commit

# Revert a range
git revert <oldest>..<newest>

# Revert a merge commit (-m 1 = keep first-parent line)
git revert -m 1 <merge-commit>

# Reset to a commit (⚠️ rewrites history)
git reset --hard <commit>
💡 Revert is safe for public/shared branches
⚠️ Reset rewrites history — avoid on shared branches
✅ For lost commits, see the Reflog item below
📌 For applying specific commits, see Cherry-pick under Branching

Recover with Reflog

Find and recover commits that look "lost" after rewrites

bash
# Show the reflog (HEAD movement history)
git reflog
git reflog --all          # All refs, not just HEAD

# Entries look like:
# abc1234 HEAD@{0}: rebase finished
# def5678 HEAD@{1}: commit: WIP fix
# 0123abc HEAD@{2}: checkout: moving to main

# Recover by SHA or HEAD@{n}
git reset --hard HEAD@{1}
git reset --hard <sha>

# Safer: branch off the recovered commit
git switch -c recovery HEAD@{1}
💡 Reflog records every HEAD movement — your safety net for rewrites
✅ Almost nothing is truly lost for ~90 days
⚡ Use HEAD@{n} or time syntax (HEAD@{2.days.ago})
🔧 Branch off the recovered commit instead of reset --hard

Merge Conflicts

Resolve Conflicts

Handle and fix merge conflicts when combining branches

bash
# During merge conflict
git status              # See conflicted files

# Resolve conflicts manually, then:
git add <resolved-file>
git commit             # Complete merge

# Abort merge
git merge --abort

# Use specific version
git checkout --ours <file>    # Keep current branch
git checkout --theirs <file>  # Take other branch
💡 Conflicts show both versions in the file
✅ Always test after resolving conflicts
🔧 Use a merge tool for complex conflicts
⚡ --ours/--theirs for quick resolution

Viewing History

Log & History

Explore repository history and find specific commits

bash
# View log
git log
git log --oneline
git log --graph --all
git log -n 5           # Last 5 commits

# Search commits
git log --grep="keyword"
git log --author="name"
git log --since="2 weeks ago"

# File history
git log -- <file>
git log -p <file>      # With changes
git blame <file>       # Line-by-line authorship
💡 Use --graph for visual branch history
⚡ Combine flags for powerful searches
📌 Blame shows who changed each line
✅ Use shortlog for contribution summary

Tags & Releases

Version Tagging

Mark specific commits as releases or milestones

bash
# List tags
git tag
git tag -l "v1.*"     # Pattern matching

# Create tag
git tag v1.0.0
git tag -a v1.0.0 -m "Version 1.0.0"  # Annotated

# Tag specific commit
git tag v1.0.0 <commit>

# Push tags
git push origin v1.0.0
git push origin --tags

# Delete tag
git tag -d v1.0.0
git push origin --delete v1.0.0
💡 Use annotated tags for releases
✅ Follow semantic versioning (v1.2.3)
📌 Tags don't push by default
⚡ Lightweight tags for temporary marks

Advanced Techniques

Submodules

Include other Git repositories within your project

bash
# Add submodule
git submodule add <url> <path>

# Clone with submodules
git clone --recursive <url>

# Update submodules
git submodule update --init
git submodule update --remote
💡 Submodules link to specific commits
⚠️ Remember to update submodules after pull
📌 Each submodule is a separate repository

Bisect (Find Bugs)

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

bash
# Start bisect
git bisect start
git bisect bad          # Current commit is bad
git bisect good <commit>  # Known good commit

# Test each commit
git bisect good         # Mark as good
git bisect bad          # Mark as bad

# Finish
git bisect reset
💡 Finds bugs using binary search
⚡ Automate with test scripts
✅ Efficiently narrows down problem commits

Worktrees

Work on multiple branches simultaneously in different directories

bash
# Add worktree
git worktree add <path> <branch>
git worktree add ../feature-branch feature

# List worktrees
git worktree list

# Remove worktree
git worktree remove <path>
💡 Each worktree is a separate working directory
⚡ Work on multiple branches without stashing
✅ Great for testing while developing

Quick Reference

Daily Workflow

Common Git workflow for everyday development

bash
# Start your day
git pull origin main

# Create feature branch
git checkout -b feature/new-feature

# Make changes
git add .
git commit -m "Add new feature"

# Push to remote
git push -u origin feature/new-feature

# Create pull request (on GitHub/GitLab)

# After PR merged
git checkout main
git pull origin main
git branch -d feature/new-feature
💡 Always pull before starting new work
✅ Use descriptive branch names
⚡ Commit often with clear messages
📌 Delete branches after merging

Useful Aliases

Set up shortcuts for common Git commands

bash
# Set up 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.last 'log -1 HEAD'
git config --global alias.unstage 'reset HEAD --'

# Advanced aliases
git config --global alias.lg "log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"
💡 Aliases save time on common commands
⚡ Create aliases for your workflow
✅ Share useful aliases with your team