Git 检查存储库是否有更改的最快方法?

Git 检查存储库是否有更改的最快方法?,git,bash,macos,terminal,zsh,Git,Bash,Macos,Terminal,Zsh,我想检查git存储库是否有更改 我一直在使用这个条件 if command git status --porcelain 2> /dev/null | grep -q .; then X else Y fi 但是太慢了 有没有更快的方法?我必须依靠git命令来完成这项工作,还是有一种超快速的方法可以完全绕过使用该命令?我发现--short选项对这类事情很有用。如果没有任何更改,则返回空字符串: test -n "$(git status --short)" &&

我想检查git存储库是否有更改

我一直在使用这个条件

if command git status --porcelain 2> /dev/null | grep -q .; then
  X
else
  Y
fi
但是太慢了

有没有更快的方法?我必须依靠git命令来完成这项工作,还是有一种超快速的方法可以完全绕过使用该命令?

我发现
--short
选项对这类事情很有用。如果没有任何更改,则返回空字符串:

test -n "$(git status --short)" && echo 'changes detected' || echo 'no change'
我不知道是否有任何速度提升。

(编辑:剥离GNUism,有一个合理的posix测试)

它列出了在HEAD和index中具有不同内容的路径,以及在index和worktree中具有不同内容的路径,而无需花费任何时间来找出这些差异


如果出于某种原因,你想减少每最后一毫秒的响应时间,你可以使用
stdbuf-oL git
使git line buffer成为它的输出,因此第一个diff将立即命中sed并关闭管道;否则,它可能会在打印之前缓冲几十个检测到的差异。

Git自己的源代码可以为您提供一个好的解决方案:shell函数基本上满足您的需要。以下是一个较短的版本(不考虑阶段性更改):


如果您想知道git status--chi瓷2>/dev/null是否会输出一些东西:
If命令git status--chi瓷2>/dev/null | read-n1;然后回应“回购有变化”;fi
。可能会比您当前的测试更快,因为我们正在摆脱子shell和外部命令。@gniourf_gniourf为什么要从
tail
切换到
read
tail
是一个外部命令,而
read
是一个内置命令。此外,对于
read-n1
,我们最多只能读取一个字符(而不是整个流)。使用
grep-q.
也可以实现同样的效果,但是
grep
是一个外部命令,因此它比
read
@gniourf\u gniourf要慢,我得到
read:bad option:-1
不要使用zsh
:)
。但是如果你真的想使用它,可以使用
grep-q.
而不是
read-n1
。。。但速度会慢一些。答案的格式会更清晰。您的测试台是否标记了此方法?对于stdbuf,只需使用
stdbuf-oL git
代替
git
。对于总是错误的部分,我只是尝试了一下,做了一些更改,它显示为错误,重置——很难,它显示为正确。也许是打字错误?
if (git diff-index --cached @; git diff-files) | grep -q .; then
        tracked changes in index or worktree
else
        index and tracked worktree content identical to checkout
fi
git_has_changes() {
    git update-index -q --ignore-submodules --refresh
    git diff-files --quiet --ignore-submodules
}

if git_has_changes; then
    echo "has changes"
else
    echo "no change"
fi