web-dev-qa-db-ja.com

リポジトリにgitフックを置く

.git/hooksをプロジェクトリポジトリに配置する(たとえば、シンボリックリンクを使用する)のは悪い習慣と見なされていますか?はいの場合、異なるgitユーザーに同じフックを提供する最良の方法は何ですか?

182
shabunc

私は通常、Scytaleに同意しますが、いくつかの追加の提案がありますが、別の回答に値するほどです。

最初に、適切なシンボリックリンクを作成するスクリプトを作成する必要があります。特に、これらのフックがポリシーの実施や有用な通知の作成に関するものである場合はそうです。フックを使用する可能性は、自分で行う必要がある場合よりもbin/create-hook-symlinksを入力するだけの場合の方がはるかに多くなります。

第二に、フックを直接シンボリックリンクすると、ユーザーが自分の個人的なフックを追加できなくなります。たとえば、ホワイトスペースエラーがないことを確認するサンプルのpre-commitフックが好きです。これを回避する素晴らしい方法は、リポジトリにフックラッパースクリプトをドロップし、それへのフックのシンボリックリンクallをドロップすることです。その後、ラッパーは$0(bashスクリプトであると仮定します。それ以外の場合はargv[0]に相当)が呼び出されたフックを特定し、リポジトリ内の適切なフックを呼び出します。適切なユーザーのフック。名前を変更して、それぞれにすべての引数を渡す必要があります。メモリからの簡単な例:

#!/bin/bash
if [ -x $0.local ]; then
    $0.local "$@" || exit $?
fi
if [ -x tracked_hooks/$(basename $0) ]; then
    tracked_hooks/$(basename $0) "$@" || exit $?
fi

インストールスクリプトは、既存のすべてのフックをサイドに移動し(名前に.localを追加)、既知のすべてのフック名を上記のスクリプトにシンボリックリンクします。

#!/bin/bash
HOOK_NAMES="applypatch-msg pre-applypatch post-applypatch pre-commit prepare-commit-msg commit-msg post-commit pre-rebase post-checkout post-merge pre-receive update post-receive post-update pre-auto-gc"
# assuming the script is in a bin directory, one level into the repo
HOOK_DIR=$(git rev-parse --show-toplevel)/.git/hooks

for hook in $HOOK_NAMES; do
    # If the hook already exists, is executable, and is not a symlink
    if [ ! -h $HOOK_DIR/$hook -a -x $HOOK_DIR/$hook ]; then
        mv $HOOK_DIR/$hook $HOOK_DIR/$hook.local
    fi
    # create the symlink, overwriting the file if it exists
    # probably the only way this would happen is if you're using an old version of git
    # -- back when the sample hooks were not executable, instead of being named ____.sample
    ln -s -f ../../bin/hooks-wrapper $HOOK_DIR/$hook
done
137
Cascabel

いいえ、それらをリポジトリに入れることは問題ありません。そうすることをお勧めします(他の人にも役立つ場合)。ユーザーは明示的に有効にする必要があります(シンボリックリンクなどで言ったように)。これは一方では少し苦痛ですが、一方でユーザーの同意なしに任意のコードを実行することからユーザーを保護します。

107
scy

現在、バージョン管理下にあるディレクトリをgit hooksディレクトリに設定するために次のことができます。例えば、MY_REPO_DIR/.githooks

git config --local core.hooksPath .githooks/

それでも直接強制力はありませんが、README(またはその他)にメモを追加する場合、各開発者側で最小限の労力が必要です。

23
bbarker

http://git-scm.com/docs/git-init#_template_directory から、これらのメカニズムのいずれかを使用して、新しく作成された各gitリポジトリの.git/hooksディレクトリを更新できます。

テンプレートディレクトリには、作成後に$ GIT_DIRにコピーされるファイルとディレクトリが含まれます。

テンプレートディレクトリは、次のいずれかになります(順序どおり)。

  • --templateオプションで指定された引数。

  • $ GIT_TEMPLATE_DIR環境変数の内容。

  • init.templateDir構成変数。または

  • デフォルトのテンプレートディレクトリ:/ usr/share/git-core/templates。

