如何检查当前分支中是否没有提交?

9ni*_*x00 166 git git-status

目标是获得可以在shell命令中评估的明确状态.

我试过git status但它总是返回0,即使有提交的项目.

git status
echo $?  #this is always 0
Run Code Online (Sandbox Code Playgroud)

我有一个想法,但我认为这是一个坏主意.

if [ git status | grep -i -c "[a-z]"> 2 ];
then
 code for change...
else
  code for nothing change...
fi
Run Code Online (Sandbox Code Playgroud)

任何其他方式?


通过以下解决更新,请参阅Mark Longair的帖子

我尝试了这个,但它导致了一个问题.

if [ -z $(git status --porcelain) ];
then
    echo "IT IS CLEAN"
else
    echo "PLEASE COMMIT YOUR CHANGE FIRST!!!"
    echo git status
fi
Run Code Online (Sandbox Code Playgroud)

我收到以下错误 [: ??: binary operator expected

现在,我正在看那个男人并尝试git diff.

===================代码为我的希望,希望更好的答案======================

#if [ `git status | grep -i -c "$"` -lt 3 ];
# change to below code,although the above code is simple, but I think it is not strict logical
if [ `git diff --cached --exit-code HEAD^ > /dev/null && (git ls-files --other --exclude-standard --directory | grep -c -v '/$')` ];
then
        echo "PLEASE COMMIT YOUR CHANGE FIRST!!!"
    exit 1

else
    exit 0
fi
Run Code Online (Sandbox Code Playgroud)

Mar*_*air 208

测试输出是否git status --porcelain为空的另一种方法是分别测试您关心的每个条件.例如,如果输出中存在未跟踪的文件,则可能并不总是在意git status.

例如,要查看是否存在任何本地未分级更改,您可以查看以下返回代码:

git diff --exit-code
Run Code Online (Sandbox Code Playgroud)

要检查是否有任何已暂存但未提交的更改,您可以使用以下返回代码:

git diff --cached --exit-code
Run Code Online (Sandbox Code Playgroud)

最后,如果您想知道工作树中是否有未被跟踪的未跟踪文件,您可以测试以下命令的输出是否为空:

git ls-files --other --exclude-standard --directory
Run Code Online (Sandbox Code Playgroud)

更新: 您在下面询问是否可以更改该命令以排除输出中的目录.您可以通过添加排除空目录--no-empty-directory,但要排除该输出中的所有目录,我认为您必须过滤输出,例如:

git ls-files --other --exclude-standard --directory | egrep -v '/$'
Run Code Online (Sandbox Code Playgroud)

-vegrep装置到不匹配的模式只输出线,而图案与一个结尾的任何线相匹配/.

  • 对于那些只想要退出代码的人来说,`--quiet`(暗示`--exit-code`)也会使输出静音. (9认同)
  • @albfan:它在[git-diff手册页](http://git-scm.com/docs/git-diff)中:"使程序退出,代码类似于diff(1).即退出如果存在差异则为1,0表示没有差异." (3认同)

eck*_*kes 103

返回值git status只是告诉您退出代码git status,而不是是否有任何修改要提交.

如果您想要更多计算机可读版本的git status输出,请尝试

git status --porcelain
Run Code Online (Sandbox Code Playgroud)

有关git status详细信息,请参阅说明.

示例使用(脚本只是测试是否git status --porcelain提供任何输出,不需要解析):

if [ -n "$(git status --porcelain)" ]; then
  echo "there are changes";
else
  echo "no changes";
fi
Run Code Online (Sandbox Code Playgroud)

请注意,您必须引用要测试的字符串,即输出git status --porcelain.有关测试构造的更多提示,请参阅Advanced Bash Scripting Guide(章节字符串比较).

  • @ 9nix00:停下来.为什么要Base64编码? (7认同)
  • 很好的解决方案。为了增加稳健性,您可以附加`|| echo no` 命令替换,这样如果 `git status` 从根本上失败,工作区就不会被错误地报告为干净。另外,你的代码(值得称赞的是)符合 POSIX 标准,但由于你链接到了 bash 指南,所以让我补充一下,如果你使用 bash 的 `[[ ... ]]` 而不是 POSIX 兼容的 `[ ... ] `,您不需要双引号命令替换(尽管它没有坏处):`[[ -z $(git status --porcelain) ]]`。 (2认同)

moo*_*oom 31

如果你像我一样,你想知道是否有:

1)对现有文件的更改2)新添加的文件3)删除的文件

