Bookmark this page. Use Ctrl+F (or Cmd+F on Mac) to find what you need. This cheat sheet covers Git commands from basics to advanced workflows.
Last updated: April 2026
Setup and Config#
| Command | Description |
|---|
git config --global user.name "Alex" | Set your name (shown in commits) |
git config --global user.email "alex@example.com" | Set your email |
git config --global init.defaultBranch main | Set default branch name |
git config --list | Show all config settings |
git init | Create a new repository |
git clone <url> | Clone a remote repository |
git clone <url> <folder> | Clone into a specific folder |
Basic Workflow#
| Command | Description |
|---|
git status | Show changed, staged, and untracked files |
git add <file> | Stage a file for commit |
git add . | Stage all changes |
git add -p | Stage changes interactively (hunk by hunk) |
git commit -m "message" | Commit staged changes |
git commit -am "message" | Stage tracked files and commit (does NOT stage untracked files) |
git commit --amend | Modify the last commit (add files or fix message) |
git diff | Show unstaged changes |
git diff --staged | Show staged changes (ready to commit) |
git diff HEAD | Show all changes (staged + unstaged) |
Working Directory → git add → Staging Area → git commit → Repository
Viewing History#
| Command | Description |
|---|
git log | Show commit history |
git log --oneline | One line per commit |
git log --oneline --graph --all | Visual branch graph |
git log -5 | Show last 5 commits |
git log --author="Alex" | Filter by author |
git log --since="2026-01-01" | Commits after a date |
git log -- <file> | History of a specific file |
git show <commit> | Show details of a commit |
git blame <file> | Show who changed each line |
Branching#
| Command | Description |
|---|
git branch | List local branches |
git branch -a | List all branches (local + remote) |
git branch <name> | Create a new branch |
git branch -d <name> | Delete a branch (safe — won’t delete unmerged) |
git branch -D <name> | Force delete a branch |
git branch -m <old> <new> | Rename a branch |
git switch <name> | Switch to a branch |
git switch -c <name> | Create and switch to a new branch |
git checkout <name> | Switch to a branch (older syntax) |
git checkout -b <name> | Create and switch (older syntax) |
Branch Workflow (ASCII Diagram)#
main: A --- B --- C --- F (merge commit)
\ /
feature: D --- E -
Merging#
| Command | Description |
|---|
git merge <branch> | Merge branch into current branch |
git merge --no-ff <branch> | Force a merge commit (no fast-forward) |
git merge --squash <branch> | Merge all commits as one (does not auto-commit) |
git merge --abort | Cancel a merge in progress |
Resolving Conflicts#
When Git cannot auto-merge, it marks conflicts in the file:
<<<<<<< HEAD
your changes
=======
their changes
>>>>>>> feature-branch
Fix the conflict, then:
git add <resolved-file>
git commit
Rebasing#
| Command | Description |
|---|
git rebase <branch> | Replay current commits on top of branch |
git rebase --abort | Cancel a rebase in progress |
git rebase --continue | Continue after resolving a conflict |
git rebase -i HEAD~3 | Interactive rebase — squash, edit, reorder last 3 commits |
Merge vs Rebase#
# Merge — creates a merge commit, preserves history
git checkout main
git merge feature
# Rebase — replays commits, creates linear history
git checkout feature
git rebase main
Rule of thumb: Rebase your local branches. Never rebase branches that others are working on.
Remote Repositories#
| Command | Description |
|---|
git remote -v | Show remote URLs |
git remote add origin <url> | Add a remote |
git push | Push to the tracking remote branch |
git push -u origin <branch> | Push and set upstream tracking |
git push origin --delete <branch> | Delete a remote branch |
git pull | Fetch + merge from remote |
git pull --rebase | Fetch + rebase from remote |
git pull --ff-only | Pull only if fast-forward is possible (safest) |
git fetch | Download changes without merging |
git fetch --all | Fetch from all remotes |
git fetch --prune | Fetch and remove deleted remote branches |
Undo Changes#
| Command | Description |
|---|
git restore <file> | Discard unstaged changes in a file |
git restore --staged <file> | Unstage a file (keep changes) |
git reset HEAD~1 | Undo last commit (keep changes unstaged) |
git reset --soft HEAD~1 | Undo last commit (keep changes staged) |
git reset --hard HEAD~1 | Undo last commit and discard changes |
git revert <commit> | Create a new commit that undoes a commit |
git clean -fd | Remove untracked files and directories |
When to Use What#
| Situation | Command |
|---|
| Undo uncommitted file changes | git restore <file> |
| Unstage a file | git restore --staged <file> |
| Undo the last commit (keep work) | git reset HEAD~1 |
| Undo a commit already pushed | git revert <commit> |
| Recover a deleted branch/commit | git reflog |
Stash#
| Command | Description |
|---|
git stash | Save changes and clean working directory |
git stash -m "description" | Stash with a message |
git stash list | Show all stashes |
git stash pop | Apply latest stash and remove it |
git stash apply | Apply latest stash (keep in stash list) |
git stash drop | Remove latest stash |
git stash clear | Remove all stashes |
git stash pop "stash@{2}" | Apply a specific stash (quote braces in Zsh) |
| Command | Description |
|---|
git tag | List all tags |
git tag v1.0.0 | Create a lightweight tag |
git tag -a v1.0.0 -m "Release 1.0" | Create an annotated tag |
git push origin v1.0.0 | Push a specific tag |
git push origin --tags | Push all tags |
git tag -d v1.0.0 | Delete a local tag |
Advanced Commands#
| Command | Description |
|---|
git cherry-pick <commit> | Apply a specific commit to current branch |
git bisect start | Start binary search for a bug |
git bisect bad | Mark current commit as bad |
git bisect good <commit> | Mark a commit as good |
git reflog | Show history of HEAD movements (recovery tool) |
git log -S "text" | Find commits that added/removed a string (pickaxe) |
git log --diff-filter=D --name-only | Find deleted files |
git worktree add ../temp main | Check out a branch in a separate folder |
git push --force-with-lease | Safer force push (fails if remote changed) |
git branch --set-upstream-to=origin/<branch> | Set upstream tracking branch |
Recovering Lost Commits#
# See all recent HEAD movements
git reflog
# Restore to a previous state
git reset --hard HEAD@{3}
# Or create a branch from a lost commit
git branch recovered HEAD@{3}
.gitignore#
# Compiled files
*.class
*.o
build/
# IDE files
.idea/
.vscode/
*.iml
# OS files
.DS_Store
Thumbs.db
# Environment files
.env
.env.local
# Dependencies
node_modules/
Check if a file is ignored: git check-ignore -v <file>
Common Workflows#
Feature Branch Workflow#
git switch -c feature/login
# ... make changes ...
git add .
git commit -m "Add login page"
git push -u origin feature/login
# Create pull request on GitHub
# After merge, clean up:
git switch main
git pull
git branch -d feature/login
Fix a Mistake on the Wrong Branch#
# Stash your changes
git stash
# Switch to the correct branch
git switch correct-branch
# Apply stashed changes
git stash pop
Common Mistakes#
Committing to the wrong branch — Use git stash, switch branches, then git stash pop. If you already committed, use git reset HEAD~1 to undo the commit (changes stay), then switch branches.
Force pushing to main — git push --force rewrites remote history and can destroy your team’s work. Use git push --force-with-lease instead — it only force-pushes if no one else has pushed since your last fetch.
Forgetting to pull before push — Always git pull (or git pull --rebase) before pushing. Otherwise your push will be rejected if the remote has new commits.