Open2

git remoteレポジトリの変更があった場合のみビルドする.

tomozosantomozosan

やるモチベーション

  • リモートの配布用のバイナリにバグ等があって古く、まだ配布されてない最新修正版を定期的にビルドしたい.

GPTさんに教えてもらったやりかた.

#!/bin/bash

# リポジトリのディレクトリに移動
cd /path/to/your/repo

# git fetch と git diff を使用して変更をチェック
git fetch origin main
if git diff --quiet HEAD..origin/main; then
    echo "変更はありません。"
else
    echo "変更を検出。プルとビルドを実行します。"
    # プルして最新の状態にする
    git pull origin main
    # ビルドコマンドを実行
    cargo build --release
fi
tomozosantomozosan

Chat GPTさんに上のスクリプトに関しての疑問を質問

if git diff --quiet HEAD..origin/main

これが何をするのか教えてください.
普通に

git diff --quiet HEAD..origin/main

とうつと変更があろうがなかろうが何も表示されないですよね.

ChatGPT
ご指摘の通り、git diff --quiet HEAD..origin/main コマンドを単独で実行した場合、通常は何も表示されません。これは --quiet オプションが指定されているためで、このオプションは差分の内容を表示せずに、差分の有無のみをステータスコード(終了コード)として返します。

このコマンドの動作は以下のようになります:

差分が存在しない場合:コマンドはステータスコード 0 (成功)を返します。これは、ローカルのHEADとリモートのmainブランチ間に差分がないことを意味します。

差分が存在する場合:コマンドはステータスコード 1 (失敗)を返します。これは、ローカルのHEADとリモートのmainブランチ間に差分が存在することを意味します。

シェルスクリプト内で if git diff --quiet HEAD..origin/main を使用すると、このコマンドの終了ステータスに基づいて条件分岐を行います。つまり、差分がなければ if 文の中身は実行されず、差分がある場合のみ中のコマンド(この例では git pull と cargo build --release)が実行されます。

この方法を使用することで、不要なビルドを避け、効率的にリポジトリの更新を管理することができます。

なるほど git diff --helpを見ると確かに

--exit-code
           Make the program exit with codes similar to diff(1). That is, it exits with 1 if
           there were differences and 0 means no differences.

--quiet
           Disable all output of the program. Implies --exit-code

it exits with 1 if
there were differences and 0 means no differences
.

そんでもってshellスクリプトのif文の評価はexit codeが0の場合は true それ以外はfalseと評価されるという仕様を利用しているのだと納得した.