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-lease

Practical 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.

CommandDescription
git initInitialize a new repository
git cloneClone a remote repo locally
git configSet user.name/email etc.
git statusShow working tree status
git addStage changes (-A all)
git commitCommit staged changes (-m message)
git pushPush commits to remote
git pullFetch and merge remote changes
git fetchFetch remote updates only (no merge)
git branchList/create branches
git checkoutSwitch branch or restore file
git switchSwitch branch (more semantic)
git mergeMerge a branch into current
git rebaseReapply commits onto another branch
git stashStash unfinished changes
git logShow commit history (--oneline)
git diffShow change diff
git resetReset to a commit (--soft/--hard)
git revertUndo a commit with a new commit
git cherry-pickApply a commit to current branch
git tagCreate a tag (version mark)
git remoteManage remotes (-v list)
git cleanRemove untracked files (-fd force)
git rmStop tracking and delete file
git showShow 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>).