1. ホーム
  2. ギット

[解決済み] [Solved] 未コミットの変更があるかどうかをプログラムで判断するには?

2022-04-15 21:15:18

質問

Makefile で、コミットされていない変更があった場合 (作業ツリーまたはインデックスのいずれか) に特定のアクションを実行したいのですが、どうすればいいですか? これを行うのに最もクリーンで効率的な方法は何でしょうか? 一方の場合はゼロ、他方の場合は非ゼロの戻り値で終了するコマンドは私の目的に合っています。

を実行することができます。 git status を経由して出力をパイプします。 grep しかし、もっといい方法があるような気がします。

どのように解決するのですか?

アップデイト : OP ダニエル・シュトゥッツバッハ 指摘 コメントで この単純なコマンドは git diff-index が効いたそうです。

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

より正確なオプションは git status --porcelain=v1 2>/dev/null | wc -l を使用します。 porcelain オプション .

参照 ミリディウム 's 回答 .

( 九角形 言及 コメントで を実行する必要があります。 git update-index --refresh 前に git diff-index それ以外の場合は diff-index は、ツリーが汚れていると誤って報告します)

すると、"が表示されます。 コマンドが成功したかどうかを確認するには? bashスクリプトで使用している場合は、"です。

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

コメント によって アンソニー・ソッティル

git diff-index HEAD ... は、コミットのないブランチ (たとえば新しく初期化されたリポジトリ) では失敗します。

私が見つけた一つの回避策は git diff-index $(git write-tree) ...

そして haridsv ポイント コメントで その git diff-files を搭載しています。 新しい ファイルでは、差分として検出されません。

より安全な方法としては git add を使用し、その後 git diff-index を実行する前に、インデックスに何かが追加されたかどうかを確認するために git commit .

git add ${file_args} && \

git diff-index --cached --quiet HEAD || git commit -m '${commit_msg}'

そして 6502 をコメントで報告しています。

ぶつけた問題点としては git diff-index は、ファイルのタイムスタンプを除いて、実際には何の違いもないのに、違いがあると言ってしまいます。

実行中 git diff を一回で解決してしまう(意外と知られていない。 git diff は実際にサンドボックスの内容を変更します。つまり、ここでは .git/index )

このようなタイムスタンプの問題は、git が次のような場合にも発生します。 dockerで動作している .


オリジナルの回答です。

プログラム的にというのは には決して頼らないでください。 ポーセリンコマンド .

いつも頼りにしている 配管コマンド .

"もご覧ください。 Git でダーティなインデックスや未追跡のファイルをチェックする のような)代替案については、" を参照してください。 git status --porcelain )

インスピレーションを得ることができます を追加しました。 require_clean_work_tree 機能 現在執筆中です。 ;) (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
}