Gitフック

公開: 2022-07-02

Gitは強力なバージョン管理システムであり、過去数回の投稿で表面をほとんど傷つけていません。 今日は、GitがGitフックで提供できる自動化機能について見ていきます。

git initコマンドを使用すると、すべてのリポジトリにフックが組み込まれます。 リポジトリが初期化されると、非表示の.gitディレクトリが取得され、その中にはすべてのフックを含むフックと呼ばれるディレクトリがあります。 手元にあるgitリポジトリを開き、 ls -aを使用して隠しディレクトリを表示し、お気に入りのコードエディタで開きます。

開始するには、 .sampleファイル拡張子を持つファイルの束が表示されます。 これらはまさに彼らが言うことであり、プロジェクトで使用できるサンプルスクリプトです。 ファイルは、それらが実行されるフックに対応するように名前が付けられています。 したがって、 post-commit.samplepost-commitフックで実行されます。

フックを書くために、ほとんどすべての言語を使用できます。 ファイルは、ファイルの先頭にあるshebang表記に従って解析されます。 ノードを使用したい場合は、 #! /usr/bindi/env nodeを使用します。 #! /usr/bindi/env nodeとファイルはノードファイルとして解析されます。

gitフックで何ができるかを説明する前に、利用可能なフックのいくつかを見てみましょう。

Gitフックの種類

ワークフローフックをコミットする

pre-commitは、コミットメッセージを入力する前に実行され、 git commit --no-verifyでバイパスできます。

prepare-commit-msgを使用して、コミットメッセージに表示されるデフォルトメッセージを編集できます。 これを使用して、開発者が残すべきコミットメッセージのタイプについて指示を出します。 また、マージなど、メッセージが自動的に生成される場所のコンテンツを自動化したり、コミットメッセージに問題番号を自動的に追加したりするためにも使用できます。

commit-msgを使用して、プロジェクトのコミットメッセージを検証できます。 たぶん、「空白を処理する」という単純なコミットメッセージをだれにも入れてほしくないでしょう。 このフックを使用して、空白という単語の存在を検出し、終了して、より適切なコミットメッセージが必要であることをユーザーに警告できます。

post-commitは、上記のすべてのコミットフックの後に実行されます。 コミットが行われたことを通知する場合に最も役立ちます。

クライアントフック

post-checkoutは、gitcheckoutコマンドを正常に実行した後に実行されます。 サイトで大きなファイルのセットを使用しているが、それらをソース管理に使用したくない場合は、このコマンドを使用してファイルを移動できます。

pre-pushは、オブジェクトがリモートリポジトリに転送される前に、gitpushコマンド中に実行されます。

サーバーフック

pre-receiveは、クライアントがコードをリモートリポジトリにプッシュしたときに実行されます。 これを使用して、プッシュされているコードをチェックし、プッシュを受け入れる前に、プロジェクトの基準を満たしていることを確認できます。

post-receiveは、リモートリポジトリが更新を受信した後に実行されます。 これを使用して、展開プロセスをトリガーするWebフックを呼び出したり、コミットが受信されてレビューの準備ができていることをチャットルームに通知したりできます。

上記のフックの多くは、特定のブランチでのみ実行するように設定できます。 これは、誰かがデプロイの準備ができているはずのメインブランチにコードをプッシュした場合にのみ、 post-receiveフックを使用することを意味する場合があります。 開発者のリストに通知して、コードを確認してからデプロイすることができます。 このようにすると、デプロイに常に2つの目を向けることになります。これは、1人の開発者が簡単に見逃す可能性のある間違いを見つけることを意味します。

使用する必要性を見たことがないので、利用可能なフックのいくつかをスキップしました。 私が話さなかったフックの1つのセットは、電子メールワークフローフックです。 電子メールでコードのパッチを受け入れていない場合は、パッチが必要になることはほとんどありません。 利用可能なすべてのフックは、ドキュメントに記載されています。

実際に私が最も使用したフックは次のとおりです。

  • 事前コミット
  • プレプッシュ
  • commit-msg
  • 事前受信
  • コミット後
  • ポストレシーブ

それでは、これらのフックを使って何かをしましょう。

WPCliとGitフックを使用したWordPressプラグインのアクティブ化

