# Git 命令行速查

Source: https://codewiki.com/zh/cheatsheets/git-shell/

## 检查仓库状态

- `git status --short --branch` — 显示分支、与上游的差异，以及工作树和索引的精简状态
- `git diff -- path/to/file` — 比较单个路径的未暂存内容与索引
- `git diff --cached -- path/to/file` — 比较单个路径的暂存内容与 `HEAD`
- `git diff HEAD -- path/to/file` — 比较工作树内容与 `HEAD`，同时包含已暂存和未暂存的变更
- `git log --oneline --decorate --graph --all` — 绘制从所有本地引用可达的提交图
- `git show --stat --oneline COMMIT` — 检查单个提交的头信息和文件级变更摘要

## 暂存与提交

- `git add -- path/to/file` — 把路径的当前内容复制到索引
- `git add -p -- path/to/file` — 交互选择要写入索引的补丁块
- `git restore --staged -- path/to/file` — 用 `HEAD` 重置索引中的路径，同时保留工作树修改
- `git diff --cached --check` — 报告待提交变更中的空白错误
- `git commit -m 'Explain the change'` — 用非空消息提交已暂存的快照
- `git commit --amend --no-edit` — 用当前索引替换最新提交，同时保留原提交消息

## 分支与标签

- `git switch -c feature/name main` — 从 `main` 创建 `feature/name` 并切换到该分支
- `git switch main` — 把工作树和索引切换到本地 `main` 分支
- `git branch --show-current` — 输出当前分支名；`HEAD` 分离时不输出内容
- `git branch -m feature/new-name` — 重命名当前分支，不改变其提交
- `git branch -d feature/name` — 仅在 Git 判定分支已完全合并时将其删除
- `git tag -a v1.2.3 -m 'Release v1.2.3'` — 在 `HEAD` 创建附注标签
- `git show --no-patch v1.2.3` — 检查标签及其目标，不输出补丁

## 比较版本

- `git rev-parse --verify main^{commit}` — 解析 `main`，并要求结果指向提交
- `git merge-base main feature/name` — 输出两个提交端点的一个最佳共同祖先
- `git log main..feature/name --oneline` — 列出可从功能分支到达、但不能从 `main` 到达的提交
- `git log --left-right --oneline main...feature/name` — 显示两侧各自独有的提交，并标明每个提交所属的一侧
- `git diff main...feature/name` — 比较功能分支端点与它相对 `main` 的合并基点
- `git diff COMMIT^ COMMIT --` — 显示非根提交相对其第一父提交的变更

## 获取并检查远程

- `git remote -v` — 显示每个远程仓库配置的获取与推送 URL
- `git config --get-all remote.origin.fetch` — 检查从 `origin` 获取时使用的引用规格
- `git fetch --prune origin` — 从 `origin` 下载数据，并删除失效的远程跟踪引用
- `git branch --remotes --verbose` — 列出本地远程跟踪引用及其端点主题
- `git log HEAD..origin/main --oneline` — 列出 `origin/main` 中已有而 `HEAD` 中没有的已获取提交
- `git diff --stat HEAD...origin/main` — 汇总远程一侧从合并基点开始的变更

## 集成与发布

- `git merge --ff-only origin/main` — 仅在无需合并提交时推进当前分支
- `git merge --no-ff feature/name` — 合并功能分支；即使可以快进，也创建合并提交
- `git pull --ff-only origin main` — 获取远程 `main`，且只接受快进更新
- `git push --dry-run origin HEAD` — 预览远程引用更新，但不改变该引用
- `git push -u origin feature/name` — 发布本地分支，并记录它的上游
- `git push --force-with-lease origin feature/name` — 仅在租约预期仍匹配时强制更新已改写的分支
- `git push --atomic origin main v1.2.3` — 要求分支和标签更新全部成功或全部失败

## 解决合并冲突

