Back

Git Pre-Commitフックによるコード検査の自動化

Git Pre-Commitフックによるコード検査の自動化

すべての開発者は、コードをプッシュした後にCI/CDパイプラインがフォーマットエラーやリンティングエラーで失敗する悔しさを知っています。これらの問題がリポジトリに到達する前に検出できるとしたらどうでしょうか?Git pre-commitフックは、自動検査をローカルで実行する強力なソリューションを提供し、時間を節約し、チーム全体で一貫したコード品質を維持します。

この記事では、pre-commitフレームワークを使用したgit pre-commitフックの設定方法、ESLint、Prettier、Blackなどの重要なツールの設定、そして開発ワークフローをスムーズかつ効率的に保つベストプラクティスの実装について説明します。

重要なポイント

  • Git pre-commitフックはコミット前に自動検査を実行し、一般的な問題がリポジトリに到達することを防ぎます
  • pre-commitフレームワークは、YAML設定と言語に依存しないサポートによりフック管理を簡素化します
  • 速度の最適化と段階的な導入は、チームの受け入れにとって重要です
  • HuskyやLefthookなどの代替ツールは、特定のニーズに対して異なるアプローチを提供します

Git Pre-Commitフックとは?

Gitフックは、コミット、プッシュ、受信などのイベントの前後にGitが実行するスクリプトです。git pre-commitフックは、変更をステージした後、Gitがコミットを作成する前に実行されます。フックが非ゼロステータスで終了した場合、Gitはコミットを中止し、最初に問題を修正する機会を与えます。

.git/hooks/内でフックを単純なシェルスクリプトとして記述することもできますが、プロジェクトが成長するにつれて管理が複雑になります。ここでpre-commitフレームワークが輝きます—チーム間でフックを管理し共有するための標準化された方法を提供します。

Pre-Commitフレームワークを使用する理由

pre-commitフレームワークは、ネイティブGitフックのいくつかの問題点を解決します:

  • 簡単なインストールと更新: フックはバージョン管理され、シンプルなYAML設定を通じてインストールされます
  • 言語に依存しない: 一つの設定からPythonリンター、JavaScriptフォーマッター、シェルスクリプトを実行できます
  • 選択的実行: フックは変更されたファイルのみで実行され、コミットを高速に保ちます
  • チームの一貫性: 同じ.pre-commit-config.yamlファイルをチーム全体で共有できます

プロジェクトでのPre-Commitの設定

まず、pre-commitパッケージをインストールします:

pip install pre-commit

プロジェクトルートに.pre-commit-config.yamlファイルを作成します。以下は一般的なニーズをカバーする実用的な設定です:

repos:
  # 基本的なファイル修正
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v4.5.0
    hooks:
      - id: trailing-whitespace
      - id: end-of-file-fixer
      - id: check-yaml
      - id: check-added-large-files

  # BlackによるPythonフォーマット
  - repo: https://github.com/psf/black
    rev: 24.2.0
    hooks:
      - id: black
        files: \.py$

  # MypyによるPython型チェック
  - repo: https://github.com/pre-commit/mirrors-mypy
    rev: v1.8.0
    hooks:
      - id: mypy
        additional_dependencies: [types-all]
        files: \.py$

  # PrettierによるJavaScript/TypeScript
  - repo: https://github.com/pre-commit/mirrors-prettier
    rev: v3.1.0
    hooks:
      - id: prettier
        files: \.(js|jsx|ts|tsx|json|css|md)$

  # ESLintによるJavaScript/TypeScriptリンティング
  - repo: https://github.com/pre-commit/mirrors-eslint
    rev: v8.56.0
    hooks:
      - id: eslint
        files: \.(js|jsx|ts|tsx)$
        additional_dependencies:
          - eslint-config-standard
          - eslint-plugin-react

  # プロジェクトテストの実行
  - repo: local
    hooks:
      - id: pytest
        name: pytest
        entry: pytest
        language: system
        pass_filenames: false
        always_run: true

gitフックをインストールします:

pre-commit install

これで、フックは毎回のコミット時に自動的に実行されます。すべてのファイルで手動実行するには:

pre-commit run --all-files

