如何在Makefile中用git status --porcelain判断Git仓库是否干净?
在Makefile中判断Git仓库是否干净的正确方法
你的问题核心出在Makefile对$符号的解析逻辑上:你代码里的$(git status --porcelain)会被Make当成变量引用(而非shell命令替换),由于不存在名为git的Make变量,这部分会被展开为空字符串,导致test -z ""永远返回0,所以.SHELLSTATUS始终不受仓库状态影响。
解决方法
需要在shell命令中将$转义为$$,让Make把$$传递给shell,shell会将其解析为命令替换的$。以下是两种可靠的实现方式:
方式1:直接赋值变量(推荐)
通过shell命令的返回结果直接设置DIRTY变量,代码更简洁:
# 判断仓库是否有未提交修改,有则DIRTY=YES,否则NO DIRTY := $(shell test -n "$$(git status --porcelain)" && echo YES || echo NO) # 或者用grep简化写法 # DIRTY := $(shell git status --porcelain | grep -q . && echo YES || echo NO) # 验证结果 $(info 当前仓库状态是否脏:$(DIRTY))
方式2:结合.SHELLSTATUS判断
如果你坚持使用.SHELLSTATUS的逻辑,修正后的代码如下:
$(shell test -n "$$(git status --porcelain)") ifneq ($(.SHELLSTATUS), 0) DIRTY = NO else DIRTY = YES endif $(info 当前仓库状态是否脏:$(DIRTY))
原理说明
$$(git status --porcelain):Make会将$$解析为单个$传递给shell,shell执行$(git status --porcelain)获取仓库状态输出。test -n "...":判断输出内容是否非空——若仓库有未提交修改,输出非空,test返回0(成功);若仓库干净,输出为空,test返回1(失败)。.SHELLSTATUS:存储的是上一次$(shell)执行的命令退出码,以此来分支设置DIRTY变量。
内容的提问来源于stack exchange,提问作者Klaus
相关产品推荐
相关产品推荐

