Respostas:
Eu geralmente concordo com Scytale, com algumas sugestões adicionais, o suficiente para que valha a pena uma resposta separada.
Primeiro, você deve escrever um script que crie os links simbólicos apropriados, especialmente se esses ganchos forem para impor políticas ou criar notificações úteis. As pessoas terão muito mais probabilidade de usar os ganchos se puderem digitar apenas do bin/create-hook-symlinks
que se tiverem que fazer isso sozinhas.
Segundo, os ganchos de ligação direta impedem que os usuários adicionem seus próprios ganchos pessoais. Por exemplo, eu gosto bastante do gancho de pré-confirmação de amostra, que garante que não haja erros de espaço em branco. Uma ótima maneira de contornar isso é inserir um script de wrapper de gancho em seu repositório e vincular todos os ganchos a ele. O wrapper pode então examinar $0
(supondo que seja um script bash; um equivalente como o argv[0]
contrário) para descobrir em qual gancho ele foi chamado e, em seguida, chamar o gancho apropriado em seu repositório, bem como o gancho do usuário apropriado, que deverá ser renomeado , passando todos os argumentos para cada um. Exemplo rápido da memória:
#!/bin/bash
if [ -x $0.local ]; then
$0.local "$@" || exit $?
fi
if [ -x tracked_hooks/$(basename $0) ]; then
tracked_hooks/$(basename $0) "$@" || exit $?
fi
O script de instalação moveria todos os ganchos preexistentes para o lado (anexado .local
aos nomes) e vincularia todos os nomes de ganchos conhecidos ao script acima:
#!/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
HOOK_DIR=$(git rev-parse --show-toplevel)/.git/hooks
.
Não, colocá-los no repositório é bom, eu até sugiro fazê-lo (se eles também forem úteis para outros). O usuário precisa ativá-los explicitamente (como você disse, por exemplo, por meio de links simbólicos), o que, por um lado, é um pouco trabalhoso, mas protege os usuários, por outro lado, de executar código arbitrário sem o seu consentimento.
Hoje em dia você pode fazer o seguinte para definir um diretório que está sob controle de versão para ser seu diretório ganchos git, por exemplo, MY_REPO_DIR/.githooks
seria
git config --local core.hooksPath .githooks/
Ainda não é diretamente aplicável, mas, se você adicionar uma nota no seu README (ou o que seja), isso requer um mínimo de esforço da parte de cada desenvolvedor.
Em http://git-scm.com/docs/git-init#_template_directory , você pode usar um desses mecanismos para atualizar o diretório .git / hooks de cada repositório git recém-criado:
O diretório do modelo contém arquivos e diretórios que serão copiados para o $ GIT_DIR após a criação.
O diretório do modelo será um dos seguintes (em ordem):
o argumento fornecido com a opção --template;
o conteúdo da variável de ambiente $ GIT_TEMPLATE_DIR;
a variável de configuração init.templateDir; ou
o diretório padrão do modelo: / usr / share / git-core / templates.
Como outros afirmam em sua resposta, se seus ganchos são específicos para seus projetos em particular, inclua-os no próprio projeto, gerenciado pelo git. Eu levaria isso ainda mais longe e diria que, como é uma boa prática ter seu projeto compilado usando um único script ou comando, seus ganchos devem ser instalados durante a compilação.
Eu escrevi um artigo sobre gerenciamento de ganchos Git , se você estiver interessado em ler sobre isso um pouco mais a fundo.
Isenção total; Eu escrevi o plugin Maven descrito abaixo.
Se você estiver lidando com o gerenciamento de compilação com o Maven para seus projetos Java, o seguinte plugin do Maven manipula a instalação de ganchos a partir de um local no seu projeto.
https://github.com/rudikershaw/git-build-hook
Coloque todos os seus ganchos do Git em um diretório do seu projeto e configure-o pom.xml
para incluir a seguinte declaração, objetivo e configuração do plugin.
<build>
<plugins>
<plugin>
<groupId>com.rudikershaw.gitbuildhook</groupId>
<artifactId>git-build-hook-maven-plugin</artifactId>
<configuration>
<gitConfig>
<!-- The location of the directory you are using to store the Git hooks in your project. -->
<core.hooksPath>hooks-directory/</core.hooksPath>
</gitConfig>
</configuration>
<executions>
<execution>
<goals>
<!-- Sets git config specified under configuration > gitConfig. -->
<goal>configure</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- ... etc ... -->
</plugins>
</build>
Quando você executa o projeto, o plugin configura o git para executar hooks fora do diretório especificado. Isso configurará efetivamente os ganchos nesse diretório para todos que trabalham no seu projeto.
Para o NPM, existe uma dependência chamada Husky, que permite instalar ganchos, incluindo os escritos em JavaScript.
// package.json
{
"husky": {
"hooks": {
"pre-commit": "npm test",
"pre-push": "npm test",
"...": "..."
}
}
}
Além disso, há pré-commit para projetos Python, overcommit para projetos Ruby, e Lefthook para Ruby ou projectos nó.
O pacote https://www.npmjs.com/package/pre-commit npm lida com isso de maneira elegante, permitindo que você especifique ganchos de pré-confirmação em seu package.json.
Para projetos PHP baseados no Composer, você pode distribuir automaticamente aos engenheiros. Aqui está um exemplo para ganchos de pré-confirmação e commit-msg.
Crie uma hooks
pasta e, em seguida, no seu compositor.json:
},
"scripts": {
"post-install-cmd": [
"cp -r 'hooks/' '.git/hooks/'",
"php -r \"copy('hooks/pre-commit', '.git/hooks/pre-commit');\"",
"php -r \"copy('hooks/commit-msg', '.git/hooks/commit-msg');\"",
"php -r \"chmod('.git/hooks/pre-commit', 0777);\"",
"php -r \"chmod('.git/hooks/commit-msg', 0777);\"",
],
Em seguida, você pode atualizá-los à medida que o projeto continua, pois todo mundo está executando composer install
regularmente.
Aqui está um script, add-git-hook.sh, que você pode enviar como um arquivo regular no repositório e pode ser executado para anexar o gancho git ao arquivo de script. Ajuste qual gancho usar (pré-confirmação, pós-confirmação, pré-envio, etc.) e a definição do gancho no heredoc do gato.
#!/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
Esse script pode fazer sentido ter permissões executáveis ou o usuário pode executá-lo diretamente. Eu usei isso para puxar automaticamente o git-pull em outras máquinas após o comprometimento.
EDIT-- Respondi à pergunta mais fácil, que não era o que era solicitado e não era o que o OP estava procurando. Eu opinava sobre os casos de uso e os argumentos para enviar scripts de gancho no repositório versus gerenciá-los externamente nos comentários abaixo. Espero que seja mais o que você está procurando.
Você pode usar uma solução gerenciada para gerenciamento de gancho pré-confirmação, como pré-confirmação . Ou uma solução centralizada para ganchos do lado do servidor, como o Datree.io . Possui políticas internas, como:
Ele não substitui todos os seus ganchos, mas pode ajudar seus desenvolvedores com os mais óbvios, sem o inferno de configuração de instalar os ganchos em todos os computadores / repositórios de desenvolvedores.
Disclaimer: Eu sou um dos fundadores da Datrees
chmod +x .git/hooks/*
ao seubin/create-hook-symlinks
para trabalhar.