Git Commands Cheat Sheet
Common Git commands: clone, add, commit, branch, merge, rebase, stash and more, with notes for everyday version control.
How It Works
Git is a distributed version-control system: every clone holds the full history, so commits work without a central server. The working tree, the staging area (index) and the local repository are the three layers behind every command — changes are added to the index, then committed to the repo.
A commit is a snapshot (not a diff) linked to its parent, forming a DAG; a branch is just a lightweight pointer to a commit, so creating or switching branches is cheap. Merge keeps a forked history, while rebase replays commits onto the target branch for a linear history — different semantics.
When to Use This Table
This table is for looking up how a particular Git subcommand is written, especially ones you do not run daily and whose flags you forget (rebase, cherry-pick, reflog, bisect and the like). Its value is coverage: commit, branch, remote, undo and diagnosis are grouped so a command is quick to find.
When not to consult it: you are learning how Git works or designing a branching strategy. Why rebase rewrites history and when cherry-pick beats merge are not answered by a command table; it only tells you how to type, not why it is designed that way.
Rule of thumb: ask whether a command changes repository state or only reads it. Read-only commands (log, status, diff, show, blame) are safe to run; state-changing ones (reset, rebase, clean, filter-branch) should not be typed until you fully understand the consequences, especially with --hard or -f.
Mind version differences: git checkout both switches branches and restores files, while git restore arrived in 2.23 and git switch also in 2.23. Older environments have neither, so scripts need a capability check or a fallback.
Boundaries and Common Pitfalls
reset --hard discards uncommitted working-tree changes
This is among the most common accidents. git reset --hard HEAD~3 rewinds both the working tree and the index, and uncommitted changes vanish unrecoverably — Git does not back up anything that was never committed. Safer: git stash or save a patch with git diff first, or use git reset --soft, which moves HEAD only and leaves the changes staged.
rebase rewrites history — never rebase pushed commits
rebase works by replaying your changes onto a new base, discarding the original commits and producing new SHAs. That is dangerous for commits already pushed to a shared branch: your history diverges from everyone else, and merging later produces conflicts and duplicated commits that are painful to untangle. Rule: rebase only your own unpushed branch, and replace bare --force with --force-with-lease, which refuses to push when the remote has moved on.
git config has three scopes with very different reach
The same setting can exist at system scope (--system, usually /etc/gitconfig), global scope (--global, ~/.gitconfig) and repository scope (--local, .git/config), each overriding the previous. To debug why a setting does not take effect, inspect all levels at once: git config --list --show-origin prints every value together with the file it came from. CI containers usually have only system and local scope, no global — which is exactly how core.autocrlf ends up true in CI while it was false on your laptop.
reflog is the only reliable way to recover lost commits
After a mistaken reset, a mistaken rebase or a branch switch that made a commit vanish, reflog holds the trajectory of HEAD movement (usually kept for 90 days) including the original SHAs. Inspect with git reflog, then restore using git reset --hard <sha> or git cherry-pick <sha>. Two limits: reflog is local, so it cannot recover changes that were never committed, and cloning someone else repository does not bring your reflog along.
How This Relates to Neighbours
For the full flag surface and official semantics of a subcommand, prefer git <cmd> --help and the git documentation; this table is a quick set of common commands.
To visualise branch state or understand the history difference between merge and rebase, use the in-site Git diagram tools; this table only provides command text.
CI-specific Git behaviour (credentials, line endings, shallow clones) is a CI configuration concern, out of scope here.
If the goal is cleaning history before pushing, that requires designing a rebase strategy and assessing risk, not looking up a command.
Practical Snippet
Key points: (1) before any history rewrite, save a patch with git diff and tag a backup branch — reflog can only recover what was committed; (2) prefer reset --soft; --hard destroys uncommitted work irrecoverably; (3) rebase only your own unpushed branch, and use --force-with-lease instead of --force when the branch was pushed; (4) to debug configuration, run git config --list --show-origin to see every value together with the file it came from.
# ① 动手前先看清现状(只读,安全)
git status --short # 工作区有哪些改动
git log --oneline -10 # 最近提交
git diff --stat # 改动规模
git config --list --show-origin # 配置来自哪个文件(排设置问题用)
# ② 改写/回退前先存档(这三步能救回绝大多数误操作)
git diff > /tmp/backup.patch # 未暂存的改动
git diff --cached > /tmp/idx.patch # 已暂存的改动
git branch backup-before-reset # 给当前 HEAD 打个标签分支
# ③ 优先用 --soft,别默认 --hard
git reset --soft HEAD~3 # 只动 HEAD,改动留在暂存区(安全)
# git reset --hard HEAD~3 # 工作区+暂存区一起丢 —— 除非确定,否则别用
# ④ 误操作后从 reflog 找回
git reflog # 找到目标 SHA
git reset --hard <sha> # 或 git cherry-pick <sha>
# ⑤ rebase 只对自己的未推送分支;强推用 --force-with-lease
git rebase -i origin/main # 先 fetch,确认没落后
git push --force-with-leasePractical Notes
- reset --hard discards uncommitted work with no recovery pathIt forces the index and working tree to the target commit, and uncommitted content never reaches the reflog. To undo a commit while keeping changes, use --soft (keep them staged) or --mixed (the default, keep them in the working tree).
- rebase rewrites commit hashes; avoid it on pushed branchesAfter rebasing a shared branch and force-pushing, everyone else local history diverges from the remote. The usual team rule: only rebase commits you have not pushed yet.
- git checkout on a single file overwrites your working-tree editsThat file-level revert is not recorded in the reflog, so a mistake is unrecoverable. It is particularly dangerous when changes were layered across several rounds, because it also wipes earlier edits you meant to keep. Inspect git diff and restore selectively instead.
Data Sources
- Git reference manual (git-scm.com/docs)
- Pro Git, 2nd edition
Codes, names and definitions above come from public specifications; we claim no originality over the specification data itself. The arrangement, Chinese annotations and practical notes on this page are written by us.
| Command | Description |
|---|---|
| git init | Initialize a new repository |
| git clone | Clone a remote repo locally |
| git config | Set user.name/email etc. |
| git status | Show working tree status |
| git add | Stage changes (-A all) |
| git commit | Commit staged changes (-m message) |
| git push | Push commits to remote |
| git pull | Fetch and merge remote changes |
| git fetch | Fetch remote updates only (no merge) |
| git branch | List/create branches |
| git checkout | Switch branch or restore file |
| git switch | Switch branch (more semantic) |
| git merge | Merge a branch into current |
| git rebase | Reapply commits onto another branch |
| git stash | Stash unfinished changes |
| git log | Show commit history (--oneline) |
| git diff | Show change diff |
| git reset | Reset to a commit (--soft/--hard) |
| git revert | Undo a commit with a new commit |
| git cherry-pick | Apply a commit to current branch |
| git tag | Create a tag (version mark) |
| git remote | Manage remotes (-v list) |
| git clean | Remove untracked files (-fd force) |
| git rm | Stop tracking and delete file |
| git show | Show a commit/object detail |
Frequently Asked Questions
What is the difference between merge and rebase?
merge creates a merge commit and keeps the full branchy history; rebase replays your commits onto the target branch for a linear history, but rewrites their hashes, so never rebase a shared branch that others have pulled.
How do I undo the last commit?
To keep the changes use git reset --soft HEAD~1; to discard them use git reset --hard HEAD~1; safer is git revert HEAD which adds a new undo commit.
How do I temporarily save unfinished work?
Use git stash to shelve changes and git stash pop to restore. You can stash multiple times and list them with git stash list.
How do I unstage a file but keep the changes?
Use git reset HEAD <file> to unstage (changes stay in the working tree); to also discard them use git checkout -- <file> (or git restore <file>).