壊れた変更を、共有する前に止める
売店が、価格をファイルに書いています。だれかがお茶の価格を間違えて消し、push しました。これで、チーム全員の一覧が壊れます。
push のときに動くチェックがあれば、止められました。現場のチームは、一日中こういうチェックを使っています。
このレッスンのゴール
メモ
push が通る前に、Git にチェックを動かさせることができる。
大事な言葉
| ことば | いみ |
|---|---|
| フック | 決まった場面で Git が動かすスクリプト(hook) |
| チェック | 成功か失敗かを返す確認 |
| 終了ステータス | プログラムが終わるときの数字。0 が成功 |
| CI | push のたびにチェックを動かすサーバー |
| ランナー | CI の仕事を実際に動かすマシン(runner) |
学生が入力するセルは、このプレビューでは空白です。
フックは Git が動かすスクリプト
Git は、.git/hooks フォルダの中で、決まった名前のスクリプトを探します。pre-push という名前のスクリプトは、push の直前に動きます。終了ステータスが 0 以外で終わると、Git は push を止めます。
スクリプトは実行できる必要があります。ここでは、チェックが prices.txt の中にお茶の価格を探します。
push 先の共有フォルダを作る
git init --bare -b main shared.gitここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
stall という名前で clone する
git clone shared.git stallここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
2つの価格のファイルを作る
printf 'コーヒー 300\nお茶 200\n' > stall/prices.txtここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
チェックを書く
printf '#!/bin/sh\ngrep -q "お茶" prices.txt || { echo "チェック失敗: お茶の価格がありません"; exit 1; }\necho "チェック成功"\n' > stall/.git/hooks/pre-pushここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
チェックを実行できるようにする
chmod +x stall/.git/hooks/pre-pushここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
ファイルをステージする
git -C stall add prices.txtここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
コミットする
git -C stall commit -m "価格を追加"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
push して、チェックが動くのを見る
git -C stall push -u origin mainここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
失敗するチェックは push を断る
では、わざとファイルを壊します。お茶の行を消して、コミットします。チェックは失敗し、Git は push を断ります。壊れたコミットは、手元のパソコンに残ります。
そのあと、レッスン6で見た git revert で悪いコミットを取り消し、もう一度 push します。
お茶の行を消す
sed -i '/お茶/d' stall/prices.txtここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
間違いをコミットする
git -C stall commit -am "お茶を間違えて消す"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
push してみる
git -C stall pushここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
間違いを取り消す
git -C stall revert --no-edit HEADここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
もう一度 push する
git -C stall pushここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
よくある間違い
注意
フックはプロジェクトの一部で、チーム全員が持つと思いがちです。持ちません。フックは .git にあり、clone ではコピーされません。--no-verify で飛ばすこともできます。チームには、サーバーで動く同じチェックが要ります。
CI は同じチェックをサーバーで動かす
CI は継続的インテグレーションの略です。push のたびにチェックを動かすサーバーのことです。手順は、リポジトリに置いたファイルに書くので、clone した全員が同じ規則を持ちます。
Gitea では、そのファイルを .gitea/workflows に置きます。サーバーは、仕事をランナーに渡します。結果はプルリクエストに出るので、レビューする人はすぐ失敗に気づけます。
例で見る: ワークフローのファイル
| ファイルの行 | 意味 |
|---|---|
| `name: check` | ページに出る名前 |
| `on: [push]` | push のたびに動く |
| `runs-on: ubuntu-latest` | 使うマシンの種類 |
| `- uses: actions/checkout@v4` | まずプロジェクトのファイルを取ってくる |
| `- run: grep -q お茶 prices.txt` | チェック本体。フックと同じ確認 |
学生が入力するセルは、このプレビューでは空白です。
ラボの Gitea にはランナーがない
このファイルは、フックと同じ仕事をします。手順は順に動き、0 以外で終わった手順は、仕事を失敗させます。
ラボの Gitea は、このファイルを受け付け、push のたびに実行を1つ記録しますが、実行は待ちのままです。ランナーがつながっていないので、だれも動かしません。現場のチームは、ランナーをつなぎます。