リポジトリを管理するための5つのシンプルなGitフック

5 Git Hooks 00 Featured Image

Gitは素晴らしいツールです。フックを通じてファイルの変更を追跡するだけでなく、他の人とシームレスにコラボレーションすることも可能です。その点で、GitはFOSSの発展を推進したツールの一つです。

しかし、Gitの最大の問題の一つは、リポジトリを管理するのに時間と労力がかかることです。たとえば、これらのリポジトリをコミットして同期するには、2〜3のgitコマンドが必要です。これにより、管理が面倒になるだけでなく、ユーザーエラーが発生しやすくなります。ここでは、リポジトリをより良く管理するためのいくつかのシンプルで効果的なGitフックを紹介します。

注意: EmacsでもGitを管理できます。方法を学びましょう!

目次

  • Gitフックとは?
    1. マスターへのプッシュを防ぐ
    1. マスターブランチへのプッシュを拒否する
    1. リポジトリをリベースからロックする
    1. コードのスタイルと構文チェックを強制する
    1. リポジトリの変更を自動的にユーザーに通知する
  • よくある質問

Gitフックとは?

基本的に、git-hookは、Gitがリポジトリでアクションを実行するたびに実行されるカスタムスクリプトを作成するために使用できる柔軟なサブコマンドです。たとえば、コミットする前にリポジトリのスタイルエラーを自動的にチェックするためにフックを使用することができます。

5 Git Hooks 02 Example Linter

フックサブコマンドは、リポジトリの「.git」ディレクトリの下にある「hooks」フォルダーを読み取ることによって機能します。このフォルダーには、Gitのすべてのアクションに対して自動化できるサンプルスクリプトを提供するいくつかのプレメイドファイルが含まれています。

5 Git Hooks 03 Default Hooks Directory

ほとんどの場合、任意のスクリプト言語でgitフックを書くことができます。これにより、ソフトウェア開発者にとって非常に柔軟で親しみやすくなります。

ヒント: Gitを始めるには、まずGitのユーザー名とメールを設定する必要があります。このガイドで方法を確認してください。

1. マスターへのプッシュを防ぐ

Gitでユーザーが最もよく犯す間違いの一つは、開発ブランチから直接マスターにコミットをプッシュすることです。これは、Githubを使用してプロジェクトを追跡および管理している場合、非常にイライラすることがあります。

5 Git Hooks 04 Example Git Push

この問題を防ぐために、マスターブランチからリポジトリをプッシュしようとするたびにチェックして確認する「pre-push」Gitフックを作成できます。

  1. 保護したいGitリポジトリに移動します。

5 Git Hooks 05 Cd To Repository

  1. チェックスクリプトを含むGitフックファイルを作成します。これは「push」の前に実行されるフックなので、「pre-push」フックファイルを作成する必要があります:
touch .git/hooks/pre-push
  1. テキストエディタで新しいフックファイルを開きます。
nano .git/hooks/pre-push
  1. 内部に新しい「pre-push」フックを書きます。たとえば、以下はマスターブランチからプッシュする際に確認を求めるスクリプトです:
#!/bin/sh  
  
protect='master'  
current=$(git symbolic-ref HEAD |sed-e's,.*/\(.*\),\1,')  
  
if[$protect = $current]  
then  
read-p"Confirm push to master? Y/n."-n1-r/dev/null  
then  
exit0  
fi  
exit1  
else  
exit0  
fi
  1. 新しいフックを保存します。nanoでは、Ctrl + Oを押してからCtrl + Xを押します。

5 Git Hooks 07 Pre Push Hook Filled

  1. 次のコマンドを実行して、Gitが新しいフックを実行できることを確認します。
chmod +x .git/hooks/pre-push

2. マスターブランチへのプッシュを拒否する

自分がマスターにプッシュするのを防ぐだけでなく、サーバー側のフックを作成して、マスターブランチへのプッシュを拒否することもできます。これは、複数の開発者とリポジトリを共有している場合に非常に便利です。

5 Git Hooks 08 Git Log Sample

これを修正するには、制限されたユーザーがマスターブランチにプッシュするのを自動的に防ぐ「pre-receive」フックを作成します。

  1. リモートリポジトリに「pre-receive」Gitフックファイルを作成します。
touch .git/hooks/pre-receive
  1. このファイルを開きます。
nano .git/hooks/pre-receive
  1. 「pre-receive」フックに拒否スクリプトを追加します。たとえば、以下のコード行はそのまま機能するはずです:
#!/bin/sh  
  
branch=$(git symbolic-ref HEAD |sed-e's,.*/\(.*\),\1,')  
  
blacklist=(alice bob)  
  
