web-dev-qa-db-ja.com

現在のブランチにコミットするものがないかどうかを確認するにはどうすればよいですか?

目標は、シェルコマンドで評価できる明確なステータスを取得することです。

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
158
9nix00

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 '/$'

-vからegrepは、パターンに一致しない行のみを出力することを意味し、パターンは/で終わる行に一致します。

195
Mark Longair

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 (セクション文字列比較)を参照してください。

101
eckes

あなたが私のような人なら、あなたは次のものがあるかどうか知りたいです:

1)既存のファイルの変更2)新しく追加されたファイル3)削除されたファイル

特に4)追跡されていないファイルについて知りたくない。

これはそれを行う必要があります:

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

レポジトリがクリーンな場合にスクリプトを終了するための私のbashコードは次のとおりです。追跡されていないファイルオプションの短いバージョンを使用します。

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

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コマンドに追加して、サイレントにします。

8
Steve Prentice

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-filesおよびgit diff-indexを使用して、既知のファイルに変更があるかどうかを調べる方法を示しています。ただし、新しい未知のファイルが作業ツリーに追加されているかどうかを確認することはできません。

5
Arrowmaster

私はこれでテストをします:

git diff --quiet --cached

またはこれは明示的です:

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

どこ:

-exit-code

Diff(1)に類似したコードでプログラムを終了します。つまり、違いがあった場合は1で終了し、0は違いがないことを意味します。

-quiet

プログラムのすべての出力を無効にします。暗黙的に--exit-code

4
archf

私は議論に少し遅れていますが、git status --porcelainが何も返さず、他に!= 0を返す場合に0の終了コードが必要なだけなら、これを試してください:

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

これにより、行数が終了コードになります…

2
Skeeve

私はこれをスクリプトで使用して次のものを持っています:

  • 0すべてがきれいなとき
  • 1 diffまたは追跡されていないファイルがある場合

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

1
grosser

きれいではありませんが、動作します:

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

メッセージがロケールに依存しているかどうかがわからないため、LANG=Cを先頭に配置することができます。

0
Tilman Vogel