今年のあるクライアントプロジェクトでは、ストアを追加し、メインサイトでいくつかのタスクを実行していました。 つまり、メインサイトにはWooCommerceプラグインがインストールまたはアクティブ化されていませんでした。 1つのブランチでWooCommerceストアを開発する必要があり、すべてをライブでプッシュする準備ができて初めて、WooCommerceをメインに移動したいと思いました。

開始するには、storeという新しいブランチが必要です。 これは、git checkout -b storeを使用して取得できます。 これにより、新しいブランチが作成され、チェックアウトされます。 それでは、フックを準備しましょう。

まず、このコマンドtouch .git/hooks/post-checkoutを使用してチェックアウト後のフックを作成する必要があります。

次に、それを実行可能にする必要があります。 これは、ターミナルchmod +x .git/hooks/post-checkoutからchmodコマンドを使用して実行できます。

次に、選択したコードエディタでファイルを開き、以下のコードpost-checkoutファイルにコピーします。

#! /bin/bash

wp plugin activate woocommerce

echo "activated WooCommerce"

wp plugin activate automatewoo

echo "activated AutomateWoo"

ターミナル経由で任意のブランチに変更することで、これをデモできます。 WooCommerceとAutomateWooがアクティブ化されたことを示す2行が表示されます。 動作していることはわかっていますが、ブランチに変更するたびにプラグインがオンになるため、希望どおりではありません。

私たちが本当に望んでいるのは、店舗の支店に移動するときにオンにし、メインの支店にいるときにオフにすることです。 そのためには、自分がどのブランチであるかを検出するためのフックが必要です。 post-checkoutの内容を以下のコードと交換します。

#! /bin/bash

oldrev=$1
newrev=$2

branch_name="(git symbolic-ref HEAD 2>/dev/null)"

if [ "refs/head/store" = "$branch_name" ];then
wp plugin activate woocommerce
echo "activated Woo"

wp plugin activate automatewoo
echo "activated AutomateWoo"
fi

if [ "refs/head/main" = "$branch_name" ];then
wp plugin deactivate woocommerce
echo "deactivated Woo"

wp plugin deactivate automatewoo
echo "deactivated AutomateWoo"
fi

このコードは、チェックアウトするブランチをbranch_name変数に割り当てることから始まります。 次に、2つのifステートメントがあります。 最初に、店舗の支店に移動したかどうかを確認します。 ある場合は、WPCLIを使用してWooCommerceとAutomateWooをアクティブ化します。

次のifステートメントは、メインブランチにいるかどうかを確認します。 もしそうなら、それはWP CLIでプラグインを非アクティブ化し、ターミナルでそれについて教えてくれます。

Gitフックを使用したGitワークフローの制御

Gitに関する以前の投稿で、さまざまなGitワークフローについて話しました。 フックの非常に一般的な使用例の1つは、誰もがコードをメインブランチに直接コミットしないようにすることです。 フックを使用して、すべてのコードが別のブランチからメインにマージされていることを確認できます。

pre-commit.samplepre-commitに変更してから、上記のように実行可能にします。 次に、以下のコードを取得して、pre-commitファイルで使用します。

#! /bin/bash

username=$GIT_AUTHOR_NAME
branch="$(git symbolic-ref HEAD 2>/dev/null)"

if [ "$branch" = "refs/heads/main" ]; then
echo "WHOA that was '"${branch}"' you should not do that. Stop doing silly stuff and create your own branch and merge it."
exit 1 # if you remove this it won't block the commit but it will send the message to slack

fi

これにより、メインブランチにいるかどうかが確認され、メインブランチにいる場合は、コミットが停止されます。 次に、メインブランチに直接コミットしてはならないことをユーザーに通知します。

多くの場所がブランチとしてmainに変更されていることを忘れないでください。 古いプロジェクトが更新されていない場合は、ここにmasterを配置する必要があります。

これをさらに一歩進めて、cURLを使用してチャットアプリのAPIにアクセスし、誰かがメインにコミットしようとしたことを公に不平を言うこともできます。

gitフックの唯一の制限はあなたの想像力です。 それらを使用して、TODOがコードに存在する場合に誰かがコミットするのを停止したり、ファイルの最後に空白を停止したりできます。

継続的な障害であるワークフローの一部がある場合は、それを自動化するためのフックを調べて、覚えておく必要がないようにします。