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

时间:2011-02-28 07:35:00

标签: git git-status

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

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

git status
echo $?  #this is always 0

我有一个想法,但我认为这是一个糟糕的主意。

if [ git status | grep -i -c "[a-z]"> 2 ];
then
 code for change...
else
  code for nothing change...
fi

任何其他方式?


使用以下解决方式进行更新,请参阅Mark Longair的帖子

我尝试了这个,但它会导致问题。

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

我收到以下错误[: ??: 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

9 个答案:

答案 0 :(得分:188)

测试git status --porcelain的输出是否为空的替代方法是分别测试您关心的每个条件。例如,如果git status的输出中有未跟踪的文件,可能并不总是在乎。

例如,要查看是否存在任何本地非暂停更改,您可以查看返回代码:

git diff --exit-code

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

git diff --cached --exit-code

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

git ls-files --other --exclude-standard --directory

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

git ls-files --other --exclude-standard --directory | egrep -v '/$'

-vegrep表示只输出与模式不匹配的行,模式匹配任何以/结尾的行。

答案 1 :(得分:98)

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

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

git status --porcelain

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

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

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

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

答案 2 :(得分:28)

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

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

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

这应该这样做:

git status --untracked-files=no --porcelain

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

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

答案 3 :(得分:8)

可以将git status --porcelain与简单的grep结合起来进行测试。

if git status --porcelain | grep .; then
    echo Repo is dirty
else
    echo Repo is clean
fi

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

# pull from origin if our repo is clean
git status --porcelain | grep . || git pull origin master

-qs添加到grep命令以使其静音。

答案 4 :(得分: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
}

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

答案 5 :(得分:4)

我对此进行测试:

git diff --quiet --cached

或者这是明确的:

git diff --quiet --exit-code --cached

其中:

<强> - 退出代码

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

<强> - 安静

禁用程序的所有输出。意味着--exit-code

答案 6 :(得分:2)

我在讨论中有点迟了,但如果git status --porcelain没有返回任何内容而你只需要退出代码为0,那么请尝试:< / p>

exit $( git status --porcelain | wc -l )

这将使行数成为退出代码......

答案 7 :(得分:1)

我在脚本中使用它来:

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

    [-z&#34; $(git status --porcelain)&#34; ]

答案 8 :(得分:0)

不漂亮,但有效:

git status | grep -qF 'working directory clean' || echo "DIRTY"

不确定该消息是否依赖于语言环境,因此可能会将LANG=C放在前面。