Помещение мерзавцев в хранилище - PullRequest
180 голосов
/ 12 августа 2010

Считается ли это плохой практикой - помещать .git / hooks в репозиторий проектов (например, используя символические ссылки). Если да, каков наилучший способ доставки одинаковых хуков разным пользователям git?

Ответы [ 8 ]

136 голосов
/ 12 августа 2010

Я в целом согласен с Scytale, с парой дополнительных предложений, достаточно того, что стоит отдельного ответа.

Во-первых, вы должны написать скрипт, который создает соответствующие символические ссылки, особенно если эти ловушки связаны с применением политики или созданием полезных уведомлений. Люди будут гораздо чаще использовать крючки, если они смогут просто набрать bin/create-hook-symlinks, чем если бы им пришлось делать это самостоятельно.

Во-вторых, непосредственно символьные хуки не позволяют пользователям добавлять свои собственные личные хуки. Например, мне скорее нравится пример ловушки перед фиксацией, который гарантирует, что у меня нет ошибок пробелов. Отличный способ обойти это - добавить скрипт репозитория хуков в репозиторий и символическую ссылку 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
106 голосов
/ 12 августа 2010

Нет, помещать их в хранилище - это хорошо, я бы даже предложил сделать это (если они полезны и для других). Пользователь должен явно включить их (как вы сказали, например, с помощью символических ссылок), что, с одной стороны, немного болезненно, но с другой стороны защищает пользователей от запуска произвольного кода без их согласия.

17 голосов
/ 21 января 2019

В настоящее время вы можете сделать следующее, чтобы установить каталог, который находится под управлением версией, в каталог git hooks, например, MY_REPO_DIR/.githooks будет

git config --local core.hooksPath .githooks/

По-прежнему не применяется напрямую, но, если вы добавитепримечание в вашем README (или что-то еще), это требует минимум усилий со стороны каждого разработчика.

5 голосов
/ 15 августа 2015

Из http://git -scm.com / docs / git-init # _template_directory вы можете использовать один из этих механизмов для обновления каталога .git / hooks каждого вновь созданного репозитория git:

Каталог шаблонов содержит файлы и каталоги, которые будут скопированы в $ GIT_DIR после его создания.

Каталог шаблонов будет одним из следующих (по порядку):

  • аргумент, заданный параметром --template;

  • содержимое переменной среды $ GIT_TEMPLATE_DIR;

  • переменная конфигурации init.templateDir;или

  • каталог шаблонов по умолчанию: /usr/share/git-core/templates.

3 голосов
/ 17 октября 2018

Хранить в проекте и устанавливать в сборке

Как другие заявляют в своем ответе, если ваши хуки специфичны для ваших конкретных проектов, включите их в сам проект, управляемый git. Я хотел бы пойти еще дальше и сказать, что, учитывая, что рекомендуется собирать проект с использованием одного скрипта или команды, ваши хуки должны быть установлены во время сборки.

Java & Maven

Полный отказ от ответственности; Я написал плагин Maven, описанный ниже.

Если вы управляете сборкой с помощью 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.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 голосов
/ 26 сентября 2017

Пакет https://www.npmjs.com/package/pre-commit npm обрабатывает это элегантно, позволяя вам указать хуки предварительной фиксации в вашем package.json.

0 голосов
/ 23 марта 2019

Вы можете использовать управляемое решение для управления хуками перед фиксацией, например pre-commit . Или централизованное решение для серверных git-хуков, таких как Datree.io . Он имеет встроенные политики, такие как:

  1. Обнаружение и предотвращение слияния секретов .
  2. Правильно применять Конфигурация пользователя Git .
  3. Принудительно Интеграция с билетом Jira - указать номер билета в имени запроса на получение / сообщении о фиксации.

Он не заменит все ваши хуки, но может помочь вашим разработчикам с наиболее очевидными из них без адской настройки установки хуков на каждом компьютер разработчика / репо.

Отказ от ответственности: я один из основателей Datrees

0 голосов
/ 18 ноября 2018

Вот скрипт add-git-hook.sh, который вы можете отправить как обычный файл в хранилище и который может быть выполнен для добавления ловушки git к файлу скрипта.Отрегулируйте, какой хук использовать (pre-commit, post-commit, pre-push и т. Д.) И определение хука в 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 на других машинах после фиксации.

EDIT-- Я ответил на более простой вопрос, который был не тем, что задавали, и не тем, что искал OP.В комментариях ниже я остановился на сценариях использования и аргументах для доставки скриптов ловушек в репо, а не на внешнем управлении ими.Надеюсь, это было больше, чем вы ищете.

...