- `git ls-files --unmerged` — 显示每个冲突在索引中记录的基点、阶段 2 侧和阶段 3 侧
- `git show :2:path/to/file` — 读取当前操作的阶段 2 版本
- `git show :3:path/to/file` — 读取当前操作的阶段 3 版本
- `git add -u -- path/to/file` — 用已解决状态替换已跟踪路径在索引中的未合并条目
- `git diff --check` — 继续操作前查找遗留的冲突标记与空白错误
- `git merge --continue` — 解决并暂存全部冲突后完成合并
- `git merge --abort` — 需要放弃合并时恢复到合并前的状态

## 变基与拣选

- `git rebase main` — 把当前分支独有的提交重放到 `main` 上
- `git rebase -i HEAD~5` — 重排、合并、编辑或丢弃最近五个提交
- `git rebase --onto main OLD_BASE feature/name` — 把 `OLD_BASE..feature/name` 重放到 `main`，并检出改写后的功能分支
- `git rebase --continue` — 暂存冲突解决结果后继续已暂停的变基
- `git rebase --abort` — 把分支和工作树恢复到变基前的状态
- `git cherry-pick -x COMMIT` — 应用一个提交的变更，并记录其来源标识
- `git cherry-pick --abort` — 恢复到当前拣选序列开始前的状态

## 按存储层撤销

- `git restore -- path/to/file` — 把索引版本复制到工作树，丢弃未暂存的已跟踪修改
- `git restore --source=COMMIT -- path/to/file` — 用提交中的版本替换工作树路径，不改变索引
- `git restore --source=HEAD --staged --worktree -- path/to/file` — 用 `HEAD` 同时替换单个路径的索引版本和工作树版本
- `git reset --soft HEAD^` — 把 `HEAD` 移到第一父提交，不改变索引或工作树
- `git reset --mixed HEAD^` — 移动 `HEAD`，用其父提交重置索引，并保持工作树不变
- `git reset --hard HEAD^` — 移动 `HEAD`，并用其父提交重置索引和工作树中的已跟踪内容
- `git revert COMMIT` — 记录普通提交的反向变更；反转合并提交还需指定 `-m`

## 储藏与工作树

- `git stash push -u -m 'Context for later'` — 储藏已跟踪和未跟踪的变更，并附上可搜索的消息
- `git stash list` — 列出储藏条目，不应用它们
- `git stash show --patch stash@{0}` — 检查一个储藏条目中保存的完整补丁
- `git stash apply stash@{0}` — 应用储藏，同时保留该储藏条目
- `git stash branch rescue/stashed stash@{0}` — 在储藏基点创建分支并应用储藏；仅在成功时删除该条目
- `git worktree add -b hotfix/name ../repo-hotfix main` — 创建新分支，并在另一个工作树中检出它
- `git worktree list --porcelain` — 以稳定、便于脚本解析的格式列出工作树

## 定位回归与恢复

- `git bisect start BAD GOOD` — 在已知错误提交与已知正确提交之间开始二分查找
- `git bisect run ./test-regression.sh` — 按退出状态分类版本：0 为正确，125 为跳过，其他 1–127 值为错误
- `git bisect reset` — 结束二分查找，返回开始前检出的分支或提交
- `git reflog --all --date=iso` — 检查 `HEAD` 和其他引用带日期的本地移动记录
- `git show --stat --oneline HEAD@{1}` — 恢复前检查引用日志中的候选位置
- `git branch rescue/lost HEAD@{1}` — 创建新分支，使确认过的引用日志位置保持可达
- `git fsck --unreachable` — 报告当前不可达、可能包含丢失提交的对象

## 检查对象与引用

- `git cat-file -t OBJECT` — 输出对象类型
- `git cat-file -p OBJECT` — 根据对象类型，以易读形式输出其内容
- `git ls-tree -r --name-only COMMIT` — 递归列出提交快照中的全部路径
- `git show COMMIT:path/to/file` — 直接读取提交快照中的一个文件
- `git ls-files --stage` — 显示每个索引条目的模式、对象标识、阶段与路径
- `git for-each-ref --format='%(refname) %(objectname)' refs/heads/` — 列出本地分支引用及其完整目标标识
- `git update-ref refs/heads/main NEW OLD` — 仅当 `main` 仍指向 `OLD` 时，才以原子方式将其更新为 `NEW`
