我如何以编程方式(在 shell 脚本中)确定是否有更改?

How can I programmatically (in a shell script) determine whether or not there are changes?

我正在尝试创建一个 Bash 脚本,它知道当前工作目录中是否有更改。我知道

$ git status

returns 类似 "nothing to commit" 的消息。我正在尝试的是将变量定义为 true 或 false。这个布尔值会告诉我是否有变化。

显然我不是 bash 脚本专家。我试过这样的东西,

there_are_changes=$(git status | grep nothin)
echo $there_are_changes

但它没有按预期工作。我该怎么办?

git-diff man page 描述了两个相关的选项:

--quiet
Disable all output of the program. Implies --exit-code.

--exit-code
Make the program exit with codes similar to diff(1). That is, it
exits with 1 if there were differences and 0 means no differences.

因此,稳健的方法是 运行

git diff --quiet; nochanges=$?

如果没有变化,shell变量nochanges将等于0(即真),否则1(即假)。

然后您可以在条件语句中使用 nochanges 的值,如下所示:

if [ $nochanges -eq 0 ]; then
    # there are no changes
else
    # there are changes
fi

或者,如果您不需要将退出状态存储在变量中,您可以这样做:

if git diff --quiet; then
    # there are no changes
else
    # there are changes
fi

由于 git diff 是瓷器 Git 命令并且您想以编程方式执行操作,您可能应该改用名为 git diff-index 的管道 Git 命令(这也是有一个 --quiet 标志,但必须提供一个树状参数):

if git diff-index --quiet HEAD; then
    # there are no changes
else
    # there are changes
fi

正如下面 中所指出的,上述方法不包括未跟踪的文件。要同时覆盖它们,您可以改用以下内容:

if [ -z "$(git status --porcelain)" ]; then
    # there are no changes
else
    # there are changes
fi

您可以使用 -n 表达式检查变量是否已设置。

#!/bin/bash
CHANGESTOCOMMIT=$(git status | grep 'Changes to be com')
UNSTAGEDCHANGES=$(git status | grep 'Changes not staged')

# If there are staged changes:
if [ -n "$CHANGESTOCOMMIT" ]; then
    echo "Changes need to be committed"
fi
if [ -n "$UNSTAGEDCHANGES" ]; then
    echo "Changes made but not staged."
fi

Git 跟踪为提交而暂存的已更改文件以及未暂存的文件,因此您的脚本可能想要检查这两个选项(或不检查)。 -n 运算符检查变量是否已设置 - 如果它为空,它将 return false。

另一种选择是 -z,如果它为空,则 return 为真(与 [=11= 逻辑相反)。有关条件表达式的完整列表,请参阅 the Bash Reference Manual.