【Git】git diffの–exit-codeとは何か?git diff –staged –exit-codeとの違いを実例で解説|いつ使うのか?(初心者向け、わかりやすい)

git-prograshi(プロぐらし)-kv git/github
記事内に広告が含まれていることがあります。

コミット履歴の管理ツール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」コマンドは実行されていないことがわかります。


&&とは何か?

「&&」はコマンドをつなげるための記述です。以下のようにコマンドをつなげることができます。

コマンド1 && コマンド2 && コマンド3,,,,,

コマンド1の処理を完了したら、コマンド2に移り、コマンド2の処理を終了したら、コマンド3の処理に移り、、、という処理になります。


実例:ステージ前の変更がない場合

上記の状態で、「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」の応用編として、リモートレポジトリの本番用のブランチのコミット番号と、現在のブランチの現在のコミット番号を比較し、ファイルの差分がなければイメージをビルドするといった使い方もできます。

詳細は下記をご参考ください。



タイトルとURLをコピーしました