$ git status
返回一个类似于“没有可提交的内容”的消息。我想要做的是定义一个变量为真或假。这个布尔值将告诉我是否存在变更。
很明显,我不是bash脚本专家。我尝试了以下代码:
there_are_changes=$(git status | grep nothin)
echo $there_are_changes
但是它没有按预期工作。我该怎么办?
$ git status
返回一个类似于“没有可提交的内容”的消息。我想要做的是定义一个变量为真或假。这个布尔值将告诉我是否存在变更。
很明显,我不是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的另一个内部命令git diff-index
(它也有一个--quiet
标志,但必须提供一个"tree-ish"参数):
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
git diff
命令中的 --quiet
参数,这真是太棒了! - jmervinegit diff --quiet; nochanges=$?
会停止执行,因此您可以改用 CHANGES=false; (git diff --quiet) || CHANGES=true
。 - Alasdair McLeayelse
? - Richardgit status --porcelain
是否输出文本(例如通过if [[ -n "$(git status --porcelain)" ]]; then echo "things changed"; fi
)。 - jeremysprofilegit diff-index --quiet HEAD
时,即使我已经将所有文件都暂存了,我仍然会遇到未暂存的错误。取消暂存并重新暂存它们仍然会导致 git diff-index --quiet HEAD
错误。所以,Aaron 的解决方案是唯一有效的。 - SwiftiSwift-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
-n
操作符用于检查变量是否已设置 - 如果为空,则返回false。-z
,如果为空则返回True(与-n
的逻辑相反)。有关条件表达式的完整列表,请参见Bash参考手册。git diff --quiet
已经提供了用户所需的功能。 - jub0bsgit diff-index --quiet HEAD
仍然会出现未暂存错误。取消暂存并重新暂存它们仍然会给我带来 git diff-index --quiet HEAD
的错误。所以 Aaron 的解决方案是唯一有效的。 - SwiftiSwift#!/bin/sh
# Check for changes not staged for commit
git diff --cached | grep -v ^$ > /dev/null
# If there are changes, exit with an error code
if [ $? -ne 0 ]; then
echo "There are changes not staged for commit."
exit 1
fi
# Check for changes to already staged files
git diff --cached --name-only | while read file; do
if [ -f "$file" ]; then
# Check if there are unstaged changes to the file
if git diff --name-only "$file" | grep -v ^$ > /dev/null; then
echo "There are unstaged changes to the file '$file'."
exit 1
else
echo "Good to go! Commit now"
exit 0
fi
fi
done
说明:
提供的代码是一个预提交钩子,它检查未暂存的更改、已经暂存的文件的更改以及已经暂存的文件的未暂存更改。
该钩子首先使用 git diff --cached
命令检查未暂存的更改。如果有任何更改,钩子将打印一条消息并退出错误代码。
如果没有未暂存的更改,则钩子将使用 git diff --cached --name-only
命令检查已经暂存的文件的更改。如果有任何修改过的文件,钩子将打印一条消息并退出错误代码。
然后,钩子将检查已修改的文件中是否有任何未暂存的更改。如果有任何未暂存的更改,钩子将打印一条消息并退出错误代码。
如果没有对已经暂存的文件进行更改或者已经暂存的文件的未暂存更改,钩子将以成功代码退出。 通常情况下,该钩子将检查您的文件是否有未提交的更改。如果有任何更改,钩子将打印一条消息并退出错误代码。这将防止您提交未暂存的更改。
以下是如何使用此钩子的示例:
我实际上使用它来避免将未通过Flutter单元测试的代码推送到git中,就像这样:
#!/bin/sh
# Check for changes not staged for commit
git diff --cached | grep -v ^$ > /dev/null
# If there are changes, exit with an error code
if [ $? -ne 0 ]; then
echo "There are no changes or some changes are not staged for commit."
git status
exit 1
fi
# Check for changes to already staged files
git diff --cached --name-only | while read file; do
if [ -f "$file" ]; then
# Check if there are unstaged changes to the file
if git diff --name-only "$file" | grep -v ^$ > /dev/null; then
echo "There are unstaged changes to the file '$file'."
exit 1
else
flutter test
# If the unit tests fail, exit with a non-zero exit code.
if [[ $? -ne 0 ]]; then
echo "Unit tests failed. Aborting commit."
exit 1
fi
fi
fi
done