if[[${blacklist[*]} =~ $USER]]; then  
if["$branch" == "master"]; then  
echo"You are not allowed commit changes in this branch"  
exit1  
fi  
fi
  1. 新しいフックファイルを保存します。私の場合、Ctrl + Oを押してからCtrl + Xを押してファイルを保存する必要があります。

  2. フックスクリプトを保存し、実行可能にします。

chmod +x .git/hooks/pre-receive

ヒント: Gitの使用をより効率的にするために、Gitエイリアスを使用することもできます。

3. リポジトリをリベースからロックする

Gitでユーザーがよく犯すもう一つの間違いは、現在アクティブなブランチをリベースすることです。これは、複数の貢献者がいるリポジトリで作業している場合、他のユーザーが行ったコミットを削除してしまうため、非常に厄介な問題です。

5 Git Hooks 11 Git Rebase Man Page

この問題を防ぐために、現在のブランチがロックされているかどうかをチェックする「pre-rebase」フックを作成します。

  1. 「.git/hooks」ディレクトリに「pre-rebase」ファイルを作成します:
touch .git/hooks/pre-rebase
  1. このファイルを編集のために開きます。
nano .git/hooks/pre-rebase
  1. 新しいフックファイル内にリベーススクリプトを追加します。
#!/bin/sh  
  
branch="$2"  
[-n"$branch"]||branch=$(git rev-parse--abbrev-ref HEAD)  
lock="branch.${branch}.rebaselock"  
  
if["$(git config --bool "$lock")" = true]; then  
echo"pre-rebase hook: "$lock" is set to true. Refusing to rebase."  
exit1  
fi
  1. 新しいフックファイルを保存し、実行可能にします。
chmod +x .git/hooks/pre-rebase

4. コードのスタイルと構文チェックを強制する

Gitフックの最も役立つ使い方の一つは、コードリンターとリンクさせることです。これは、プロジェクトのスタイルとフォーマットに従っているかどうかをチェックするシンプルなプログラムです。

5 Git Hooks 14 Shellcheck Man Page

  1. Gitリポジトリにリンターをリンクさせるには、まず「pre-commit」フックファイルを作成します。
touch .git/hooks/pre-commit
  1. プロジェクトの言語に適したリンターをインストールします。この場合、私はBashコードを分析するために「shellcheck」を使用しています:
sudo apt install shellcheck
  1. 新しいフックファイルを開き、次のスクリプトを追加します。
#!/bin/bash  
forfilein $(git diff--cached--name-only--diff-filter=AM |grep-E'\.sh$')  
do  
  
shellcheck "$file"# 新しいファイルごとにリンターを実行します。  
  
if[$?-ne0]; then  
exit1# リンターが失敗した場合はコミットを終了します。  
fi  
done
  1. 新しいフックファイルを保存し、実行可能にします:
chmod +x .git/hooks/pre-commit

5. リポジトリの変更を自動的にユーザーに通知する

最後に、リポジトリに新しいコミットがあるたびに自動的にメールを送信するGitフックを作成することもできます。これは、リポジトリのためのシンプルな通知システムを作成したい場合に便利です。

  1. リポジトリの.git/hooksディレクトリに「post-receive」フックファイルを作成します:
touch .git/hooks/post-receive
  1. 新しいGitフックファイルを開き、次のスクリプトを入力します:
#!/bin/sh  
  
commit_message=$(git log-1--pretty=%B)  
users=("[email protected]""[email protected]""[email protected]")  
  
for user in"${users[@]}"; do  
    mail -s"New Commit: $commit_message"$user
  1. 新しいフックファイルを保存し、実行可能にします。
chmod +x .git/hooks/post-receive

よくある質問

GitフックをCのようなコンパイル言語で書くことはできますか?

Gitフックの最大の制限の一つは、ターミナルから直接実行できる言語を使用する必要があることです。これは、Gitフックがスクリプトにコンパイル言語をサポートしていないことを意味します。たとえば、PythonやShellを使用して新しいGitフックを作成できますが、CやC++は使用できません。

同じGitリポジトリで複数のフックを実行することは可能ですか?

はい。上記の例ではフックを単一の離散機能として示していますが、これらを組み合わせて独自のユニークなワークフローを作成することができ、Gitフックは非常に柔軟で適応可能です。たとえば、「マスターへのプッシュを防ぐ」pre-pushフックと「構文チェック」pre-commitフックの両方を自分のリポジトリで使用できます。

EメールGitフックがユーザーにメールを送信しないのはなぜですか?

この問題は、リモートサーバーが適切に外向きのメールを送信できないことが原因である可能性が高いです。これを修正するには、リモートサーバーが安全で、作業中のメール配信エージェントとSMTPドメインを持っていることを確認してください。

画像クレジット: Unsplash。すべての変更とスクリーンショットはRamces Redによるものです。