フックのパフォーマンス最適化

速度が重要です—遅いフックは開発者の頻繁なコミットを妨げます。以下のプラクティスに従ってください:

ステージされたファイルのみでフックを実行: pre-commitフレームワークはデフォルトでこれを行いますが、カスタムフックがこのパターンを尊重することを確認してください。

高速なツールを使用: 速度が重要な場合、PythonではFlake8の代わりにRuffを、JavaScriptではESLintの代わりにBiomeを選択してください。

ローカルでは高コストな検査をスキップ: 包括的なテストスイートはCI/CDに任せます。ローカルフックはフォーマットや基本的なリンティングなどの迅速な成果に焦点を当てるべきです。

可能な場合は並列化: 一部のツールは並列実行をサポートしています。例えば、pytestはpytest-xdistでテストを並列実行できます。

チーム導入のベストプラクティス

チームにpre-commitフックを導入してもらうには、慎重な実装が必要です:

小さく始める: 末尾の空白除去などの非侵入的なフックから始めます。より厳格な検査は段階的に追加します。

設定を文書化: READMEにインストール手順を含めます。オンボーディングプロセスの一部にします。

環境の違いに対処: 可能な限り言語に依存しないフックを使用します。言語固有のツールについては、.pre-commit-config.yamlで互換性のあるバージョンを指定することを確認してください。

回避手段を提供: 時々開発者はフックをバイパスする必要があります。--no-verifyフラグはすべてのフックをスキップします:

git commit --no-verify -m "Emergency fix"

これは控えめに使用し、適切な場合を文書化してください。

代替アプローチ

pre-commitが最も人気のあるフレームワークですが、代替手段も存在します:

Husky: JavaScriptプロジェクトで人気があり、npmスクリプトとよく統合されます。

ネイティブGitフック: .git/hooks/内の直接的なシェルスクリプトは最大限の制御を提供しますが、移植性に欠けます。

Lefthook: 並列実行サポートを持つ高速でクロスプラットフォームな代替手段。

ほとんどのチームにとって、pre-commitは機能、パフォーマンス、エコシステムサポートの最良のバランスを提供します。

よくある落とし穴と解決策

CIでのフック失敗: CI環境に必要なすべての依存関係がインストールされていることを確認してください。CIステップとしてpre-commit run --all-filesの実行を検討してください。

プラットフォーム固有の問題: チームが使用するすべてのプラットフォームでフックをテストしてください。必要に応じて一貫した環境のためにDockerを使用してください。

設定ファイルでのマージコンフリクト: .pre-commit-config.yamlの変更を最小限かつアトミックに保ってください。フックバージョンの更新は別のコミットで行ってください。

まとめ

Git pre-commitフックは、コード品質を反応的なプロセスから予防的なプロセスに変換します。問題がリポジトリに入る前に検出することで、時間を節約し、コンテキストスイッチングを減らし、コードベース全体でより高い基準を維持できます。基本的なフォーマットフックから始め、段階的にリンターや型チェッカーを追加し、チームのワークフローをスムーズに保つために常に速度を優先してください。

成功した導入の鍵は、徹底性と開発者体験のバランスを取ることにあります。即座に価値を提供する高速で焦点を絞ったフックは、チームのワークフローの不可欠な部分となるでしょう。

FAQ

はい、pre-commitはモノレポに優れています。異なるファイルパターンやディレクトリに対して異なるフックを設定できます。設定でfilesとexcludeキーを使用して、リポジトリ内の特定の言語やフォルダーをターゲットにしてください。

pre-commitと併せてnvmやpyenvなどの言語バージョンマネージャーを使用してください。または、フック設定でlanguage_versionを指定するか、Dockerベースのフックを使用してすべての開発者のマシン間で一貫した環境を確保してください。

pre-commitがインストールされていない場合、フックはローカルで実行されませんが、コードは引き続きコミットされます。標準を強制するために、CI パイプラインでpre-commit検査をセーフティネットとして実行し、pre-commitのインストールをプロジェクトセットアップドキュメントの一部にしてください。

Gain control over your UX

See how users are using your site as if you were sitting next to them, learn and iterate faster with OpenReplay. — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.

OpenReplay