首页 文章

将git钩子放入存储库

提问于
浏览
160

它被认为是一种不好的做法 - 将.git / hooks放入项目存储库(例如,使用符号链接) . 如果是的话,为不同的git用户提供相同的钩子的最佳方法是什么?

6 回答

  • 4

    不,将它们放入存储库是好的,我甚至建议这样做(如果它们对其他人也有用) . 用户必须明确启用它们(如您所说,例如通过符号链接),这一方面有点痛苦,但另一方面保护用户在未经他们同意的情况下运行任意代码 .

  • 0

    我通常同意Scytale的一些额外建议,足以让我们单独回答 .

    首先,您应该编写一个脚本来创建适当的符号链接,特别是如果这些挂钩是关于强制执行策略或创建有用的通知 . 如果他们只能输入 bin/create-hook-symlinks ,那么人们将更有可能使用钩子,而不是自己必须这样做 .

    其次,直接符号链接钩子可以防止用户添加自己的个人钩子 . 例如,我更喜欢示例预提交钩子,它确保我没有任何空格错误 . 解决这个问题的一个好方法是在你的repo中放入一个钩子包装器脚本,并将所有挂钩符号链接到它 . 然后包装器可以检查 $0 (假设它是一个bash脚本;另外一个类似于 argv[0] )以找出它被调用的钩子,然后在你的repo中调用适当的钩子,以及相应的用户钩子,这将是必须的重命名,将所有参数传递给每个参数 . 内存中的快速示例:

    #!/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
    
  • 1

    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 .

  • 128

    https://www.npmjs.com/package/pre-commit npm包可以优雅地处理它,允许您在package.json中指定预提交挂钩 .

  • 88

    存储在项目中并在构建中安装

    正如Scy在他的回答中所述,如果您的钩子特定于您的特定项目,我会将它们包含在项目本身中,由git管理 . 我会更进一步说,鉴于使用单个脚本或命令构建项目是一个好习惯,应该在构建期间安装钩子 .

    Java&Maven

    Full disclaimer; I wrote the Maven plugin described below.

    如果您正在使用Maven为Java项目处理构建管理,则以下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.1</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

    这是一个脚本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.
    
    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想要的 . 我讨论了在repo中运送钩子脚本的用例和参数,而不是在下面的注释中对外部管理它们 . 希望这更像你正在寻找的东西 .

相关问题