Git でダーティインデックスや追跡されていないファイルを確認する 質問する

Git でダーティインデックスや追跡されていないファイルを確認する 質問する

Git リポジトリにコミットされていない変更があるかどうかを確認するにはどうすればいいですか?

  1. インデックスに追加されたがコミットされていない変更
  2. 追跡されていないファイル

スクリプトからですか?

git-statusgit バージョン 1.6.4.2 では常にゼロを返すようです。

ベストアンサー1

Git を確実に「スクリプト化」するための鍵は、「配管」コマンドを使用することです。

開発者は、配管コマンドを変更する際に、非常に安定したインターフェースを提供するよう注意を払います (つまり、リポジトリの状態、stdin、コマンドライン オプション、引数などの特定の組み合わせは、コマンド/オプションが存在するすべてのバージョンの Git で同じ出力を生成します)。配管コマンドの新しい出力バリエーションは、新しいオプションによって導入できますが、古いバージョンに対して既に記述されているプログラムでは問題が発生することはありません (スクリプトが記述された時点では新しいオプションは存在しなかった (または少なくとも使用されていなかった) ため、古いバージョンでは新しいオプションは使用されません)。

残念ながら、日常的に使われるGitコマンドは「磁器」コマンドなので、ほとんどのGitユーザーは配管コマンドに慣れていないかもしれません。磁器コマンドと配管コマンドの区別は、主にgit マニュアルページ(サブセクションを参照)高レベルコマンド(磁器)そして低レベルコマンド(配管)


コミットされていない変更を確認するには、おそらくgit diff-index(インデックス(およびおそらく作業ツリーの追跡された部分)を他のツリー状のもの(例HEAD)と比較する)、おそらくgit diff-files(作業ツリーをインデックスと比較する)、そしておそらくgit ls-files(ファイルを一覧表示します。例: 追跡されていないファイルや無視されていないファイルを一覧表示します)。

(以下のコマンドでは、HEAD --の代わりに が使用されていることに注意してくださいHEAD。そうでない場合、コマンド失敗するという名前のファイルがある場合HEAD

リポジトリにステージングされた変更(まだコミットされていない)があるかどうかを確認するには、次のコマンドを使用します。

git diff-index --quiet --cached HEAD --
  • で終了する場合0、違いはありませんでした (1違いがあったことを意味します)。

作業ツリーにステージング可能な変更があるかどうかを確認するには:

git diff-files --quiet
  • git diff-index終了コードは( 0== 違いなし; 1== 違い)の場合と同じです。

作業ツリー内のインデックスと追跡ファイルの組み合わせが次の点に関して変更されているかどうかを確認するにはHEAD:

git diff-index --quiet HEAD --
  • これは、前の 2 つを組み合わせたようなものです。主な違いの 1 つは、作業ツリーで「元に戻した」( にあるコンテンツに戻ったHEAD) ステージングされた変更がある場合でも、「違いはありません」と報告されることです。この同じ状況では、2 つの個別のコマンドはどちらも「違いがある」という報告を返します。

追跡されていないファイルについても言及されています。これは「追跡されていない、無視されていない」という意味かもしれませんし、単に「追跡されていない」(無視されたファイルを含む) という意味かもしれません。いずれにしても、git ls-filesこのツールは役に立ちます。

「追跡なし」の場合(存在する場合は無視されたファイルも含まれます):

git ls-files --others

「追跡されず無視されない」場合:

git ls-files --exclude-standard --others

最初に考えたのは、これらのコマンドの出力があるかどうかを確認することです。

test -z "$(git ls-files --others)"
  • で終了する場合、0追跡されていないファイルはありません。 で終了する場合、1追跡されていないファイルが存在します。

これにより、異常終了が「追跡されていないファイルなし」レポートに変換される可能性がわずかにありますgit ls-files(どちらも上記のコマンドの終了がゼロ以外になります)。もう少し堅牢なバージョンは次のようになります。

u="$(git ls-files --others)" && test -z "$u"
  • 考え方は前のコマンドと同じですが、 からの予期しないエラーがgit ls-files外部に伝搬される可能性があります。この場合、 の終了がゼロ以外の場合、「追跡されていないファイルがある」こと、またはエラーが発生したことを意味します。代わりに、「エラー」結果と「追跡されていないファイルがない」結果を組み合わせたい場合は、 を使用しますtest -n "$u"( の終了は「追跡されていないファイルがいくつかある」ことを意味し、 の終了が0ゼロ以外の場合、エラーまたは「追跡されていないファイルがない」ことを意味します)。

もう 1 つのアイデアは、--error-unmatch追跡されていないファイルがない場合に 0 以外の終了を発生させるために を使用することです。これも、「追跡されていないファイルはありません」(終了1) と「エラーが発生しました」(終了 0 以外ですが、おそらく) を混同するリスクがあります。ただし、 vs. vs. 非ゼロ終了コード128をチェックすることは、おそらくかなり堅牢です。01

git ls-files --others --error-unmatch . >/dev/null 2>&1; ec=$?
if test "$ec" = 0; then
    echo some untracked files
elif test "$ec" = 1; then
    echo no untracked files
else
    echo error from ls-files
fi

追跡されていないファイルと無視されていないファイルのみを考慮する場合は、上記のいずれかのgit ls-files例を使用できます。--exclude-standard

おすすめ記事