bre*_*son 154 git shell-script
我有一个rsync
以 Git 工作目录作为目标运行的脚本。我希望脚本根据工作目录是否干净(没有更改提交)而具有不同的行为。例如,如果输出git status
如下,我希望脚本退出:
git status
Already up-to-date.
# On branch master
nothing to commit (working directory clean)
Everything up-to-date
Run Code Online (Sandbox Code Playgroud)
如果目录不干净,那么我希望它执行更多命令。
如何在 shell 脚本中检查上述输出?
Tho*_*man 235
解析 的输出git status
是一个坏主意,因为输出旨在是人类可读的,而不是机器可读的。无法保证在未来版本的 Git 或不同配置的环境中输出将保持不变。
UVVs 注释在正确的轨道上,但不幸的是git status
,当有未提交的更改时,返回代码不会更改。它,然而,提供的--porcelain
选项,这将导致输出git status --porcelain
在一个易于解析格式脚本来进行格式化,并仍将是跨版本的Git稳定,无论用户配置的。
我们可以使用空输出git status --porcelain
作为没有要提交的更改的指示符:
if [ -z "$(git status --porcelain)" ]; then
# Working directory clean
else
# Uncommitted changes
fi
Run Code Online (Sandbox Code Playgroud)
如果我们不关心工作目录中未跟踪的文件,我们可以使用--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
Run Code Online (Sandbox Code Playgroud)
为了使其在没有输出到 的情况下实际导致git status
失败的情况下更加稳健stdout
,我们可以将检查细化为:
if output=$(git status --porcelain) && [ -z "$output" ]; then
# Working directory clean
else
# Uncommitted changes
fi
Run Code Online (Sandbox Code Playgroud)
还值得注意的是,虽然git status
在工作目录不干净时没有给出有意义的退出代码,但git diff
提供了--exit-code
选项,这使得它的行为类似于diff实用程序,即1
在存在差异和0
没有发现差异时以状态退出。
使用它,我们可以检查未暂存的更改:
git diff --exit-code
Run Code Online (Sandbox Code Playgroud)
并已上演但未提交的更改:
git diff --cached --exit-code
Run Code Online (Sandbox Code Playgroud)
虽然git diff
可以通过适当的参数报告子模块中未跟踪的文件--ignore-submodules
,但不幸的是,似乎没有办法让它报告实际工作目录中未跟踪的文件。如果工作目录中未跟踪的文件是相关的,git status --porcelain
则可能是最好的选择。
小智 39
用:
git diff-index --quiet HEAD
Run Code Online (Sandbox Code Playgroud)
返回码反映了工作目录的状态(0 = 干净,1 = 脏)。未跟踪的文件将被忽略。
对Andr\xc3\xa9\'s优秀答案的小扩展。
\n未跟踪的文件将被忽略。
\ngit update-index --really-refresh\nif git diff-index --quiet HEAD\nthen\n GIT_MODS="clean"\nelse\n GIT_MODS="dirty"\nfi\n
Run Code Online (Sandbox Code Playgroud)\n如果你想避免在 stdout 中放入东西,你可能需要添加>> /dev/null
或类似的就行了update-index
。
如果您只想要 0 或 1 进程退出代码,那么您可以在块之外运行测试if-then
。
#!/bin/bash
[ -z "$(git status --porcelain)" ]
Run Code Online (Sandbox Code Playgroud)
或者
#!/bin/bash
test -z "$(git status --porcelain)"
Run Code Online (Sandbox Code Playgroud)
例子:
$ test -z "$(git status --porcelain)"
$ echo $?
0
$ echo 'hello world' > fish.txt
$ test -z "$(git status --porcelain)"
$ echo $?
1
Run Code Online (Sandbox Code Playgroud)