有些脚本在检查更改时不能正确工作。

我是这样试的:

VN=$(git describe --abbrev=7 HEAD 2>/dev/null)

git update-index -q --refresh
CHANGED=$(git diff-index --name-only HEAD --)
if [ ! -z $CHANGED ];
    then VN="$VN-mod"
fi

是否存在某种布尔检查,自上次提交以来是否有更改,或者我如何真正测试本地存储库是否有新的更改?

我所做的所有这些都是为了一个版本创建脚本(我在这里的某个地方找到的)。


当前回答

这工作得很好。它还会列出受影响的文件:

if git diff-index --name-status --exit-code HEAD;
then
    echo Git working copy is clean...;
else
    echo ;
    echo ERROR: Git working copy is dirty!;
    echo Commit your changes and try again.;
fi;

其他回答

Ansible的解决方案:

- name: Bootstrap checks
  block:
  - shell: "git status --porcelain"
    register: git_status
  - fail:
      msg: "Please clean git status: {{ git_status.stdout }}"
    when: git_status.stdout != ""

下面是一组很棒的Bash脚本函数,它可以检查是否存在差异,将其打印给用户,并提示用户是否希望在部署之前提交更改。它是为Heroku和Python应用程序构建的,但对于任何其他应用程序,它几乎不需要更改。

commit(){
    echo "Please enter a commit message..."
    read msg
    git add . --all
    git commit -am $msg
}

check_commit(){
    echo ========== CHECKING FOR CHANGES ========
    changes=$(git diff)
    if [ -n "$changes" ]; then
        echo ""
        echo "*** CHANGES FOUND ***"
        echo "$changes"
        echo ""
        echo "You have uncomitted changes."
        echo "Would you like to commit them (y/n)?"
        read n
        case $n in
            "y") commit;;
            "n") echo "Changes will not be included...";;
            *) echo "invalid option";;
        esac
    else
        echo "... No changes found"
    fi
}

deploy(){
    check_commit
    echo ========== DEPLOYING TO HEROKU ========
    git push heroku master
    heroku run python manage.py syncdb
}

你可以从gist上复制:https://gist.github.com/sshadmand/f33afe7c9071bb725105

虽然Jefromi的回答很好,但我发布这篇文章只是为了参考。

在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
}

您所做的几乎可以工作:如果它是空的,您应该引用$CHANGED,而-z测试为空,这意味着没有更改。你的意思是:

if [ -n "$CHANGED" ]; then
    VN="$VN-mod"
fi

引用Git的Git - version - gen:

git update-index -q --refresh
test -z "$(git diff-index --name-only HEAD --)" ||
VN="$VN-dirty"

看起来你是在抄袭,但你忘记了引用的细节。

当然,你也可以这样做:

if git diff-index --quiet HEAD --; then
    # No changes
else
    # Changes
fi

或者如果你只关心“某事发生了变化”的情况:

if ! git diff-index --quiet HEAD --; then
    VN="$VN-mod"
fi

使用——quiet的好处是Git可以在遇到单个差异时立即停止处理,因此它可能不需要检查整个工作树。

我的观点是:

git status --porcelain | head -1

只返回一行,而不是一个长列表