コミット履歴の管理ツールGitにはファイルの差分を調べるコマンドとして「git diff」が用意されています。
このgit diffのオプションの一つに「–exit-code」があります。
ここでは「git diff –exit-code」と「git diff –staged –exit-code」の違いやそれぞれの処理が何をしているかについてまとめています。
git diff –exit-codeとは何か?
概要
git diff --exit-code
はステージ前(git add前)のファイル差分を確認し、差分がなければ次の処理へと移り、差分があれば処理を強制終了するコマンドです。
git diff --exit-code
解説
「git diff」はステージ(git add)前の変更内容の詳細を表示するコマンドです。(ワークツリーと最新のコミットを比較)
ステージ前とは以下のような状態です。
リモートレポジトリ(Github)
↑ push
ローカルレポジトリ
↑ commit
ステージ(インデックス)
↑ add
作業ツリー(ワークツリー)←ココ
「–exit-code」オプションをつけることで、「git diff」コマンドを実行し、差分がある場合は「git diff」の内容が画面に出力し、処理を強制終了します。
差分がなければ、次の処理に進みます。
実例:ステージ前の変更がある場合
例えば以下のようにgit add前(not staged)の状態のファイル「app/Http/Controllers/UserController.php」があるとします。
$ git status
On branch test
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: app/Http/Controllers/UserController.php
no changes added to commit (use "git add" and/or "git commit -a")
この状態で、git diff --exit-code && git log --oneline
を実行すると次のようになります。
$ $ git diff --exit-code && git log --oneline
diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php
index b754608..49ae5df 100644
--- a/app/Http/Controllers/UserController.php
+++ b/app/Http/Controllers/UserController.php
@@ -1,6 +1,6 @@
<?php
-namespace App\Http\Controllers;
+namespace App\Http\Controllers ;
use Illuminate\Http\Request;
$
git diffの内容が表示され、処理を強制終了します。
「git diff」コマンドの後ろに指定した、「git log」コマンドは実行されていないことがわかります。
実例:ステージ前の変更がない場合
上記の状態で、「app/Http/Controllers/UserController.php」を「git add」してステージの状態にしたとします。
$ git status
On branch test
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: app/Http/Controllers/UserController.php
ステージ前の変更はありません。
この状態で、git diff --exit-code && git log --oneline
を実行すると次のようになります。
$ git diff --exit-code && git log --oneline
d6a2c47 (HEAD -> test, master) [A]UserController
59218ac [A]template header,contents,footer
5c22e8d [A]views > index
「git log –oneline」の内容が表示されていることがわかります。
git diff –staged –exit-codeとは何か?
概要
git diff --staged --exit-code
は、ステージ後(git add後・コミット前)のファイル差分を確認し、差分がなければ次の処理へと移り、差分があれば処理を強制終了するコマンドです。
git diff --staged --exit-code
git diffコマンドの「–staged」と「–exit-code」オプションを併用しています。
–stagedオプションとは何か?
「git diff –staged」はステージ後(git add後・コミット前)の変更内容の詳細を表示するコマンドです。(ステージと最新のコミットを比較)
リモートレポジトリ(Github)
↑ push
ローカルレポジトリ
↑ commit
ステージ(インデックス) ←ココ
↑ add
作業ツリー(ワークツリー)
「–exit-code」オプションをつけることで、「git diff –staged」コマンドを実行し、差分がある場合は「git diff –staged」の内容が画面に出力し、処理を強制終了します。
差分がなければ、次の処理に進みます。
実例:ステージ後・コミット前の変更がある場合
例えば以下のようにgit add後、git commit前(to be committed)の状態のファイル「app/Http/Controllers/UserController.php」があるとします。
$ git status
On branch test
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: app/Http/Controllers/UserController.php
この状態で、git diff --staged --exit-code && git log --oneline
を実行すると次のようになります。
$ git diff --staged --exit-code && git log --oneline
diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php
index b754608..49ae5df 100644
--- a/app/Http/Controllers/UserController.php
+++ b/app/Http/Controllers/UserController.php
@@ -1,6 +1,6 @@
<?php
-namespace App\Http\Controllers;
+namespace App\Http\Controllers ;
use Illuminate\Http\Request;
$
「git diff –staged」の内容が表示され、処理を強制終了しています。
「git diff」コマンドの後ろに指定した、「git log」コマンドは実行されていないことがわかります。
実例:ステージの変更がない場合
上記の状態で、「app/Http/Controllers/UserController.php」を「git commit」してステージを空にしたとします。
$ git status
On branch test
nothing to commit, working tree clean
Gitはクリーンな状態です。
この状態で、git diff --staged --exit-code && git log --oneline
を実行すると次のようになります。
$ git diff --staged --exit-code && git log --oneline
86b6bd7 (HEAD -> test) [F]UserController minar fix
d6a2c47 (master) [A]UserController
59218ac [A]template header,contents,footer
5c22e8d [A]views > index
「git log –oneline」の内容が表示されていることがわかります。
実例:ステージ前の変更がある場合
なお、以下のようにgit add前のステージの状態のファイル「app/Http/Controllers/UserController.php」があるとします。
$ git status
On branch test
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: app/Http/Controllers/UserController.php
no changes added to commit (use "git add" and/or "git commit -a")
この状態で、git diff --staged --exit-code && git log --oneline
を実行すると次のようになります。
$ git diff --exit-code && git log --oneline
86b6bd7 (HEAD -> test) [F]UserController minar fix
d6a2c47 (master) [A]UserController
59218ac [A]template header,contents,footer
5c22e8d [A]views > index
「git log –oneline」の内容が表示されていることがわかります。
「git diff –staged」はあくまで、ステージと最新のコミットとの変更状態を比較するものなので、ワーキングツリー(git add前)に変更があっても、その差分は無視します。
–exit-codeはいつ使うのか?
git diffのオプション「–exit-code」はいつ使うのか?というと、複数のコマンドをつなげて処理を自動化させたい場合につかいます。
例えば、Dockerでビルドを実行しイメージを作成するときに、変更がコミットされていない状態でビルドをしてしまうというミスが発生することがあります。
git diffの「–exit-code」を使えば、このポカミスを防ぐ処理を記述することができます。
例えば以下のような使い方です。
alias build-image=check-build-image
function check-build-image() {
echo 'git diffで確認します。修正中でコミット前のファイルがある場合はビルドできません。';
git diff --exit-code && \
git diff --staged --exit-code && \
docker-compose build prd
}
「git diff –exit-code」と「git diff –staged –exit-code」をそれぞれ実行し、変更内容が残っていなければ、「docker-compose build prd」を実行する処理となります。
参考
「git diff –exit-code」と「git diff –staged –exit-code」の応用編として、リモートレポジトリの本番用のブランチのコミット番号と、現在のブランチの現在のコミット番号を比較し、ファイルの差分がなければイメージをビルドするといった使い方もできます。
詳細は下記をご参考ください。