Git作業ディレクトリを宛先としてrsync
を実行するスクリプトがあります。作業ディレクトリがクリーン(コミットする変更がない)かどうかに応じて、スクリプトに異なる動作をさせたい。たとえば、git status
の出力が以下の場合、スクリプトを終了させます。
git status
Already up-to-date.
# On branch master
nothing to commit (working directory clean)
Everything up-to-date
ディレクトリがクリーンでない場合は、さらにいくつかのコマンドを実行してください。
上記のような出力をシェルスクリプトで確認するにはどうすればよいですか?
git status
の出力を解析することは悪い考えです。出力は人間が読み取れるように意図されており、機械が読み取れるようには意図されていないからです。 Gitの将来のバージョンまたは異なる構成の環境で出力が同じままである保証はありません。
VVのコメント は正しい方向にありますが、コミットされていない変更がある場合、残念ながらgit status
の戻りコードは変更されません。ただし、これは --porcelain
オプションを提供します。これにより、git status --porcelain
の出力がスクリプト用に解析しやすい形式にフォーマットされますandは、ユーザー設定に関係なく、Gitバージョン全体で安定した状態を保ちます。
git status --porcelain
の空の出力を、コミットする変更がないことを示すインジケータとして使用できます。
if [ -z "$(git status --porcelain)" ]; then
# Working directory clean
else
# Uncommitted changes
fi
作業ディレクトリ内の追跡されていないファイルを気にしない場合は、 --untracked-files=no
オプションを使用してそれらを無視できます。
if [ -z "$(git status --untracked-files=no --porcelain)" ]; then
# Working directory clean excluding untracked files
else
# Uncommitted changes in tracked files
fi
実際に_git status
がstdout
への出力なしに失敗する条件に対してこれをより堅牢にするために、チェックを調整できますに:
if output=$(git status --porcelain) && [ -z "$output" ]; then
# Working directory clean
else
# Uncommitted changes
fi
注目に値することですが、git status
は作業ディレクトリが汚れていると意味のある終了コードを提供しませんが、git diff
は --exit-code
オプションを提供します。 diff ユーティリティに似ています。つまり、違いがあった場合は1
、何も見つからなかった場合は0
で終了します。
これを使用して、ステージングされていない変更を次のように確認できます。
git diff --exit-code
ステージングされたが、コミットされていない変更:
git diff --cached --exit-code
git diff
は --ignore-submodules
への適切な引数を介してサブモジュールの追跡されていないファイルについてレポートできますが、残念ながら実際の作業ディレクトリで追跡されていないファイルについてレポートする方法はないようです。作業ディレクトリ内の追跡されていないファイルが関連している場合は、git status --porcelain
がおそらく最善の策です。
使用する:
git diff-index --quiet HEAD
戻りコードは、作業ディレクトリーの状態を反映しています(0 =クリーン、1 =ダーティー)。追跡されていないファイルは無視されます。
この種のテストをしました
TEST=$(git status --porcelain|wc -l)
if [ 0 -eq $TEST ]; then
echo "No changes"
else
echo "Changes"
fi
#!/bin/bash
echo "First arg: $1"
cd $1
bob="Already up-to-date."
echo $bob
echo $(git pull) > s.txt
cat s.txt
if [ "$(cat s.txt)" == "$bob" ]
then
echo "up"
else
echo "not up"
fi
rm -rf s.txt