并且特别不想知道4)未跟踪的文件.

这应该这样做:

git status --untracked-files=no --porcelain
Run Code Online (Sandbox Code Playgroud)

如果repo是干净的,这是我的bash代码退出脚本.它使用未跟踪文件选项的简短版本:

[[ -z $(git status -uno --porcelain) ]] && echo "this branch is clean, no need to push..." && kill -SIGINT $$;
Run Code Online (Sandbox Code Playgroud)

  • +1代表`-untracked-files = no`; 我认为你的测试可以简化为`[[-z $(git status --ntracked-files = no --porcelain)]]`.`git status`不应写入stderr,除非出现基本问题 - 然后你想要看到那个输出.(如果您希望在该事件中具有更强大的行为,请将`|| echo no`附加到命令替换,以便清洁测试仍然失败).字符串比较/`-z`运算符可以处理多行字符串 - 不需要`tail`. (4认同)
  • 谢谢@ mklement0,甚至更短:`[[-z $(git status -u no --porcelain)]]` (2认同)
  • 我很欣赏后续行动; 这是一个微妙的错误 - 教训是带有_optional_参数的_short_选项必须附加_directly_参数,中间没有空格.如何将纠正的短版本直接纳入您的答案? (2认同)

Ste*_*ice 8

可以结合git status --porcelain使用简单的方法grep来执行测试.

if git status --porcelain | grep .; then
    echo Repo is dirty
else
    echo Repo is clean
fi
Run Code Online (Sandbox Code Playgroud)

我有时将它用作简单的单行程序:

# pull from origin if our repo is clean
git status --porcelain | grep . || git pull origin master
Run Code Online (Sandbox Code Playgroud)

添加-qs到grep命令以使其保持静默.

  • +1 优雅;轻微警告:如果`git status` 致命失败(例如,损坏的存储库),您的测试将错误地报告 _clean_ 工作区。一种选择是使用 `git status --porcelain 2>&1`,但如果你使用 grep 和 `-q`,那会“吃掉”错误信息。(处理它会失去优雅:`(git status --porcelain || echo err)| grep -q .`) (2认同)

小智 6

我会对此进行测试:

git diff --quiet --cached
Run Code Online (Sandbox Code Playgroud)

或者这是明确的:

git diff --quiet --exit-code --cached
Run Code Online (Sandbox Code Playgroud)

在哪里:

--退出代码

使用类似于 diff(1) 的代码使程序退出。也就是说,如果存在差异,则以 1 退出,0 表示没有差异。

- 安静的

禁用程序的所有输出。暗示 --exit-code


Arr*_*ter 5

从git源代码中有一个sh脚本,其中包含以下内容.

require_clean_work_tree () {
    git rev-parse --verify HEAD >/dev/null || exit 1
    git update-index -q --ignore-submodules --refresh
    err=0

    if ! git diff-files --quiet --ignore-submodules
    then
        echo >&2 "Cannot $1: You have unstaged changes."
        err=1
    fi

    if ! git diff-index --cached --quiet --ignore-submodules HEAD --
    then
        if [ $err = 0 ]
        then
            echo >&2 "Cannot $1: Your index contains uncommitted changes."
        else
            echo >&2 "Additionally, your index contains uncommitted changes."
        fi
        err=1
    fi

    if [ $err = 1 ]
    then
        test -n "$2" && echo >&2 "$2"
        exit 1
    fi
}
Run Code Online (Sandbox Code Playgroud)

此代码段显示了如何使用它git diff-filesgit diff-index查明以前已知文件是否有任何更改.但是,它不允许您查明是否已将新的未知文件添加到工作树中.


gro*_*ser 5

我在脚本中使用它来实现:

  • 0 当一切都干净时
  • 1 当存在差异或未跟踪的文件时

    [ -z "$(git status --porcelain)" ]

  • 使用“如果!” git diff --安静;then` 更干净、更高效(我认为)。换句话说,使用退出代码,而不是标准输出。 (2认同)

Ske*_*eve 5

我的讨论有点晚了,但如果只是需要退出代码 0 ifgit status --porcelain不返回任何内容并且 != 0 else,请尝试以下操作:

exit $( git status --porcelain | wc -l )
Run Code Online (Sandbox Code Playgroud)

这将使行数成为退出代码,当行数超过 255 行时,就有出现问题的风险。所以

exit $( git status --porcelain | head -255 | wc -l )
Run Code Online (Sandbox Code Playgroud)

将解释这一点;)