如何以编程方式确定是否存在未提交的更改?
在Makefile中,如果有未提交的更改(在工作树或索引中),我想执行某些操作。 什么是最干净和最有效的方式来做到这一点? 一个返回值为零,另一个返回值为非零的命令将适合我的目的。
我可以运行git status
并通过grep
pipe道输出,但我觉得必须有更好的方法。
更新 :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 }