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

Git 如何以编程方式(在shell脚本中)确定是否有更改?,git,bash,Git,Bash,我正在尝试创建一个Bash脚本,它知道当前工作目录中是否有更改。我知道 $ git status 返回类似“无需提交”的消息。我试图定义一个变量为真或假。这个布尔值将告诉我是否有更改 显然,我不是bash脚本的专家。我试过这样的东西 there_are_changes=$(git status | grep nothin) echo $there_are_changes 但它并没有像预期的那样起作用。我该怎么办?这里介绍了两个相关选项: --quiet Disable all output

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

$ git status
返回类似“无需提交”的消息。我试图定义一个变量为真或假。这个布尔值将告诉我是否有更改

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

there_are_changes=$(git status | grep nothin)
echo $there_are_changes
但它并没有像预期的那样起作用。我该怎么办?

这里介绍了两个相关选项:

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

因此,一种稳健的方法是运行

git diff——安静;nochanges=$?
如果没有更改,外壳变量
nochanges
将等于
0
(即true),否则等于
1
(即false)

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

if[$nochanges-eq 0];然后
#没有变化
其他的
#有变化
fi
或者,如果不需要将退出状态存储在变量中,则可以执行以下操作:

如果git diff——安静;然后
#没有变化
其他的
#有变化
fi

Edit:由于
git diff
是一个陶瓷git命令,并且您希望以编程方式执行操作,因此您可能应该使用名为
git diff index
的管道git命令(它也有一个
--quiet
标志,但必须提供一个类似树的参数):

if git diff index——安静头;然后
#没有变化
其他的
#有变化
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
运算符检查变量是否已设置-如果为空,则返回false


另一种选择是
-z
,如果为空则返回True(与
-n
的逻辑相反。有关条件表达式的完整列表,请参阅。

是的,否决票对此没有意义。@Jubobs的答案更清晰了一点,但你从我这里得到了+1。我把
-z
-n
混在一起了,所以我的脚本有一个逻辑错误。现在已修复。命令替换不雅观;
git diff--quiet
已经提供了用户想要的功能。没错,您的解决方案对于这个用例来说更加优雅。问题是如何检查变量是否已设置(true或false)在bash中,但您的解决方案完全避开了grep的需要。我不知道
git diff
--quiet
标志,这很好!因为
git diff--quiet;nochanges=$?
将在设置为在非零退出代码后停止的脚本中停止执行,您可以改为使用
CHANGES=false;(git diff--quiet)| | CHANGES=true
我们如何只检查更改?例如,避免使用
else
?您有可用的python吗?如果有,像这样的脚本可能更容易用python编写。可能重复我尝试删除问题,…但我正在阅读非常有用的答案。我会保留它!!!
#!/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