如何以编程方式确定是否存在未提交的更改?

在Makefile中,如果有未提交的更改(在工作树或索引中),我想执行某些操作。 什么是最干净和最有效的方式来做到这一点? 一个返回值为零,另一个返回值为非零的命令将适合我的目的。

我可以运行git status并通过greppipe道输出,但我觉得必须有更好的方法。

更新 :OP Daniel Daniel Stutzbach 在评论中指出,这个简单的命令git diff-index为他工作:

 git diff-index --quiet HEAD -- 

如果您在bash脚本中使用它,则可以看到“ 如何检查命令是否成功? ”:

 git diff-index --quiet HEAD -- || echo "untracked"; // do something about it 

注:正如Anthony Sottile 评论的那样

git diff-index HEAD ...会在没有提交的分支上失败(比如新初始化的仓库)。
我find的一个解决方法是git diff-index $(git write-tree) ...


“编程”意味着永远不要依赖瓷器的命令
始终依靠pipe道命令

另请参阅“ 使用Git检查脏索引或未跟踪的文件 ”以获取替代方法(如git status --porcelain

您可以从我们所说的新的“ require_clean_work_tree函数 ”中获得灵感;)(2010年10月初)

 require_clean_work_tree () { # Update the index git update-index -q --ignore-submodules --refresh err=0 # Disallow unstaged changes in the working tree if ! git diff-files --quiet --ignore-submodules -- then echo >&2 "cannot $1: you have unstaged changes." git diff-files --name-status -r --ignore-submodules -- >&2 err=1 fi # Disallow uncommitted changes in the index if ! git diff-index --cached --quiet HEAD --ignore-submodules -- then echo >&2 "cannot $1: your index contains uncommitted changes." git diff-index --cached --name-status -r --ignore-submodules HEAD -- >&2 err=1 fi if [ $err = 1 ] then echo >&2 "Please commit or stash them." exit 1 fi } 

虽然其他的解决scheme是非常彻底的,如果你想要一些真正的快速和肮脏,尝试这样的事情:

 [[ -z $(git status -s) ]] 

它只是检查状态摘要中是否有输出。

git diff --exit-code将返回非零值,如果有任何更改; git diff --quiet与没有输出相同。 既然你想检查工作树和索引,使用

 git diff --quiet && git diff --cached --quiet 

要么

 git diff --quiet HEAD 

任何一方都会告诉您是否存在未提交的变更。

正如其他答案指出的那样,这样的指令就足够简单:

 git diff-index --quiet HEAD -- 

如果您省略了最后两个破折号,那么如果您有一个名为HEAD的文件,则该命令将失败。

例:

 #!/bin/bash set -e echo -n "Checking if there are uncommited changes... " trap 'echo -e "\033[0;31mFAILED\033[0m"' ERR git diff-index --quiet HEAD -- trap - ERR echo -e "\033[0;32mAll set!\033[0m" # continue as planned... 

谨慎的话:这个命令忽略未跟踪的文件。

扩展@ Nepthar的答案:

 if [[ -z $(git status -s) ]] then echo "tree is clean" else echo "tree is dirty, please commit changes before running this" exit fi 

使用Python和GitPython:

 git.Repo(path).is_dirty(untracked_files=True) 

如果存储库不干净,则返回True

这是最好的,最干净的方法。

 function git_dirty { text=$(git status) changed_text="Changes to be committed" untracked_files="Untracked files" dirty=false if [[ ${text} = *"$changed_text"* ]];then dirty=true fi if [[ ${text} = *"$untracked_files"* ]];then dirty=true fi echo $dirty }