git - 我如何以编程方式确定是否有未提交的更改?

标签 git

在 Makefile 中,如果有未提交的更改(在工作树或索引中),我想执行某些操作。最干净、最有效的方法是什么?在一种情况下返回值为零而在另一种情况下返回值为非零的命令将适合我的目的。

我可以运行 git status 并通过 grep 管道输出,但我觉得一定有更好的方法。

最佳答案

更新:OP Daniel Stutzbach指出in the comments这个简单的命令 git diff-index为他工作:

git update-index --refresh 
git diff-index --quiet HEAD --

一个更精确的选择是测试 git status --porcelain=v1 2>/dev/null | wc -l,使用 porcelain option .
参见 Myridiumanswer .

( nornagon 提到 in the comments 如果有文件被触及,但其内容与索引中的内容相同,则需要运行 git update-index --refreshgit diff-index 之前,否则 diff-index 会错误地报告树是脏的)

如果您在 bash 脚本中使用它,您可以看到“How to check if a command succeeded?”:

git diff-index --quiet HEAD -- || echo "untracked"; // do something about it

注:如commented通过 Anthony Sottile

git diff-index HEAD ... will fail on a branch which has no commits (such as a newly initialized repository).
One workaround I've found is git diff-index $(git write-tree) ...

haridsv指出in the comments 文件上的 git diff-files 没有将其检测为 diff。
更安全的方法似乎是先在文件规范上运行 git add,然后使用 git diff-index 查看在运行 git 之前是否有任何内容添加到索引中提交

git add ${file_args} && \
git diff-index --cached --quiet HEAD || git commit -m '${commit_msg}'

6502评论中的报道:

One problem I bumped in is that git diff-index will tell that there are differences when indeed there is none except for timestamps of the files.
Running git diff once solves the issue (surprisingly enough, git diff does actually change the content of the sandbox, meaning here .git/index)

如果 git 是 running in docker,也会出现这些时间戳问题.


原答案:

“以编程方式”意味着从不依赖porcelain commands .
一直依赖plumbing commands .

另请参阅“Checking for a dirty index or untracked files with Git”以了解替代方案(如 git status --porcelain)

你可以汲取灵感from the new "require_clean_work_tree function" which is written as we speak ;)(2010 年 10 月上旬)

require_clean_work_tree () {
    # Update the index
    git update-index -q --ignore-submodules --refresh
    err=0

    # Disallow unstaged changes in the working tree
    if ! git diff-files --quiet --ignore-submodules --
    then
        echo >&2 "cannot $1: you have unstaged changes."
        git diff-files --name-status -r --ignore-submodules -- >&2
        err=1
    fi

    # Disallow uncommitted changes in the index
    if ! git diff-index --cached --quiet HEAD --ignore-submodules --
    then
        echo >&2 "cannot $1: your index contains uncommitted changes."
        git diff-index --cached --name-status -r --ignore-submodules HEAD -- >&2
        err=1
    fi

    if [ $err = 1 ]
    then
        echo >&2 "Please commit or stash them."
        exit 1
    fi
}

关于git - 我如何以编程方式确定是否有未提交的更改?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3878624/

相关文章:

Git:如何确保未跟踪的配置文件不会被静默删除

git - 'git bisect skip'在TortoiseGit中怎么办?

linux - ubuntu安装gitlab失败

linux - Git pull : Change Authentication

git - Mac 终端命令 - 忘记关闭引号后如何返回

linux - Git 推送更改文件的所有权导致 500 服务器错误

Github for mac diff 选项

git - 使用 git 开发时修复错误

git - merge (无分支)到 master

python - Yosup Echoclient 错误 : "InvalidMessage or KeyId for 91XXXXXXXXXX, going to send a retry"