如何无需解析git status输出,列出相对于当前目录的Git暂存文件?
如何无需解析git status输出,列出相对于当前目录的Git暂存文件?
这个需求我太懂了!之前为了在子目录里方便看暂存文件的相对路径,踩了好几个Git参数的坑,现在终于有一套顺手的方案了,给你拆解一下:
核心解决方案:用git diff --cached配合--relative
你要的「暂存文件(增/删/改)+ 相对当前目录路径」的效果,其实用git diff --cached就能实现,关键是要正确使用--relative参数:
# 列出所有暂存的文件(增、删、改),路径相对当前目录 git diff --cached --name-only --relative
比如你在a/b/c/d目录下运行这个命令,输出会是:
deleted-staged-cur.txt modified-staged-cur.txt ../e/deleted-staged-other.txt ../e/modified-staged-other.txt
完全符合你想要的「和git ls-files --modified一致的相对路径格式」!
分场景的具体命令
如果你需要单独列出某一类暂存文件(比如只看删除、只看新增),可以加上--diff-filter参数过滤类型:
1. 只看暂存的删除文件
git diff --cached --name-only --relative --diff-filter=D
2. 只看暂存的修改文件
git diff --cached --name-only --relative --diff-filter=M
3. 只看暂存的新增文件(刚git add的未跟踪文件)
git diff --cached --name-only --relative --diff-filter=A
4. 限制查看特定目录的暂存文件
和git ls-files一样,你可以在命令末尾加目录参数,只看该目录下的暂存文件,路径依然相对当前目录:
# 只看当前目录 + 上级e目录的暂存文件 git diff --cached --name-only --relative . ../e
配置别名/Shell函数,一键调用
为了日常使用方便,你可以把这些命令配置成Git别名或者Shell函数:
方法1:Git别名(在~/.gitconfig中添加)
[alias] # 列出所有暂存文件 staged = !git diff --cached --name-only --relative # 只看暂存的删除文件 staged-del = !git diff --cached --name-only --relative --diff-filter=D # 只看暂存的修改文件 staged-mod = !git diff --cached --name-only --relative --diff-filter=M # 只看暂存的新增文件 staged-add = !git diff --cached --name-only --relative --diff-filter=A
之后直接运行git staged、git staged-del就能快速查看。
方法2:Shell函数(在~/.bashrc/~/.zshrc中添加)
如果需要支持更灵活的目录参数传递,比如git-staged ../e,可以写个Shell函数:
git-staged() { # 默认查看当前目录,可传自定义目录参数 local target_dirs="${@:-.}" git diff --cached --name-only --relative $target_dirs }
保存后重启终端,运行git-staged看当前目录暂存文件,git-staged ../e看上级e目录的暂存文件。
补充:为什么之前的--relative=..没用?
你之前踩的--relative=..的坑,是因为这个参数的逻辑不是「相对当前目录的上级」,而是「从仓库根目录开始匹配前缀并移除」。比如你在a/b/c/d目录,--relative=..会去仓库根目录找..这个路径(显然不存在),所以才会出现奇怪的结果。
正确的用法是:
- 不带参数的
--relative:自动以当前工作目录为基准输出相对路径 - 带目录参数的
--relative <path>:仅当<path>是仓库根目录下的绝对路径前缀时,才会移除该前缀(一般很少用到这个场景)
搭配你已有的命令,覆盖所有场景
现在你可以把这套方案和你之前用的git ls-files命令结合起来,实现全场景的文件列表:
- 暂存文件:
git staged(或上面的细分命令) - 未暂存修改/删除:
git ls-files --modified --deleted - 未跟踪文件:
git ls-files --others --exclude-standard
这样就完全不用解析git status的输出,所有路径都是相对当前目录的,用起来超顺手!




