git diff --name-only 最稳,只列修改文件路径不带内容差异;需指定基准如 HEAD(工作区vs最新提交)、--cached(暂存区)或 HEAD~1 HEAD(两提交间),避免默认对比导致遗漏。

git diff 怎么只列出修改过的文件名
想导出变更文件,第一步得准确识别哪些文件被改了。直接用 git diff --name-only 最稳,它不输出内容差异,只返回相对路径的文件名列表。
常见错误是漏掉参数范围,比如没指定对比基准,结果默认比工作区和暂存区——这会漏掉已 git add 但未 commit 的改动。实际常用组合:
-
git diff --name-only HEAD:对比当前工作区与最新提交(含未暂存修改) -
git diff --name-only HEAD~1 HEAD:对比上一次和本次提交(纯 commit 间差异) -
git diff --name-only --cached:只看已git add但未 commit 的文件
把 diff 文件批量导出成补丁或原始内容
仅列出文件名还不够,多数场景需要导出实际变更内容。关键分清两种需求:
- 要可移植的补丁(比如发给同事或 CI 处理),用
git diff > changes.patch,支持后续用git apply回滚 - 只要变更文件的「当前版本」内容(不含 diff 格式),不能直接用
git diff输出重定向——它带 +/- 行和头信息。正确做法是先取文件名,再用git show或cp配合git checkout
例如导出所有 HEAD 相比工作区修改的文件到 ./exported/ 目录:
mkdir -p ./exported
git diff --name-only HEAD | xargs -I {} cp "{}" "./exported/{}导出时避开 submodule、二进制或忽略文件
默认 git diff 会包含所有 tracked 文件,但实际导出常需过滤。容易踩的坑是依赖 .gitignore ——它只影响 untracked 文件,对已跟踪的无效。
- 排除 submodule:
git diff --name-only --no-submodules HEAD - 跳过二进制(避免 diff 报错或输出乱码):
git diff --quiet --no-ext-diff配合判断,或用git ls-files -t先筛出非 binary 类型 - 按后缀过滤,比如只导出
.py和.js:git diff --name-only HEAD -- '*.py' '*.js'
Windows 下路径空格和编码导致导出失败
在 PowerShell 或 CMD 中执行 xargs 类操作时,文件名含空格会直接中断。Git for Windows 自带的 Bash(Git Bash)更可靠;若必须用 PowerShell,得用 ForEach-Object 替代 xargs,并确保 $_.Trim() 清除换行符。
另一个隐形问题是中文路径在某些终端显示为乱码,导出后文件名损坏。解决方式是统一用 UTF-8 环境:chcp 65001(Windows 命令行),或 Git Bash 下默认支持,无需额外设置。
真正麻烦的是 diff 输出本身含中文字符时,部分工具(如老版本 patch)解析失败——这时宁可用 git archive 配合 git diff-tree 提取 blob,绕过文本 diff 解析环节。


















