git diff 不加参数时比较工作区与暂存区的差异,仅显示已修改但未暂存的文件内容变化,不涉及任何分支或提交历史。

git diff 不加参数时比的是什么
不加任何参数的 git diff,只比较工作区(你改过的文件)和暂存区(git add 过的变更)之间的差异。它**不会涉及任何分支或提交**,哪怕你刚切到 main 分支,它也完全不管 main 的历史。
常见误判是:改完文件后执行 git diff 没输出,就以为“没改”,其实可能是你已经 git add 了——这时得用 git diff --staged 看暂存区和 HEAD 的区别。
- 想看「还没
add的修改」→ 用git diff - 想看「已
add但还没commit的修改」→ 用git diff --staged - 想看「上次提交之后所有未 commit 的改动(含已 add 和未 add)」→ 用
git status -s配合git diff和git diff --staged
比较两个本地分支用 git diff branchA branchB
命令 git diff branchA branchB 是单向的:它把 branchA 当作旧版本、branchB 当作新版本,输出“从 A 到 B 需要怎么改”。如果 A 实际比 B 更新,diff 结果会是反向 patch(删 A 的内容、加 B 的内容),容易看晕。
更安全的做法是用三点语法:git diff branchA...branchB(注意是三个点)。Git 会自动算出两分支最近共同祖先(merge base),再以该基线为起点做 diff,结果更符合直觉。
- 两个点
..:强制单向,适合明确知道谁是基准(如git diff main..feature表示“main 上没有、feature 上有的变更”) - 三个点
...:自动找基线,适合快速摸清两边各自有什么(等价于git diff $(git merge-base branchA branchB)..branchB) - 别写成
git diff branchA branchB --,末尾--只在路径有歧义时才需要(比如文件名和分支名冲突)
git diff --name-only 和 --stat 要配合用
git diff 默认输出完整行级差异,文件一多根本没法扫。日常排查优先用轻量指令定位范围:
当用户提及 GitHub URL,或要求分析、审查、探索或理解任意 GitHub 项目、仓库或代码库时,请使用此技能。触发条件包括以下短语:“分析这个项目”、“看看这个仓库”、“analyze this repo”、“what does this project do”,或消息中包含任何 github.com URL。
-
git diff --name-only branchA branchB:只列文件路径,不显示改了啥。适合快速确认“是不是动了 config 目录” -
git diff --stat branchA branchB:显示每个文件增删行数,一眼看出哪个文件改得最多(比如src/api.js | 42 +++++++---) - 两者组合用更高效:先
--name-only锁定目标文件,再对单个文件跑git diff branchA branchB -- src/api.js
注意:--stat 不会列出重命名或删除的文件,除非加 --name-status;而 --name-only 默认也不显示状态标记(M/A/D),需额外加 --name-status 才能区分修改、新增、删除。
为什么 git diff origin/main main 有时没输出
这不是命令错了,而是 origin/main 这个远程追踪引用在本地可能根本没更新。Git 不会自动同步远程分支指针,origin/main 可能还停留在上周 fetch 的状态。
验证方式很简单:
- 运行
git fetch origin main(只拉main,快且干净) - 再用
git ls-remote origin main查远端最新 commit hash - 用
git show-ref origin/main查本地缓存的 hash - 两个 hash 不一致?说明远端被 force-push 或重写了,本地
origin/main已过期
真正省心的做法是用 @{u}(upstream)简写:git diff @{u} 自动对比当前分支和它的上游分支(比如 main 对应 origin/main),Git 会帮你兜底检查是否需要 fetch —— 但前提是上游已正确设置(git branch --set-upstream-to=origin/main main)。
最常被忽略的一点:远程分支名不是“活”的,它只是本地一个缓存指针。你不主动 fetch,它就不会动,也不会报错提醒你它已失效。

















