Git logoGit v2.40BEGINNER

Git

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

8 min read
gitversion-controlgithubcommandsworkflow

Getting Started

Initial Setup

Configure Git for first time use with your identity

bash
💡 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
💡 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
💡 .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
💡 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 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
💡 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
💡 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
⚠️ 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
💡 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
💡 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 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
💡 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 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
💡 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
💡 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
💡 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
💡 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
💡 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
💡 Finds bugs using binary search
⚡ Automate with test scripts
✅ Efficiently narrows down problem commits

Worktrees

Work on multiple branches simultaneously in different directories

bash
💡 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
💡 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
💡 Aliases save time on common commands
⚡ Create aliases for your workflow
✅ Share useful aliases with your team