如何通过脚本将Git已追踪文件存入单个stash?
Git Stash 处理混合追踪/未追踪文件的解决方案
问题场景
平时常用这类命令批量操作文件:
git add/checkout/stash -- (find -name "*.extension")
其中add和checkout能正常运行,但checkout或stash遇到未追踪文件时,会报错:
'<file>' did not match any file(s) known to git
checkout可以用循环规避:
for file in (find -name "*.extension") git checkout -- $file end
但用同样循环执行stash时,会为每个文件创建独立的stash记录,不符合需求。希望执行git stash tracked-file untracked-file时,效果等同于只stash追踪文件,忽略未追踪文件。
解决方法
方法1:用git ls-files过滤已追踪文件
直接通过git ls-files筛选出Git已追踪的文件,再传给git stash,一次性完成操作:
git stash -- $(find -name "*.extension" | git ls-files --stdin)
原理:git ls-files --stdin会从标准输入读取文件名,仅输出Git已追踪的文件,自动过滤未追踪文件,避免报错,且只会生成一个stash记录。
方法2:通过git status精准筛选修改的追踪文件
如果需要仅针对已修改的追踪文件操作,可以结合git status和文本处理工具过滤:
git stash -- $(git status --porcelain | grep "^ M" | awk '{print $2}' | grep "\.extension$")
原理:
git status --porcelain输出简洁的文件状态,^ M代表已修改的追踪文件awk '{print $2}'提取文件名grep "\.extension$"筛选目标后缀的文件,最后传给git stash
补充说明
- 循环执行
git stash会生成多个stash的原因:每次单独传入一个文件时,Git会创建新的stash记录;一次性传入所有目标文件则只会生成一条记录。 - 如果需要同时暂存未追踪文件,可使用
git stash push -u -- <文件>,但这会把未追踪文件也存入stash,不符合忽略未追踪文件的需求,因此优先选择上述过滤方案。
内容的提问来源于stack exchange,提问作者porky11
相关产品推荐
相关产品推荐

