Gitを確実に「スクリプト化」するための鍵は、「配管」コマンドを使用することです。
開発者は、配管コマンドを変更するときに注意を払い、非常に安定したインターフェースを提供するようにします(つまり、リポジトリーの状態、標準入力、コマンドラインオプション、引数などの特定の組み合わせは、コマンド/のすべてのバージョンの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"
(exit 0
は「追跡されていないファイル」を意味し、ゼロ以外はエラーまたは「追跡されていないファイル」を意味します)。
別のアイデアは、を使用--error-unmatch
して、追跡されていないファイルがない場合にゼロ以外の終了を発生させることです。これには、「追跡されていないファイルがない」(exit 1
)と「エラーが発生しました」(exitが0以外であるが、おそらく128
)とが混同するリスクもあります。しかし、0
対1
ゼロ以外の終了コードをチェックすることはおそらくかなり堅牢です:
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
使用できます。