git initCreate a new empty git repository in the current directory.
⚠ Common pitfall: Running inside an existing repo creates a nested .git that confuses tooling. Run `git status` first.
git init
git init my-project
Git command cheat sheet — searchable, with explanations, common mistakes, and real examples.
git initCreate a new empty git repository in the current directory.
⚠ Common pitfall: Running inside an existing repo creates a nested .git that confuses tooling. Run `git status` first.
git init
git init my-project
git clone <url>Download a remote repository into a new local directory, with full history.
⚠ Common pitfall: For huge repos use --depth=1 (shallow) to skip history; you cannot push amends from a shallow clone without --unshallow.
git clone https://github.com/user/repo.git
git clone --depth=1 https://github.com/user/repo.git
git statusShow changed, staged and untracked files in the working tree.
git status
git status -s
git add <file>Stage a file (or all files with .) for the next commit.
⚠ Common pitfall: `git add .` from a subdirectory only adds that subtree; `git add -A` stages everything in the repo including deletions.
git add src/index.ts
git add .
git add -A
git add -p
git commit -m "msg"Record staged changes as a new commit with the given message.
⚠ Common pitfall: Forgetting to stage first creates an empty commit error; -am only stages tracked files (not new files).
git commit -m "fix: handle null user"
git commit -am "wip"
git commit --amendReplace the last commit with a new one (message and/or content).
⚠ Common pitfall: Amending a pushed commit rewrites history — collaborators need to force-pull or face conflicts.
git commit --amend
git commit --amend --no-edit
git commit --amend -m "better message"
git pushUpload local commits on the current branch to the tracked remote.
git push
git push origin main
git push -u origin <branch>Push a new local branch to the remote and set it as the upstream tracking branch.
⚠ Common pitfall: Without -u, future `git push` on this branch will keep asking for the remote/branch.
git push -u origin feature/login
git pullFetch changes from the tracked remote branch and merge them into the current branch.
⚠ Common pitfall: Default pull = fetch + merge, which creates merge commits. Many teams prefer `git pull --rebase`.
git pull
git pull --rebase
git fetchDownload new commits, refs and objects from a remote, but do NOT merge anything into your branches.
git fetch
git fetch origin
git fetch --all --prune
git clone --depth=1 <url>Shallow clone with only the latest commit (no history). Much faster for CI builds.
⚠ Common pitfall: Cannot push or rebase from a shallow clone until you run `git fetch --unshallow`.
git clone --depth=1 https://github.com/torvalds/linux.git
git mv <src> <dst>Rename or move a file and stage the change in one step.
git mv old-name.ts new-name.ts
git log -n 5Show only the last 5 commits (any number works).
git log -n 5
git log -3 --oneline
git tag <name>Create a lightweight tag on the current commit. Use -a for an annotated tag with message + tagger.
⚠ Common pitfall: Annotated tags (`git tag -a v1.0 -m "..."`) are recommended for releases — lightweight tags do not store metadata.
git tag v1.0.0
git tag -a v1.0.0 -m "first stable release"
git tag -d <name>Delete a local tag. To delete the remote tag too: `git push --delete origin <name>`.
git tag -d v1.0.0
git push --delete origin v1.0.0
git rm <file>Remove a file from the working tree AND stage the deletion.
⚠ Common pitfall: Use `git rm --cached <file>` to stop tracking without deleting from disk (e.g. for files newly added to .gitignore).
git rm secret.env
git rm --cached config.local.json
git branchList local branches; * marks the current branch.
git branch
git branch -a
git branch -vv
git branch <name>Create a new branch from the current HEAD, but do not switch to it.
git branch feature/login
git branch -d <name>Delete a local branch (safely — fails if it has unmerged commits).
⚠ Common pitfall: Use -D (capital) to force-delete unmerged branches — irreversible without reflog.
git branch -d feature/done
git branch -D feature/wip
git branch -m <new>Rename the current branch.
git branch -m main
git branch -m old-name new-name
git checkout <branch>Switch to an existing branch (legacy command — git switch is the modern replacement).
⚠ Common pitfall: `git checkout <file>` and `git checkout <branch>` are different commands sharing one name — confusing. Use `git switch` and `git restore`.
git checkout main
git checkout -
git checkout -b <new>Create a new branch from current HEAD and switch to it in one step.
git checkout -b feature/login
git checkout -b hotfix origin/main
git switch <branch>Switch to an existing branch. Modern replacement for `git checkout <branch>`.
git switch main
git switch -
git switch -c <new>Create and switch to a new branch. Modern replacement for `git checkout -b`.
git switch -c feature/login
git switch -c hotfix origin/main
git merge <branch>Merge the named branch into the current branch.
⚠ Common pitfall: Default merge creates a merge commit even when fast-forward is possible. Use `--ff-only` to refuse non-FF merges or `--no-ff` to always make a merge commit.
git merge feature/login
git merge --no-ff feature/login
git merge --ff-only origin/main
git merge --abortCancel an in-progress merge and restore the pre-merge state.
git merge --abort
git rebase <branch>Replay commits from current branch on top of <branch>. Linear history, but rewrites commit IDs.
⚠ Common pitfall: Never rebase commits already pushed to a shared branch — collaborators will get conflicts on every pull.
git rebase main
git rebase origin/main
git rebase --abortCancel an in-progress rebase and restore the pre-rebase state.
git rebase --abort
git rebase --continueAfter resolving conflicts during rebase, continue replaying remaining commits.
git add resolved-file.ts && git rebase --continue
git cherry-pick <sha>Apply the changes from a specific commit onto the current branch as a new commit.
⚠ Common pitfall: The cherry-picked commit gets a NEW SHA. Cherry-picking the same change twice creates duplicate logic.
git cherry-pick a1b2c3d
git cherry-pick a1b2c3d..f4e5d6c
git cherry-pick -x a1b2c3d
git branch -aList ALL branches (local + remote-tracking).
git branch -a
git branch --mergedList local branches fully merged into the current branch — safe to delete.
git branch --merged main
git branch --merged | grep -v "\*" | xargs git branch -d
git reset HEAD <file>Unstage a file (keep changes in the working tree).
git reset HEAD src/index.ts
git reset HEAD .
git reset --soft HEAD~1Undo the last commit but keep changes staged. The most "non-destructive" reset.
git reset --soft HEAD~1
git reset --mixed HEAD~1Undo the last commit and unstage everything, but keep working tree changes. This is the default.
git reset HEAD~1
git reset --mixed HEAD~1
git reset --hard HEAD~1Throw away the last commit AND wipe matching working tree changes. Destructive.
⚠ Common pitfall: Anything not committed AND not in reflog is gone. Run `git stash` first if you might want it back.
git reset --hard HEAD~1
git reset --hard origin/main
git revert <sha>Create a new commit that undoes the changes of <sha>. Safe on shared branches — does NOT rewrite history.
git revert a1b2c3d
git revert HEAD
git revert -m 1 <merge-sha>
git restore <file>Discard unstaged changes in a file (modern replacement for `git checkout -- <file>`).
git restore src/broken.ts
git restore .
git restore --staged <file>Unstage a file but keep working tree changes (modern replacement for `git reset HEAD <file>`).
git restore --staged src/index.ts
git stashSave uncommitted changes (staged + unstaged) onto a stack and reset the working tree.
⚠ Common pitfall: By default `git stash` does NOT include untracked files; use `git stash -u` to include them.
git stash
git stash -u
git stash push -m "WIP login form"
git stash popRe-apply the most recent stash AND remove it from the stash stack.
⚠ Common pitfall: If pop has conflicts the stash stays on the stack — fix conflicts then `git stash drop`.
git stash pop
git stash pop stash@{2}git stash listList all stashes with their indexes and messages.
git stash list
git stash dropDelete a single stash without applying it.
git stash drop
git stash drop stash@{1}git reflogShow local history of HEAD movements. Lifesaver for recovering lost commits / branches.
⚠ Common pitfall: Reflog is LOCAL ONLY — pushing/cloning does not copy it. Default expiry is 90 days.
git reflog
git reset --hard HEAD@{1}git clean -fdDelete untracked files (-f) and untracked directories (-d) from the working tree.
⚠ Common pitfall: Irreversible. Always `git clean -nfd` (dry-run) first to see what will be deleted.
git clean -nfd
git clean -fd
git clean -fdx
git remote -vList all remotes with their fetch and push URLs.
git remote -v
git remote add <name> <url>Add a new remote under the given short name (usually `origin` or `upstream`).
git remote add origin https://github.com/me/repo.git
git remote add upstream https://github.com/orig/repo.git
git remote set-url <name> <url>Change the URL of an existing remote (e.g. switching from HTTPS to SSH).
git remote set-url origin git@github.com:me/repo.git
git remote rename <old> <new>Rename a remote.
git remote rename origin github
git remote remove <name>Remove a remote entirely (does NOT delete the remote repo itself).
git remote remove old-upstream
git fetch --pruneFetch from remote AND delete local remote-tracking branches whose remote counterparts are gone.
git fetch --prune
git fetch -p origin
git pull --rebaseFetch from remote and rebase local commits on top — keeps history linear, avoids merge commits.
⚠ Common pitfall: If you have unrelated remote changes and rebase fails, run `git rebase --abort` to back out.
git pull --rebase
git config --global pull.rebase true
git push --tagsPush local tags to the remote (regular push does not include them).
git push --tags
git push origin v1.2.0
git push --delete origin <branch>Delete a branch on the remote.
git push --delete origin feature/old
git push origin :feature/old
git ls-remote <url>List refs (branches, tags) on a remote WITHOUT cloning. Handy for inspecting a repo before downloading.
git ls-remote https://github.com/torvalds/linux.git
git ls-remote --heads origin
git push --force-with-leaseForce-push, but ONLY if the remote tip is what you last saw. The safe force-push.
⚠ Common pitfall: Plain --force overwrites teammates work silently. Always use --force-with-lease on shared branches.
git push --force-with-lease
git push --force-with-lease origin feature/login
git rebase -i HEAD~NInteractively rewrite the last N commits: reorder, squash, fixup, reword, drop.
⚠ Common pitfall: Rebasing pushed commits = history rewrite. Only do it on your own branches before PR.
git rebase -i HEAD~5
git rebase -i main
git commit --fixup=<sha>Create a fixup commit targeting <sha>. With `git rebase -i --autosquash` it auto-squashes into the right spot.
git commit --fixup=a1b2c3d
git rebase -i --autosquash main
git merge --squash <branch>Squash all commits of <branch> into one staged change without committing — you then write one summary commit.
git merge --squash feature/login
git commit -m "feat: login flow"
git format-patch <branch>Generate .patch files for each commit since <branch>. Used to mail patches to mailing lists (Linux kernel style).
git format-patch main
git format-patch -1 HEAD
git am <patch>Apply a mailbox-style patch (created by format-patch) as one or more commits.
git am 0001-fix-bug.patch
git request-pull <start> <url>Generate a summary of changes for asking an upstream maintainer to pull from you (pre-GitHub workflow).
git request-pull v1.0 https://github.com/me/repo feature-x
git pull --rebase --autostashAuto-stash dirty working tree, pull --rebase, then unstash. Great alias for the daily pull.
git pull --rebase --autostash
git config --global rebase.autoStash true
git worktree add <path> <branch>Check out an additional branch into a separate working directory — work on two branches without stashing.
⚠ Common pitfall: Worktrees share the same .git, so reflog / index ops still affect each other. List with `git worktree list`.
git worktree add ../hotfix hotfix/login
git worktree list
git worktree remove ../hotfix
git config --global user.name "Name"Set your global git author name (applies to all repos).
git config --global user.name "Alice Wang"
git config --global user.email "you@example.com"Set your global git author email.
⚠ Common pitfall: Use a per-repo `git config user.email` inside work repos to keep personal/work commit attribution separate.
git config --global user.email "alice@company.com"
git config user.email "alice@personal.com"
git config --listShow every effective config setting (system + global + local), in evaluation order.
git config --list
git config --list --show-origin
git config --global alias.<name> <cmd>Create a custom git alias. Common ones: co=checkout, br=branch, st=status, lg="log --oneline --graph".
git config --global alias.co checkout
git config --global alias.lg "log --oneline --graph --all"
git config --global core.editor "code --wait"Set the editor git opens for commit messages, interactive rebase, etc.
git config --global core.editor "code --wait"
git config --global core.editor "vim"
git config --global init.defaultBranch mainMake `git init` create `main` as the default branch instead of `master`.
git config --global init.defaultBranch main
git config --global pull.rebase trueMake `git pull` always rebase by default (no more accidental merge commits).
git config --global pull.rebase true
git config --global core.autocrlf inputConvert CRLF to LF on commit but not on checkout. Recommended on macOS/Linux working with cross-platform repos.
⚠ Common pitfall: On Windows the recommended value is `true` (CRLF on checkout, LF on commit). Mixing them creates phantom diffs.
git config --global core.autocrlf input
git config --unset <key>Remove a single git config entry.
git config --global --unset user.email
git config --unset alias.co
git logShow commit history for the current branch.
git log
git log -n 10
git log --author="Alice"
git log --oneline --graph --allCompact, one-line-per-commit graph of every branch — the most-used git log incantation.
git log --oneline --graph --all
git log --oneline --graph --all --decorate
git log -pShow commit history WITH the full diff of each commit.
git log -p
git log -p src/index.ts
git log --statShow commit history with file-change statistics (which files, how many lines).
git log --stat
git log --stat -n 5
git diffShow unstaged changes (working tree vs index).
git diff
git diff src/index.ts
git diff --stagedShow staged changes (index vs last commit) — what `git commit` would record.
git diff --staged
git diff --cached
git diff <branch1>..<branch2>Show the diff between the tips of two branches.
git diff main..feature/login
git diff origin/main..HEAD
git diff <branch1>...<branch2>Show changes on <branch2> since it diverged from <branch1> (uses merge base). Common for PR previews.
⚠ Common pitfall: Two dots vs three dots produce different diffs — three-dot is what PRs actually show.
git diff main...feature/login
git blame <file>Show, for every line of a file, the commit and author that last changed it.
⚠ Common pitfall: Whitespace-only / formatting commits hide real authors. Use `git blame -w --ignore-rev <fmt-sha>` to skip them.
git blame src/index.ts
git blame -L 10,30 src/index.ts
git blame -w src/index.ts
git show <sha>Show metadata and diff of a single commit.
git show a1b2c3d
git show HEAD
git show HEAD:src/index.ts
git shortlog -snSummarize commits per author with counts (sorted, numbered). Great for changelogs / credits.
git shortlog -sn
git shortlog -sn --since="1 month ago"
git bisectBinary-search through commits to find the one that introduced a bug.
git bisect start
git bisect bad
git bisect good v1.0
git bisect reset
git log -S "<text>"Find every commit that ADDED or REMOVED the given text — invaluable for "when did this string appear?".
git log -S "TODO" --source --all
git log -S "DEBUG_FLAG"
git grep <pattern>Search tracked files for a regex pattern (faster and ignore-aware vs plain grep).
git grep "TODO"
git grep -n "TODO" -- "*.ts"
git diff --name-onlyList ONLY the file names that changed, no diff body. Useful for piping to other commands.
git diff --name-only
git diff --name-only origin/main...HEAD | xargs eslint
git log --since/--untilFilter commits by date range. Accepts natural language like "2 weeks ago" or ISO dates.
git log --since="2 weeks ago"
git log --since=2026-01-01 --until=2026-02-01
git submodule add <url> <path>Add another git repo as a submodule at the given path.
⚠ Common pitfall: Submodules pin a specific commit, not a branch. New clones need `git submodule update --init --recursive` or the dir will be empty.
git submodule add https://github.com/user/lib.git vendor/lib
git submodule initRegister submodules listed in .gitmodules into local .git/config.
git submodule init
git submodule update --init --recursiveInitialize, fetch and check out all submodules (and submodules-of-submodules) to their pinned commits.
git submodule update --init --recursive
git clone --recurse-submodules <url>
git submodule update --remoteMove each submodule to the latest commit of its tracked remote branch (then commit in the parent).
git submodule update --remote
git submodule update --remote vendor/lib
git submodule foreach <cmd>Run a shell command inside every submodule. Useful for batch git operations.
git submodule foreach git pull
git submodule foreach "git checkout main && git pull"
git submodule deinit <path>Remove a submodule cleanly: unregister it, then `git rm <path>` and commit.
⚠ Common pitfall: Just deleting the directory leaves stale .gitmodules / .git/config entries. Always deinit + rm.
git submodule deinit vendor/lib
git rm vendor/lib && rm -rf .git/modules/vendor/lib
git checkout -- <file> (LEGACY — destructive)Discard ALL unstaged changes in <file>. Same as `git restore <file>`. Cannot be undone — there is no reflog for working-tree state.
⚠ Common pitfall: No prompt, no confirmation, no backup. Use `git stash` first if unsure.
git checkout -- broken.ts
git restore broken.ts
detached HEAD recoveryYou checked out a commit/tag directly (e.g. `git checkout v1.0`). Any commits you make here will be lost unless you create a branch.
⚠ Common pitfall: If you accidentally left detached HEAD with new commits, find them in `git reflog` and `git branch save-me <sha>` immediately.
git switch -c new-branch
git reflog
git branch save-me HEAD@{0}merge conflict resolutionWhen git stops mid-merge with conflicts: edit the <<<<<<< / ======= / >>>>>>> markers in each file, `git add` each resolved file, then `git commit` (or `git merge --continue`).
⚠ Common pitfall: Forgetting to `git add` the resolved file leaves the merge incomplete — commit will fail with "you have unmerged paths".
git status
git add resolved.ts
git commit
git merge --abort
recover lost commits with reflogAfter a botched reset/rebase/branch-delete, `git reflog` lists every HEAD movement. Find the SHA you want and `git reset --hard <sha>` or `git branch rescue <sha>`.
⚠ Common pitfall: Reflog entries expire (default 90 days for reachable, 30 days for unreachable). Recover sooner rather than later.
git reflog
git branch rescue HEAD@{3}git reset --hard HEAD@{5}undo `git push --force`If you force-pushed and overwrote teammates work: ask them to share their reflog (their local copy still has the old commits) and force-push that SHA back.
⚠ Common pitfall: GitHub keeps "lost" commits on its dangling-objects GC for ~14 days — you can sometimes recover via the API. ALWAYS use --force-with-lease.
# on a teammate's machine still holding the old SHAs:
git push --force-with-lease origin <sha>:main
remove a file from git historyA secret got committed. `git rm` only removes it going forward. To purge ALL history, use `git filter-repo` (modern, preferred) or BFG Repo Cleaner.
⚠ Common pitfall: After purge, rotate the secret anyway — anyone who cloned still has it. Then force-push the cleaned history.
git filter-repo --invert-paths --path secrets/key.pem
git push --force-with-lease origin --all
"fatal: refusing to merge unrelated histories"You tried to merge/pull two repos that have no common ancestor (e.g. cloned and re-inited). Add `--allow-unrelated-histories` if you really want to merge them.
git pull origin main --allow-unrelated-histories
Searchable git command cheat sheet covering 100+ commands you actually type at the terminal. Every entry has the full syntax, a plain-English and Chinese explanation, the common pitfall people hit with it, and one or two real examples you can copy. Nine categories: basic (init, clone, status, add, commit, push, pull, fetch, tag, mv, rm), branch (branch, checkout, switch, merge, rebase, cherry-pick), undo & recovery (reset --soft / --mixed / --hard, revert, restore, stash, reflog, clean), remote (remote, fetch --prune, push -u, push --tags), collab (rebase -i, --autosquash, merge --squash, --force-with-lease, worktree), config & aliases, inspect & history (log, diff, blame, show, bisect, grep, log -S), submodules (add, init, update --remote, foreach, deinit), and common mistakes (detached HEAD recovery, merge conflict workflow, lost-commit recovery via reflog, undoing --force-push, purging secrets with filter-repo). Type any word and it filters live across commands, descriptions, pitfalls and examples; tap a category chip to scope. Bilingual EN/ZH, fully client-side, no tracking, no ads. Pair with our Regex Cheatsheet for the other "I always forget this syntax" reference, or Crontab Helper for the third thing every developer Googles weekly.
Paste or drop your content into the tool panel.
Click the button. All processing is local in your browser.
Copy the result or download to disk in one click.
Use it in the small gaps between coding, reviewing, debugging, and shipping.
These links move the current task into a more complete workflow.
Folks in your role tend to reach for these alongside this tool.