# Git Commands Cheatsheet
Git's day-to-day command set is small; the confusion comes from the handful of commands that rewrite history or discard changes. This sheet groups the safe daily commands separately from the destructive ones, and flags exactly which ones can lose work.
| Command | Effect |
|---|---|
| `git status` | What's changed, staged vs unstaged |
| `git add <file>` / `git add -A` | Stage a file / stage everything |
| `git commit -m "msg"` | Commit staged changes |
| `git commit --amend` | Rewrite the *previous* commit (message and/or content) |
| `git push` | Push commits to the tracked remote branch |
| `git pull` | Fetch + merge (or rebase, if configured) from the remote |
| `git log --oneline` | Compact commit history |
| `git diff` | Unstaged changes vs the working tree |
| `git diff --staged` | Staged changes vs the last commit |
| Command | Effect |
|---|---|
| `git branch` | List local branches |
| `git branch <name>` | Create a branch (doesn't switch to it) |
| `git checkout -b <name>` / `git switch -c <name>` | Create and switch to a new branch |
| `git checkout <name>` / `git switch <name>` | Switch branches |
| `git branch -d <name>` | Delete a branch (fails if unmerged) |
| `git branch -D <name>` | Force-delete a branch, merged or not |
| `git merge <branch>` | Merge another branch into the current one |
| `git rebase <branch>` | Replay current branch's commits on top of another branch |
| Command | Effect | Destructive? |
|---|---|---|
| `git restore <file>` | Discard unstaged changes to a file | Yes — uncommitted work is gone |
| `git restore --staged <file>` | Unstage a file, keep the edits | No |
| `git reset --soft HEAD~1` | Undo last commit, keep changes staged | No |
| `git reset --mixed HEAD~1` | Undo last commit, keep changes unstaged (default mode) | No |
| `git reset --hard HEAD~1` | Undo last commit AND discard the changes | **Yes** |
| `git revert <commit>` | Create a new commit that undoes another commit | No (safe on shared branches) |
| `git stash` | Shelve uncommitted changes | No (recoverable via `stash list`) |
| `git clean -fd` | Delete untracked files and directories | **Yes** |
git stash push -u -m "wip: feature x" # -u also stashes untracked files
git checkout main
# ...do something else...
git stash pop # re-apply and drop the stash entry
git add forgotten-file.js
git commit --amend --no-edit
Only amend commits that haven't been pushed yet — amending a pushed commit rewrites history and forces everyone else to pull --rebase or reset to reconcile.
git cherry-pick <commit-sha>
git rebase -i HEAD~3
# mark commits as "squash" or "fixup" in the editor that opens
git revert HEAD
git push
revert adds a new commit instead of rewriting history, so it's safe on branches other people have already pulled — unlike reset --hard + force-push.
git reset --hard discards uncommitted changes permanently: there is no undo for the working-tree changes it throws away (the commits it moves past are usually recoverable via git reflog, but uncommitted edits are not). Always git stash or commit first if there's any doubt.git push --force overwrites the remote branch, dropping others' commits: if a teammate pushed after you last pulled, a force-push can silently erase their work. git push --force-with-lease is the safer default — it refuses if the remote has commits you haven't seen.git checkout -- <file> and git restore <file> both discard changes with no confirmation: neither prompts before deleting your edits; both are one-way unless you've committed or stashed first.git merge vs git rebase rewrite history differently: rebase changes commit SHAs on the branch being replayed, which breaks references anyone else holds to those commits (open PRs, local checkouts). Never rebase a branch other people are actively working from..gitignore doesn't un-track already-committed files: adding a pattern to .gitignore only stops new files matching it from being tracked. A file already in the repo needs git rm --cached <file> before the ignore rule takes effect.git diff does, useful for comparing text outside a repo (commit messages, config snippets, pasted output).git log --oneline — generate and compare hashes here.git push usually deploys to.