A comprehensive, all-in-one reference for every Git command you'll ever need. Whether you're a beginner learning version control for the first time, a seasoned developer looking for a quick refresher, or preparing for a DevOps / software engineering interview — this is your quick guide. It covers repository setup, branching strategies, history inspection, remote collaboration, undoing mistakes, rewriting history, and much more. Each section includes concise descriptions and a full hands-on practice scenario so you can learn by doing.
⭐ Star this repo if you find it useful — it helps others discover it too!
- ⚙️ Setup & Configuration
- 📁 Creating Repositories
- 📸 Staging & Snapshots
- 🌿 Branching & Merging
- 🔍 Inspecting & Comparing
- 🌐 Sharing & Updating (Remote)
- ⏪ Undoing Changes
- ✏️ Rewriting History
- 📦 Stashing
- 🏷️ Tagging
- 🍒 Cherry-Pick
- 📂 Submodules
- 🌳 Worktrees
- 🐛 Bisect (Bug Hunting)
- 🛟 Reflog (Safety Net)
- 🩹 Patches
- 🧹 Cleaning
- 📦 Archive & Bundle
- 🕵️ Blame & Annotate
- 🪝 Hooks
- ⚡ Aliases
- 🧪 Practice Scenario
- 🤝 Contributing
- ☕ Buy Me a Coffee
- 📄 License
| Command | Description |
|---|---|
git config --global user.name "Your Name" |
Set your global username |
git config --global user.email "you@example.com" |
Set your global email |
git config --list |
List all current configuration settings |
git config --global core.editor "vim" |
Set default text editor |
git config --global init.defaultBranch main |
Set default branch name for new repos |
git config --global color.ui auto |
Enable colored output |
git config --global alias.st status |
Create a shortcut alias |
git config --global credential.helper cache |
Cache credentials in memory temporarily |
git config --global pull.rebase true |
Default to rebase on pull instead of merge |
git config --global merge.conflictstyle diff3 |
Show base version in merge conflicts |
git config --local user.email "work@company.com" |
Set repo-specific config (overrides global) |
| Command | Description |
|---|---|
git init |
Initialize a new Git repo in the current directory |
git init <directory> |
Create a new repo in the specified directory |
git init --bare |
Create a bare repo (no working directory, for servers) |
git clone <url> |
Clone a remote repo to your local machine |
git clone <url> <directory> |
Clone into a specific directory name |
git clone --depth 1 <url> |
Shallow clone — only the latest commit (faster) |
git clone --branch <branch> <url> |
Clone a specific branch |
git clone --recursive <url> |
Clone including all submodules |
| Command | Description |
|---|---|
git status |
Show the working tree status |
git status -s |
Short-format status output |
git add <file> |
Stage a specific file |
git add . |
Stage all changes in current directory and subdirectories |
git add -A |
Stage all changes across the entire repo |
git add -p |
Interactively stage hunks of changes |
git add *.js |
Stage all files matching a pattern |
git rm <file> |
Remove a file and stage the deletion |
git rm --cached <file> |
Unstage a file but keep it on disk |
git mv <old> <new> |
Rename/move a file and stage the change |
git commit -m "message" |
Commit staged changes with a message |
git commit -am "message" |
Stage all tracked file changes and commit |
git commit --amend |
Modify the last commit (message or content) |
git commit --amend --no-edit |
Add staged changes to the last commit silently |
git commit --allow-empty -m "msg" |
Create a commit with no file changes |
git commit -S -m "message" |
Create a GPG-signed commit |
| Command | Description |
|---|---|
git branch |
List local branches |
git branch -a |
List all branches (local + remote) |
git branch -r |
List remote-tracking branches only |
git branch <name> |
Create a new branch |
git branch -d <name> |
Delete a branch (safe — only if merged) |
git branch -D <name> |
Force-delete a branch |
git branch -m <old> <new> |
Rename a branch |
git branch -m <new> |
Rename the current branch |
git branch --merged |
List branches already merged into current |
git branch --no-merged |
List branches not yet merged |
git branch -vv |
Show branches with last commit and tracking info |
git checkout <branch> |
Switch to an existing branch |
git checkout -b <branch> |
Create and switch to a new branch |
git checkout -b <branch> <remote>/<branch> |
Create a local branch tracking a remote branch |
git checkout -- <file> |
Discard changes to a file in working directory |
git switch <branch> |
Switch branches (modern alternative to checkout) |
git switch -c <branch> |
Create and switch to a new branch |
git merge <branch> |
Merge a branch into the current branch |
git merge --no-ff <branch> |
Merge with a merge commit (no fast-forward) |
git merge --squash <branch> |
Squash all commits from branch into one staged change |
git merge --abort |
Abort an in-progress merge |
git rebase <branch> |
Rebase current branch onto another branch |
git rebase -i HEAD~<n> |
Interactive rebase for the last n commits |
git rebase --onto <new> <old> <branch> |
Rebase a range of commits onto a new base |
git rebase --abort |
Abort an in-progress rebase |
git rebase --continue |
Continue rebase after resolving conflicts |
| Command | Description |
|---|---|
git log |
Show commit history |
git log --oneline |
Compact one-line-per-commit log |
git log --oneline --graph --all |
Visual graph of all branches |
git log --stat |
Show files changed in each commit |
git log -p |
Show full diffs for each commit |
git log -n <number> |
Show only the last n commits |
git log --author="name" |
Filter commits by author |
git log --since="2024-01-01" |
Commits after a date |
git log --until="2024-12-31" |
Commits before a date |
git log --grep="keyword" |
Search commit messages |
git log -S "string" |
Find commits that added or removed a string (pickaxe) |
git log -- <file> |
History of a specific file |
git log --follow <file> |
Track a file across renames |
git log <branch1>..<branch2> |
Commits in branch2 not in branch1 |
git log --pretty=format:"%h %an %s" |
Custom formatted log |
git shortlog -sn |
Summarize commits per author |
git diff |
Show unstaged changes |
git diff --staged |
Show staged changes (also --cached) |
git diff <branch1>..<branch2> |
Diff between two branches |
git diff <commit1>..<commit2> |
Diff between two commits |
git diff --name-only |
List only the names of changed files |
git diff --stat |
Summary of changes (insertions/deletions) |
git diff --word-diff |
Inline word-level diff |
git show <commit> |
Show details and diff of a specific commit |
git show <commit>:<file> |
Show a file as it was at a specific commit |
| Command | Description |
|---|---|
git remote |
List remote names |
git remote -v |
List remotes with URLs |
git remote add <name> <url> |
Add a new remote |
git remote remove <name> |
Remove a remote |
git remote rename <old> <new> |
Rename a remote |
git remote set-url <name> <url> |
Change a remote's URL |
git remote show <name> |
Show info about a remote |
git fetch |
Download objects/refs from remote (don't merge) |
git fetch --all |
Fetch from all remotes |
git fetch --prune |
Fetch and remove stale remote-tracking branches |
git fetch <remote> <branch> |
Fetch a specific branch |
git pull |
Fetch and merge remote changes |
git pull --rebase |
Fetch and rebase instead of merge |
git pull <remote> <branch> |
Pull a specific remote branch |
git push |
Push commits to the tracked remote branch |
git push <remote> <branch> |
Push to a specific remote/branch |
git push -u origin <branch> |
Push and set upstream tracking |
git push --all |
Push all local branches |
git push --tags |
Push all tags |
git push --force |
Force push (overwrites remote — use with care) |
git push --force-with-lease |
Safer force push — fails if remote was updated |
git push origin --delete <branch> |
Delete a remote branch |
git push origin :<branch> |
Shorthand to delete a remote branch |
| Command | Description |
|---|---|
git checkout -- <file> |
Discard unstaged changes to a file |
git restore <file> |
Discard unstaged changes (modern syntax) |
git restore --staged <file> |
Unstage a file (keep changes in working dir) |
git reset <file> |
Unstage a file (legacy syntax) |
git reset |
Unstage everything but keep working dir changes |
git reset --soft HEAD~1 |
Undo last commit, keep changes staged |
git reset --mixed HEAD~1 |
Undo last commit, keep changes unstaged (default) |
git reset --hard HEAD~1 |
Undo last commit and discard all changes |
git reset --hard <commit> |
Reset branch to a specific commit (destructive) |
git revert <commit> |
Create a new commit that undoes a specific commit |
git revert --no-commit <commit> |
Revert changes without auto-committing |
git revert HEAD~3..HEAD |
Revert the last 3 commits |
git clean -fd |
Remove untracked files and directories |
git clean -n |
Dry run — show what would be removed |
git checkout <commit> -- <file> |
Restore a file from a specific commit |
| Command | Description |
|---|---|
git rebase -i HEAD~<n> |
Interactively edit/squash/reorder the last n commits |
git commit --amend |
Edit the most recent commit |
git filter-branch --tree-filter '<cmd>' HEAD |
Rewrite history by running a command on each commit |
git filter-repo --path <file> --invert-paths |
Remove a file from entire history (use git-filter-repo) |
git reflog |
View the reflog to recover lost commits |
git reset --hard <reflog-entry> |
Recover to a reflog state |
⚠️ Warning: Rewriting history on shared branches can cause problems for collaborators. Only rewrite history on local/feature branches.
| Command | Description |
|---|---|
git stash |
Stash current uncommitted changes |
git stash push -m "description" |
Stash with a descriptive message |
git stash list |
List all stashes |
git stash show |
Show a summary of the latest stash |
git stash show -p |
Show full diff of the latest stash |
git stash show stash@{n} |
Show a specific stash |
git stash pop |
Apply the latest stash and remove it |
git stash apply |
Apply the latest stash but keep it in the list |
git stash apply stash@{n} |
Apply a specific stash |
git stash drop stash@{n} |
Delete a specific stash |
git stash clear |
Remove all stashes |
git stash branch <name> |
Create a branch from a stash |
git stash push -p |
Interactively select hunks to stash |
git stash --include-untracked |
Stash including untracked files |
git stash --all |
Stash including ignored files |
| Command | Description |
|---|---|
git tag |
List all tags |
git tag <name> |
Create a lightweight tag |
git tag -a <name> -m "message" |
Create an annotated tag with a message |
git tag -a <name> <commit> |
Tag a specific past commit |
git tag -d <name> |
Delete a local tag |
git push origin <tag> |
Push a specific tag to remote |
git push origin --tags |
Push all tags to remote |
git push origin --delete <tag> |
Delete a remote tag |
git show <tag> |
Show tag details |
git describe --tags |
Describe current commit relative to nearest tag |
git tag -l "v1.*" |
List tags matching a pattern |
| Command | Description |
|---|---|
git cherry-pick <commit> |
Apply a specific commit to the current branch |
git cherry-pick <c1> <c2> <c3> |
Cherry-pick multiple commits |
git cherry-pick <start>..<end> |
Cherry-pick a range of commits |
git cherry-pick --no-commit <commit> |
Apply changes without committing |
git cherry-pick --abort |
Abort an in-progress cherry-pick |
git cherry-pick --continue |
Continue after resolving conflicts |
| Command | Description |
|---|---|
git submodule add <url> <path> |
Add a submodule |
git submodule init |
Initialize submodule configuration |
git submodule update |
Fetch and checkout submodule commits |
git submodule update --init --recursive |
Initialize and update all submodules recursively |
git submodule status |
Show the status of submodules |
git submodule foreach '<cmd>' |
Run a command in each submodule |
git submodule deinit <path> |
Unregister a submodule |
git rm <submodule-path> |
Remove a submodule |
| Command | Description |
|---|---|
git worktree add <path> <branch> |
Create a new working tree for a branch |
git worktree add -b <new-branch> <path> |
Create a new branch in a new worktree |
git worktree list |
List all linked worktrees |
git worktree remove <path> |
Remove a linked worktree |
git worktree prune |
Clean up stale worktree metadata |
| Command | Description |
|---|---|
git bisect start |
Begin a bisect session |
git bisect bad |
Mark current commit as bad (has the bug) |
git bisect good <commit> |
Mark a commit as good (no bug) |
git bisect reset |
End the bisect session |
git bisect skip |
Skip the current commit |
git bisect log |
Show the bisect log |
git bisect run <script> |
Automate bisect with a test script |
| Command | Description |
|---|---|
git reflog |
Show history of HEAD movements |
git reflog show <branch> |
Show reflog for a specific branch |
git reflog expire --expire=30.days |
Expire reflog entries older than 30 days |
git reset --hard HEAD@{n} |
Restore HEAD to a reflog entry |
git checkout HEAD@{n} |
Check out a previous HEAD state |
| Command | Description |
|---|---|
git format-patch <commit> |
Create patch files for commits since the given commit |
git format-patch -1 <commit> |
Create a patch for a single commit |
git format-patch -n HEAD~<n> |
Create patches for the last n commits |
git am <patch-file> |
Apply a patch file |
git am --abort |
Abort patch application |
git apply <patch-file> |
Apply a patch without creating a commit |
git diff > changes.patch |
Export unstaged changes as a patch file |
git apply changes.patch |
Apply a diff-format patch |
| Command | Description |
|---|---|
git clean -n |
Dry run — preview files that would be removed |
git clean -f |
Remove untracked files |
git clean -fd |
Remove untracked files and directories |
git clean -fx |
Remove untracked and ignored files |
git clean -fX |
Remove only ignored files |
git clean -fdx |
Remove everything not tracked (nuclear option) |
git gc |
Run garbage collection |
git gc --aggressive |
More thorough garbage collection |
git prune |
Remove unreachable objects |
| Command | Description |
|---|---|
git archive --format=zip HEAD > repo.zip |
Create a zip of the current HEAD |
git archive --format=tar HEAD > repo.tar |
Create a tarball of HEAD |
git archive --format=zip --prefix=project/ HEAD > project.zip |
Archive with a directory prefix |
git bundle create repo.bundle --all |
Create a bundle of the entire repo |
git bundle create repo.bundle main |
Bundle a specific branch |
git clone repo.bundle |
Clone from a bundle file |
git bundle verify repo.bundle |
Verify a bundle file |
| Command | Description |
|---|---|
git blame <file> |
Show who last modified each line |
git blame -L <start>,<end> <file> |
Blame a specific line range |
git blame -w <file> |
Ignore whitespace changes in blame |
git blame -C <file> |
Detect lines moved or copied from other files |
git blame --since="3 weeks ago" <file> |
Only show recent blame entries |
git annotate <file> |
Similar to blame with slightly different output |
git log -p -S "function_name" -- <file> |
Track how a specific piece of code evolved |
Git hooks are scripts that run automatically at certain lifecycle events. They live in .git/hooks/.
| Hook | Trigger |
|---|---|
pre-commit |
Before a commit is created |
prepare-commit-msg |
Before the commit message editor opens |
commit-msg |
After the commit message is entered (validate it) |
post-commit |
After a commit is created |
pre-push |
Before a push is executed |
pre-rebase |
Before a rebase starts |
post-merge |
After a merge is completed |
post-checkout |
After a checkout or switch |
pre-receive |
Server-side: before refs are updated |
post-receive |
Server-side: after refs are updated |
Example — Create a pre-commit hook that runs linting:
cat > .git/hooks/pre-commit << 'EOF'
#!/bin/sh
npm run lint
if [ $? -ne 0 ]; then
echo "Lint failed. Commit aborted."
exit 1
fi
EOF
chmod +x .git/hooks/pre-commitSpeed up your workflow with aliases:
git config --global alias.st "status"
git config --global alias.co "checkout"
git config --global alias.br "branch"
git config --global alias.ci "commit"
git config --global alias.lg "log --oneline --graph --all --decorate"
git config --global alias.last "log -1 HEAD"
git config --global alias.unstage "reset HEAD --"
git config --global alias.undo "reset --soft HEAD~1"
git config --global alias.wip "commit -am 'WIP'"
git config --global alias.aliases "config --get-regexp alias"Below is a hands-on scenario that walks through most Git commands. Run these in your terminal to practice.
mkdir git-practice && cd git-practice
git init
git config user.name "Practice User"
git config user.email "practice@example.com"# Create a file and make the first commit
echo "# My Project" > README.md
git add README.md
git commit -m "Initial commit"
# Create a feature branch and add work
git checkout -b feature/login
echo "def login(user, password):" > auth.py
echo " return True" >> auth.py
git add auth.py
git commit -m "Add login function"
# Make another change on the feature branch
echo "def logout(user):" >> auth.py
echo " return True" >> auth.py
git add auth.py
git commit -m "Add logout function"
# Switch back to main and merge the feature
git checkout main
git merge --no-ff feature/login -m "Merge feature/login into main"
# Check the visual log
git log --oneline --graph --all# Start new work but need to switch context
echo "TODO: add password hashing" >> auth.py
git stash push -m "wip: password hashing"
# Do a quick fix on main
echo "v1.0" > VERSION
git add VERSION
git commit -m "Add version file"
# Tag the release
git tag -a v1.0 -m "First stable release"
# Restore stashed work
git stash pop
git add auth.py
git commit -m "Add password hashing TODO"# Create two parallel branches
git checkout -b feature/signup
echo "def signup(email):" > signup.py
echo " return True" >> signup.py
git add signup.py
git commit -m "Add signup function"
git checkout main
echo "Updated README" >> README.md
git add README.md
git commit -m "Update README"
# Rebase feature branch onto updated main
git checkout feature/signup
git rebase main
# Cherry-pick a commit to a hotfix branch
git checkout main
git checkout -b hotfix/urgent
git cherry-pick feature/signup # picks the tip of feature/signup
# Undo the cherry-pick with reset
git reset --soft HEAD~1
git status # changes are staged but uncommitted
git reset # unstage everything
git checkout main# View diffs
echo "extra line" >> README.md
git diff # unstaged changes
git add README.md
git diff --staged # staged changes
# Blame a file
git blame auth.py
# Simulate bisect (mark commits)
git bisect start
git bisect bad # current commit is bad
git bisect good v1.0 # v1.0 was good
# Git checks out a midpoint; test, then:
git bisect reset # end the session# Create some untracked files
touch temp1.txt temp2.txt
mkdir temp_dir && touch temp_dir/junk.txt
# Preview and clean
git clean -n # dry run
git clean -fd # remove untracked files and dirs
# Delete merged branches
git branch --merged | grep -v "main" | xargs git branch -d
# Final state
git log --oneline --graph --allWorking Dir ──git add──▶ Staging ──git commit──▶ Local Repo ──git push──▶ Remote
◀──git restore── ◀──git restore --staged── ◀──git pull──
| I want to... | Command |
|---|---|
| 💾 Save my work | git commit -am "msg" |
| ↩️ Undo last commit (keep files) | git reset --soft HEAD~1 |
| 🗑️ Undo last commit (lose files) | git reset --hard HEAD~1 |
| 👀 See what changed | git diff |
| 📜 See commit history | git log --oneline |
| 🔀 Switch branches | git switch <branch> |
| 📦 Save work temporarily | git stash |
| 📤 Get work back | git stash pop |
| 🔙 Undo a pushed commit safely | git revert <commit> |
| 🕵️ Find who changed a line | git blame <file> |
| 🐛 Find which commit broke something | git bisect start |
| 🛟 Recover something lost | git reflog |
Contributions are welcome! If you'd like to improve this cheatsheet — fix a typo, add a missing command, or suggest a better example — here's how:
- Fork this repository.
- Create a branch for your change:
git checkout -b improve-cheatsheet
- Make your edits and commit with a clear message:
git commit -m "Add missing git sparse-checkout commands" - Push your branch and open a Pull Request:
git push origin improve-cheatsheet
- Describe what you changed and why in the PR description.
Guidelines:
- Keep commands and descriptions concise.
- Follow the existing table format.
- Test any practice scenario steps you add.
- One topic per PR keeps reviews fast.
If this cheatsheet saved you time or helped you learn something new, consider buying me a coffee!
https://buymeacoffee.com/connectankush
Your support and feedback are valuable in maintaining and improving this resource. 🙏
This project is licensed under the MIT License.
Happy Gitting! 🎉