在Makefile中,如果存在未提交的更改(在工作树或索引中),我想执行某些操作.什么是最干净,最有效的方法?退出的命令在一种情况下返回值为零而在另一种情况下为非零符合我的目的.
我可以运行git status并输出输出grep,但我觉得必须有更好的方法.
Von*_*onC 271
UPDATE:在OP 丹尼尔Stutzbach指出,在评论这个简单的命令git diff-index为他工作:
git diff-index --quiet HEAD --
Run Code Online (Sandbox Code Playgroud)
然后,如果您在bash脚本中使用它,则可以看到" 如何检查命令是否成功? ":
git diff-index --quiet HEAD -- || echo "untracked"; // do something about it
Run Code Online (Sandbox Code Playgroud)
git diff-index HEAD ...将在没有提交的分支上失败(例如新初始化的存储库).
我找到的一个解决方法是git diff-index $(git write-tree) ...
"以编程方式"意味着永远不要依赖瓷器命令.
始终依赖管道命令.
另请参阅" 使用Git检查脏索引或未跟踪文件 "(如haridsv)
您可以从我们发言时写的新" git diff-files功能 "中获取灵感;)(2010年10月初)
git add ${file_args} && \
git diff-index --cached --quiet HEAD || git commit -m '${commit_msg}'
Run Code Online (Sandbox Code Playgroud)
Nep*_*har 88
虽然其他解决方案非常彻底,但如果您想要一些非常快速和肮脏的东西,请尝试以下方法:
[[ -z $(git status -s) ]]
Run Code Online (Sandbox Code Playgroud)
它只检查状态摘要中是否有任何输出.
Jos*_*Lee 53
git diff --exit-code如果有任何变化,将返回非零值; git diff --quiet没有输出是一样的.由于您要检查工作树和索引,请使用
git diff --quiet && git diff --cached --quiet
Run Code Online (Sandbox Code Playgroud)
要么
git diff --quiet HEAD
Run Code Online (Sandbox Code Playgroud)
任何一个都会告诉您是否存在未提交的未提交的更改.
Tra*_*der 14
扩展@Nepthar的答案:
if [[ -z $(git status -s) ]]
then
echo "tree is clean"
else
echo "tree is dirty, please commit changes before running this"
exit
fi
Run Code Online (Sandbox Code Playgroud)
一些答案既使问题过于复杂,又没有达到预期的结果。例如,接受的答案会遗漏未跟踪的文件。
尽管有些人(错误地)在评论中另有说法,但仍使用git status --porcelain被设计为机器可解析的提供。如果git status. 所以我用 test 测试清洁度,[ -z "$(git status --porcelain=v1 2>/dev/null)" ]如果在 git 目录之外运行,它也会通过。
最低工作示例:
[ -z "$(git status --porcelain=v1 2>/dev/null)" ] && echo "git undirty"
Run Code Online (Sandbox Code Playgroud)
出现在git status(截至目前)中的任何内容都将正确触发此测试。该=v1位确保跨 git 版本的输出格式一致。
受到这个答案的启发。你grep的git status --porcelain=v1输出行。每行的前两个字符表示特定文件的状态。在 grepping 之后,您可以通过管道输出wc -l计算行数的输出来计算有多少具有该状态。
例如,如果在 git 存储库中运行,此脚本将打印一些信息。
#!/bin/sh
GS=$(git status --porcelain=v1 2>/dev/null) # Exit code 128 if not in git directory. Unfortunately this exit code is a bit generic but it should work for most purposes.
if [ $? -ne 128 ]; then
function _count_git_pattern() {
echo "$(grep "^$1" <<< $GS | wc -l)"
}
echo "There are $(_count_git_pattern "??") untracked files."
echo "There are $(_count_git_pattern " M") unstaged, modified files."
echo "There are $(_count_git_pattern "M ") staged, modified files."
fi
Run Code Online (Sandbox Code Playgroud)
工作树是“干净的”如果
git ls-files \
--deleted \
--modified \
--others \
--exclude-standard \
-- :/
Run Code Online (Sandbox Code Playgroud)
什么也不返回。
--deleted检查工作树中删除的文件--modified检查工作树中修改的文件--others检查工作树中添加的文件--exclude-standard根据通常的.gitignore,.git/info/exclude...规则忽略-- :/所有内容的路径规范,如果不在存储库的根目录中运行则需要如果工作树是干净的,则输出为空
我创建了一些方便的 git 别名来列出未暂存和暂存的文件:
git config --global alias.unstaged 'diff --name-only'
git config --global alias.staged 'diff --name-only --cached'
Run Code Online (Sandbox Code Playgroud)
然后,您可以轻松执行以下操作:
[[ -n "$(git unstaged)" ]] && echo unstaged files || echo NO unstaged files
[[ -n "$(git staged)" ]] && echo staged files || echo NO staged files
Run Code Online (Sandbox Code Playgroud)
您可以通过在PATH被调用的某处创建一个脚本来使其更具可读性git-has:
#!/bin/bash
[[ $(git "$@" | wc -c) -ne 0 ]]
Run Code Online (Sandbox Code Playgroud)
现在上面的例子可以简化为:
git has unstaged && echo unstaged files || echo NO unstaged files
git has staged && echo staged files || echo NO staged files
Run Code Online (Sandbox Code Playgroud)
为了完整起见,这里是未跟踪和忽略文件的类似别名:
git config --global alias.untracked 'ls-files --exclude-standard --others'
git config --global alias.ignored 'ls-files --exclude-standard --others --ignored'
Run Code Online (Sandbox Code Playgroud)
小智 5
使用 python 和 GitPython 包:
import git
git.Repo(path).is_dirty(untracked_files=True)
Run Code Online (Sandbox Code Playgroud)
True如果存储库不干净,则返回
| 归档时间: |
|
| 查看次数: |
78290 次 |
| 最近记录: |