我如何检查我的git存储库中是否有任何未提交的更改:

添加到索引但未提交的更改 无路径的文件

从一个脚本?

git-status在git 1.6.4.2版本中似乎总是返回0。


当前回答

好时机!几天前我写了一篇关于这方面的博客文章,当时我想出了如何在提示符中添加git状态信息。

我是这么做的:

对于脏状态: 如果当前git分支是脏的,则返回“*”。 函数evil_git_dirty { [[$ (git diff, shortstat 2 > / dev / null |尾巴n1 ) != "" ]] && 回声“*” } 对于未跟踪的文件(请注意git状态的——porcelain标志,它会为您提供良好的可解析输出): 返回未跟踪文件的数量 函数evil_git_num_untracked_files { Expr ' git status——porcelain 2>/dev/null| grep "^??"| wc -l ' }

虽然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)

注意:2>/dev/null会过滤掉错误消息,所以你可以在非git目录上使用这些命令。(它们将简单地为文件计数返回0。)

编辑:

以下是这些帖子:

在终端提示中添加Git状态信息

改进了启用git的Shell提示符

其他回答

这是一个更加shell友好的变体,用于查找存储库中是否存在任何未跟踪的文件:

# Works in bash and zsh
if [[ "$(git status --porcelain 2>/dev/null)" = *\?\?* ]]; then
  echo untracked files
fi

这不会派生第二个进程grep,并且不需要检查您是否在git存储库中。这对于shell提示等很方便。

@eduard- wch的回答很完整,但因为我想同时检查两者,这里是我的最后一个变体。

        set -eu

        u="$(git ls-files --others)"
        if ! git diff-index --name-only --quiet HEAD -- || [ -z "${u:-}" ]; then
            dirty="-dirty"
        fi

当不使用set -e或类似的方法执行时,我们可以执行u="$(git ls-files——others)"|| exit 1(如果对已使用的函数有效,则返回)

因此,untracked_files仅在命令成功时设置。

之后,我们可以检查这两个属性,并设置一个变量(或任何东西)。

这是最好、最干净的方法。由于某些原因,所选的答案对我不起作用,它没有拾取未提交的新文件所进行的更改。

function git_dirty {
    text=$(git status)
    changed_text="Changes to be committed"
    untracked_files="Untracked files"

    dirty=false

    if [[ ${text} = *"$changed_text"* ]];then
        dirty=true
    fi

    if [[ ${text} = *"$untracked_files"* ]];then
        dirty=true
    fi

    echo $dirty
}

你也可以

git describe --dirty

. 如果它检测到一个肮脏的工作树,它将在结尾附加单词“-dirty”。根据git-describe(1):

   --dirty[=<mark>]
       Describe the working tree. It means describe HEAD and appends <mark> (-dirty by default) if
       the working tree is dirty.

. 注意:未跟踪的文件不被认为是“脏文件”,因为,正如manpage声明的那样,它只关心工作树。

假设你使用的是git 1.7.0或更高版本…

在阅读了本页上的所有答案并进行了一些实验后,我认为将正确性和简洁性正确结合的方法是:

test -n "$(git status --porcelain)"

虽然git允许在跟踪、忽略、未跟踪但未忽略等内容之间有很多细微差别,但我相信典型的用例是用于自动化构建脚本,如果签出不干净,您希望停止所有内容。

在这种情况下,模拟程序员将要做的事情是有意义的:键入git status并查看输出。但我们不想依赖于特定的单词显示,所以我们使用了1.7.0中引入的——porcelain模式;启用干净目录时,不会产生任何输出。

然后使用test -n查看是否有输出。

如果工作目录是干净的,该命令将返回1,如果有要提交的更改,则返回0。你可以把-n改成-z。这对于将其链接到脚本中的命令非常有用。例如:

test -z "$(git status --porcelain)" || red-alert "UNCLEAN UNCLEAN"

这实际上是在说“要么不需要做出改变,要么就会拉响警报”;这个一行语句可能比if语句更可取,这取决于您正在编写的脚本。