rsync
我有一个以 Git 工作目录作为目标运行的脚本。我希望脚本具有不同的行为,具体取决于工作目录是否干净(没有要提交的更改)。例如,如果输出git status
如下,我希望脚本退出:
git status
Already up-to-date.
# On branch master
nothing to commit (working directory clean)
Everything up-to-date
如果目录不干净,那么我希望它执行更多命令。
如何在 shell 脚本中检查类似上面的输出?
答案1
解析 的输出git status
是一个坏主意,因为输出是人类可读的,而不是机器可读的。无法保证输出在 Git 的未来版本或不同配置的环境中保持相同。
UVV评论git status
是在正确的轨道上,但不幸的是,当有未提交的更改时,返回代码不会改变。然而,它确实提供了--porcelain
选项,这会导致 的输出git status --porcelain
被格式化为易于脚本解析的格式,和无论用户配置如何,跨 Git 版本都将保持稳定。
我们可以使用 的空输出git status --porcelain
作为没有要提交的更改的指示器:
if [ -z "$(git status --porcelain)" ]; then
# Working directory clean
else
# Uncommitted changes
fi
如果我们不关心工作目录中未跟踪的文件,我们可以使用--untracked-files=no
可以选择忽略这些:
if [ -z "$(git status --untracked-files=no --porcelain)" ]; then
# Working directory clean excluding untracked files
else
# Uncommitted changes in tracked files
fi
为了使其在以下条件下更加稳健实际上导致git status
失败而没有输出到stdout
,我们可以将检查细化为:
if output=$(git status --porcelain) && [ -z "$output" ]; then
# Working directory clean
else
# Uncommitted changes
fi
还值得注意的是,虽然git status
当工作目录不干净时不会给出有意义的退出代码,但git diff
提供了--exit-code
选项,这使得它的行为类似于差异实用程序,即1
当存在差异且未0
发现差异时以状态退出。
使用它,我们可以通过以下方式检查未暂存的更改:
git diff --exit-code
并进行了但未提交的更改:
git diff --cached --exit-code
虽然git diff
可以通过适当的参数报告子模块中未跟踪的文件--ignore-submodules
,不幸的是,似乎没有办法让它报告实际工作目录中未跟踪的文件。如果工作目录中未跟踪的文件是相关的,git status --porcelain
这可能是最好的选择。
答案2
使用:
git update-index --really-refresh
git diff-index --quiet HEAD
返回代码反映了工作目录的状态(0 = 干净,1 = 脏)。未跟踪的文件将被忽略。
答案3
答案4
我做了这样的测试
TEST=$(git status --porcelain|wc -l)
if [ 0 -eq $TEST ]; then
echo "No changes"
else
echo "Changes"
fi