Chr*_*sen 388
可靠地"编写脚本"Git的关键是使用'plumbing'命令.
开发人员在更改管道命令时要小心,以确保它们提供非常稳定的接口(即存储库状态,stdin,命令行选项,参数等的给定组合将在所有版本的Git中产生相同的输出,其中命令/选项存在).管道命令中的新输出变化可以通过新选项引入,但是对于已经针对旧版本编写的程序不会引入任何问题(它们不会使用新选项,因为它们不存在(或者至少是在编写脚本时没用过).
不幸的是,'日常'Git命令是'瓷器'命令,所以大多数Git用户可能不熟悉管道命令.瓷器和管道命令之间的区别在主git联机帮助页中进行(参见标题为高级命令(瓷器)和低级命令(管道)的小节.
要了解未经修改的更改,您可能需要git diff-index
(比较索引(可能跟踪工作树的位)与其他树木(例如HEAD
)),也许git diff-files
(比较工作树与索引),以及可能git ls-files
(列表文件;例如列表未跟踪) ,未经标记的文件).
(请注意,在下面的命令中,HEAD --
使用而不是HEAD
因为如果存在名为的文件,命令将失败HEAD
.)
要检查存储库是否已暂存更改(尚未提交),请使用以下命令:
git diff-index --quiet --cached HEAD --
Run Code Online (Sandbox Code Playgroud)
0
随之退出则没有差异(1
意味着存在差异).要检查工作树是否有可以暂存的更改:
git diff-files --quiet
Run Code Online (Sandbox Code Playgroud)
git diff-index
(0
==无差异; 1
==差异)相同.检查工作树中索引和跟踪文件的组合是否有关于HEAD
以下内容的更改:
git diff-index --quiet HEAD --
Run Code Online (Sandbox Code Playgroud)
HEAD
),它仍然会报告"没有差异" .在同样的情况下,两个单独的命令都将返回"存在差异"的报告.您还提到了未跟踪的文件.你可能的意思是"没有跟踪和不受欢迎",或者你可能意味着只是简单的"未跟踪"(包括被忽略的文件).无论哪种方式,git ls-files
是工作的工具:
对于"未跟踪"(将包括被忽略的文件,如果存在):
git ls-files --others
Run Code Online (Sandbox Code Playgroud)
对于"未跟踪和不受欢迎":
git ls-files --exclude-standard --others
Run Code Online (Sandbox Code Playgroud)
我的第一个想法是检查这些命令是否有输出:
test -z "$(git ls-files --others)"
Run Code Online (Sandbox Code Playgroud)
0
然后没有未跟踪的文件.如果它退出1
然后有未跟踪的文件.这很可能会将异常退出git ls-files
转换为"无未跟踪文件"报告(两者都会导致上述命令的非零退出).更健壮的版本可能如下所示:
u="$(git ls-files --others)" && test -z "$u"
Run Code Online (Sandbox Code Playgroud)
git ls-files
传播出去.在这种情况下,非零退出可能意味着"有未跟踪的文件"或者它可能意味着发生了错误.如果您希望将"错误"结果与"无跟踪文件"结果相结合,请使用test -n "$u"
(其中"退出" 0
表示"某些未跟踪文件",非零表示错误或"没有未跟踪文件").另一个想法是--error-unmatch
在没有未跟踪文件时使用导致非零退出.这也存在将"没有未跟踪文件"(退出1
)与"发生错误" 混淆的风险(退出非零,但可能128
).但检查0
vs. 1
与非零退出代码可能相当强大:
git ls-files --others --error-unmatch . >/dev/null 2>&1; ec=$?
if test "$ec" = 0; then
echo some untracked files
elif test "$ec" = 1; then
echo no untracked files
else
echo error from ls-files
fi
Run Code Online (Sandbox Code Playgroud)
如果您只想考虑未跟踪和未签名的文件,则git ls-files
可以采用上述任何示例--exclude-standard
.
0xf*_*xfe 167
好时机!几天前我写了一篇关于这个的博客文章,当时我想出了如何在我的提示中添加git状态信息.
这是我做的:
对于脏状态:
# Returns "*" if the current git branch is dirty.
function evil_git_dirty {
[[ $(git diff --shortstat 2> /dev/null | tail -n1) != "" ]] && echo "*"
}
Run Code Online (Sandbox Code Playgroud)对于未跟踪的文件(注意--porcelain
标志为其git status
提供了可用的可解析输出):
# Returns the number of untracked files
function evil_git_num_untracked_files {
expr `git status --porcelain 2>/dev/null| grep "^??" | wc -l`
}
Run Code Online (Sandbox Code Playgroud)虽然git diff --shortstat
更方便,但您也可以git status --porcelain
用于获取脏文件:
# Get number of files added to the index (but uncommitted)
expr $(git status --porcelain 2>/dev/null| grep "^M" | wc -l)
# Get number of files that are uncommitted and not added
expr $(git status --porcelain 2>/dev/null| grep "^ M" | wc -l)
# Get number of total uncommited files
expr $(git status --porcelain 2>/dev/null| egrep "^(M| M)" | wc -l)
Run Code Online (Sandbox Code Playgroud)
注意:2>/dev/null
筛选出错误消息,以便您可以在非git目录上使用这些命令.(他们只会返回0
文件计数.)
编辑:
以下是帖子:
ben*_*ado 136
假设您使用的是git 1.7.0或更高版本...
在阅读了本页面上的所有答案和一些实验后,我认为正确和简洁的正确组合的方法是:
test -n "$(git status --porcelain)"
Run Code Online (Sandbox Code Playgroud)
虽然git允许在跟踪,忽略,未跟踪但未签名等等之间存在很多细微差别,但我相信典型的用例是自动构建脚本,如果您的结账不干净,您希望停止所有内容.
在这种情况下,模拟程序员会做什么是有意义的:输入git status
并查看输出.但是我们不想依赖特定的单词出现,所以我们使用--porcelain
1.7.0中引入的模式; 启用时,干净的目录不会导致输出.
然后我们test -n
用来查看是否有任何输出.
如果工作目录是干净的,则此命令将返回1;如果要提交更改,则此命令将返回0.如果您想要相反,可以将其更改-n
为a -z
.这对于将其链接到脚本中的命令很有用.例如:
test -z "$(git status --porcelain)" || red-alert "UNCLEAN UNCLEAN"
Run Code Online (Sandbox Code Playgroud)
这有效地说"要么没有变化要么发出警报"; 根据您编写的脚本,这个单行可能比if语句更可取.
Dea*_*her 14
VonC回答的一个实现:
if [[ -n $(git status --porcelain) ]]; then echo "repo is dirty"; fi
Run Code Online (Sandbox Code Playgroud)
看了几个答案......(并且在*nix和windows上有各种问题,这是我的要求)......发现以下效果很好......
git diff --no-ext-diff --quiet --exit-code
Run Code Online (Sandbox Code Playgroud)
检查*nix中的退出代码
echo $?
#returns 1 if the repo has changes (0 if clean)
Run Code Online (Sandbox Code Playgroud)
检查窗口$中的退出代码
echo %errorlevel%
#returns 1 if the repos has changes (0 if clean)
Run Code Online (Sandbox Code Playgroud)
来自https://github.com/sindresorhus/pure/issues/115 感谢@paulirish对该帖子的分享
git status
为什么不使用脚本封装 ' :
这样,您就可以在脚本中使用“增强”状态。
正如0xfe在他的出色回答中提到的那样,git status --porcelain
在任何基于脚本的解决方案中都非常有用
--porcelain
Run Code Online (Sandbox Code Playgroud)
以稳定、易于解析的脚本格式提供输出。
目前这与 相同--short output
,但保证将来不会改变,从而使脚本安全。
一种 DIY 可能性,已更新以遵循0xfe的建议
#!/bin/sh
exit $(git status --porcelain | wc -l)
Run Code Online (Sandbox Code Playgroud)
正如Chris Johnsen所指出的,这只适用于 Git 1.7.0 或更高版本。
归档时间: |
|
查看次数: |
71556 次 |
最近记录: |