Git diff默认不显示工作区与别名分支差异,因为其设计仅比较工作区与暂存区或两个提交,而“工作区别名”实为独立worktree目录,并非Git原生概念;需用git --git-dir --work-tree指定路径或diff -r直比文件系统。

git diff 为什么默认不显示工作区与别名分支的差异
因为 git diff 默认只比较工作区(WORKING TREE)和暂存区(INDEX),或通过 git diff A..B 比较两个提交。所谓“工作区别名”,Git 本身没有这个概念——它只是你用 git worktree add 创建的独立工作目录,每个绑定一个分支,但 Git 不会自动把它们当“别名”关联起来。
想秒级对比两个分支在各自工作区的差异,关键不是起个名字,而是绕过默认比较路径、直连两个工作树的文件系统状态。
用 git worktree + git --git-dir 指向目标工作树仓库
每个 git worktree 目录下都有自己的 .git 文件(不是目录),内容类似 gitdir: /path/to/.git/worktrees/xxx。要对比主工作区和另一个工作树的差异,得让 git diff 知道“另一方”的真实 Git 目录位置。
实操步骤:
- 先用
git worktree list查出目标工作树路径和对应分支,比如输出:/path/to/project-feature dev - 进入主工作区(比如
main分支所在目录),执行:git --git-dir=/path/to/project-feature/.git --work-tree=/path/to/project-feature diff HEAD
- 这行命令等价于:“在
project-feature工作树里,拿它的HEAD和它的工作区文件做 diff” - 再结合
git diff的双点语法,就能比出两个工作树当前状态的差异:git diff $(cd /path/to/project-feature && git rev-parse HEAD) HEAD
(注意:这只是提交差异,不含未暂存修改)
真正秒级对比必须包含未暂存修改,用 rsync 或 diff -r 更可靠
git diff 再怎么绕参数,也只读取 Git 索引和对象数据库,对另一工作树中未 git add 的脏文件无感知。实际开发中,你往往想看“这个功能分支改了啥,和我本地正在调的分支差多少”,这时候纯 Git 命令会漏掉大量临时改动。
更稳的做法是跳过 Git 层,直接比文件系统:
- 确保两个工作树都 clean(或明确接受 untracked 文件参与对比)
- 用
diff -r排除 Git 元数据:diff -r --exclude=.git /path/to/main-worktree/ /path/to/feature-worktree/
- 或用
rsync --itemize-changes获取单行摘要:rsync -avn --delete --exclude='.git' /path/to/main-worktree/ /path/to/feature-worktree/
(-n表示 dry-run,v显示详情) - 性能上,
rsync在大项目里明显快于diff -r,尤其只关心变更列表时
alias 要加 --no-pager 防卡死,且不能省略 --work-tree
有人想封装成 alias,比如:git config --global alias.diffwt '!f() { git --git-dir=$1/.git diff HEAD; }; f'——这会失败,因为没传 --work-tree,Git 仍以当前目录为根去解析路径,导致文件找不到或报错 fatal: not a git repository。
正确写法(zsh/bash 兼容):
git config --global alias.diffwt '!f() { git --git-dir="$1/.git" --work-tree="$1" diff HEAD; }; f'
使用:git diffwt /path/to/other-worktree
额外提醒:git diff 默认走 pager,如果对比结果长,而 alias 没加 --no-pager,可能卡住或输出乱码。建议在 alias 里显式加上:git --no-pager --git-dir=... diff ...
工作树之间没有共享索引,也没有隐式同步机制,所谓“秒级对比”本质是靠绕过 Git 抽象层、直击文件系统实现的——越接近底层,越容易漏掉 Git 特有语义(如 submodule 状态、sparse checkout 规则),这点容易被忽略。


