5
DavidN

プロジェクトに保存してビルドにインストールする

他の人が答えで述べているように、フックが特定のプロジェクトに固有の場合は、gitで管理されているプロジェクト自体にフックを含めます。これをさらに進めて、単一のスクリプトまたはコマンドを使用してプロジェクトをビルドすることをお勧めすることを考えると、ビルド中にフックをインストールする必要があります。

JavaとMav​​en

完全な免責事項;以下に説明するMavenプラグインを作成しました。

Javaプロジェクトに対してMavenでビルド管理を処理している場合、次のMavenプラグインがプロジェクト内の場所からのフックのインストールを処理します。

https://github.com/rudikershaw/git-build-hook

<build>
  <plugins>
    <plugin>
      <groupId>com.rudikershaw.gitbuildhook</groupId>
      <artifactId>git-build-hook-maven-plugin</artifactId>
      <version>2.0.2</version>
      <configuration>
        <!-- The locations of a variety of different hooks to install in the local project. -->
        <preCommit>path/to/hook.sh</preCommit>
      </configuration>
      <executions>
        <execution>
          <goals>
            <!-- Inititalise a Git repository if one does not already exist. -->
            <goal>initialize</goal>          
            <!-- Install Git hooks. -->
            <goal>install</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  <!-- ... etc ... -->
  </plugins>
</build>

JavaScriptとNPM

NPMには Husky と呼ばれる依存関係があり、JavaScriptで作成されたものを含むフックをインストールできます。

// package.json
{
  "husky": {
    "hooks": {
      "pre-commit": "npm test",
      "pre-Push": "npm test",
      "...": "..."
    }
  }
}
3
Rudi Kershaw

https://www.npmjs.com/package/pre-commit npmパッケージはこれをエレガントに処理し、package.jsonで事前コミットフックを指定できるようにします。

3
Greg Magolan

pre-commit のようなプリコミットフック管理にマネージドソリューションを使用できます。または、 Datree.io のようなサーバー側git-hooksの集中ソリューション。次のような組み込みポリシーがあります。

  1. シークレットのマージ を検出して防止します。
  2. 適切な強制 Gitユーザー設定
  3. 強制 Jiraチケット統合 -プルリクエスト名/コミットメッセージにチケット番号を記載します。

すべてのフックを置き換えるわけではありませんが、すべての開発者のコ​​ンピューター/レポにフックをインストールするという設定の地獄なしに、最も明白なもので開発者を助けるかもしれません。

免責事項:私はDatreesの創設者の一人です

0
Shimon Tolts

スクリプトはadd-git-hook.shです。これは、リポジトリ内の通常のファイルとして出荷でき、実行してスクリプトファイルにgitフックを追加できます。使用するフック(事前コミット、事後コミット、事前プッシュなど)およびcat heredocのフックの定義を調整します。

#!/usr/bin/bash
# Adds the git-hook described below. Appends to the hook file
# if it already exists or creates the file if it does not.
# Note: CWD must be inside target repository

HOOK_DIR=$(git rev-parse --show-toplevel)/.git/hooks
HOOK_FILE="$HOOK_DIR"/post-commit

# Create script file if doesn't exist
if [ ! -e "$HOOK_FILE" ] ; then
        echo '#!/usr/bin/bash' >> "$HOOK_FILE"
        chmod 700 "$HOOK_FILE"
fi

# Append hook code into script
cat >> "$HOOK_FILE" <<EOF

########################################
# ... post-commit hook script here ... #
########################################

EOF

このスクリプトは、実行可能権限を持っているか、ユーザーが直接実行できる場合があります。これを使用して、コミット後に他のマシンで自動的にgit-pullを実行しました。

編集-私は簡単な質問に答えましたが、それは尋ねられたものではなく、OPが探していたものではありませんでした。リポジトリでフックスクリプトを配布する場合と、外部で管理する場合のユースケースと引数については、以下のコメントで意見を述べました。それがあなたが探しているものであったことを願っています。

0
mathewguest