Os scripts de gancho do Git podem ser gerenciados junto com o repositório?

337

Gostaríamos de criar alguns scripts básicos de gancho que todos possamos compartilhar - para coisas como pré-formatação de mensagens de confirmação. O Git possui scripts de gancho para os quais normalmente são armazenados <project>/.git/hooks/. No entanto, esses scripts não são propagados quando as pessoas fazem um clone e não são controlados por versão.

Existe uma boa maneira de ajudar todos a obter os scripts de gancho certos? Posso apenas fazer esses scripts de gancho apontarem para scripts controlados por versão no meu repositório?

Pat Notz
fonte
5
Uma boa pergunta Eu só gostaria que houvesse uma resposta melhor (sem queixas ao @mipadi, eu gostaria que o git tivesse uma maneira de fazer isso de uma maneira mais automática - mesmo que apenas com uma opção especificada para o git clone.)
lindes
Eu concordo, @lindes! Mas talvez restringindo esse compartilhamento de ganchos intencionalmente? As coisas ficariam confusas para os usuários do Windows, suponho.
precisa saber é o seguinte
@kristianlm: Existem todos os tipos de razões pelas quais pode ser confuso às vezes ... e também quando é bom tê-la lá. Eu só queria que houvesse alguma opção ou algo que copiasse os ganchos. Acho que vou ter que verificar o código do git-core em algum momento e fazer um patch. :) (ou esperança de que alguém o faça ... ou ao vivo com a solução em resposta mipadi de , ou qualquer outra coisa.)
lindes
pre-commitfacilita isso para ganchos de pré-confirmação. Não responde à pergunta do OP sobre o gerenciamento de qualquer gancho git arbitrário, mas os ganchos pré-confirmação são provavelmente os mais usados ​​para fins de qualidade de código.
22617 ericsoco

Respostas:

144

Teoricamente, você pode criar um hooksdiretório (ou o nome que você preferir) no diretório do projeto com todos os scripts e depois vinculá-los .git/hooks. Obviamente, cada pessoa que clonou o repositório teria que configurar esses links simbólicos (embora você possa ser realmente sofisticado e ter um script de implantação que o clonador possa executar para configurá-los de maneira semi-automática).

Para fazer o link simbólico no * nix, tudo o que você precisa fazer é:

root="$(pwd)"
ln -s "$root/hooks" "$root/.git/hooks"

use ln -sfse você estiver pronto para substituir o que está em.git/hooks

mipadi
fonte
38
este foi não-trivial, por isso estou incluindo um link de como ligar simbolicamente corretamente: stackoverflow.com/questions/4592838/...
David T.
17
A versão 2.9 do git agora tem uma opção de configuração para core.hooksPathconfigurar um arquivo fora do .git para vincular à pasta hooks.
Aaron Rabinowitz
216

No Git 2.9 , a opção de configuração core.hooksPathespecifica um diretório de ganchos personalizados.

Mova seus ganchos para um hooksdiretório rastreado em seu repositório. Em seguida, configure cada instância do repositório para usar o rastreado em hooksvez de $GIT_DIR/hooks:

git config core.hooksPath hooks

Em geral, o caminho pode ser absoluto ou relativo ao diretório em que os ganchos são executados (geralmente a raiz da árvore de trabalho; consulte a seção DESCRIÇÃO man githooks).

Max Shenfield
fonte
15
... e o diretório hooks para o qual apontar pode ser um repositório separado de hooks;)
René Link
10
Bem, esse parâmetro de configuração é definido automaticamente quando você faz um clone do git?
Anel
4
Como regra, as variáveis ​​de configuração do git não podem ser definidas pelo repositório que você está clonando. Eu acho que isso é para impedir a execução de código arbitrário. O git config controla a execução do código através de ganchos, o nome do usuário nas mensagens de confirmação e outras funções importantes.
Max Shenfield
1
E se alguém da equipe fizer um check-out git para outro ramo? Eles têm para incluí-lo em todos os ramos ..
jokerster
1
Isso é verdade. Por outro lado, se você atualizar os ganchos em confirmações mais recentes, os repositórios clonados os obterão automaticamente ao trabalhar em ramificações criadas sobre essa confirmação. Ambas as formas têm suas vantagens e desvantagens.
fabb 08/07/19
15

Se o seu projeto é um projeto JavaScript e você usa npmcomo gerenciador de pacotes, pode usar shared-git-hooks para aplicar githooks npm install.

kilianc
fonte
5
Agora eu sei quem é adicionado intrusivamente a porcaria .git/hooks.
gavenkoa
Aviso - não suporta Windows (a menos que seja executado como administrador no git bash). A solução simples é adicionar "preinstall": "git config core.hooksPath hooks" como um script no package.json. ie Onde hooks é uma pasta que contém seus scripts git.
Shane Gannon
8

Para usuários do Nodejs, uma solução simples é atualizar o package.json com

{
  "name": "name",
  "version": "0.0.1",
  ......
  "scripts": {
    "preinstall": "git config core.hooksPath hooks", 

A pré-instalação será executada antes

instalação npm

e redireciona o git para procurar ganchos dentro do diretório. \ hooks (ou qualquer outro nome que você escolher). Este diretório deve imitar . \. Git \ hooks em termos de nome de arquivo (menos a .sample) e estrutura.

Imagine o Maven e outras ferramentas de compilação terão o equivalente à pré-instalação .

Também deve funcionar em todas as plataformas.

Se precisar de mais informações, consulte https://www.viget.com/articles/two-ways-to-share-git-hooks-with-your-team/

Shane Gannon
fonte
5

E quanto ao git-hooks , ele .git/hooksinvoca a rota no script no diretório do projetogithooks .

Também existem muitos recursos para minimizar o gancho de cópia e link simbólico em todo o lugar.

taboa
fonte
5

A maioria das linguagens de programação modernas, ou melhor, suas ferramentas de construção, suporta plugins para gerenciar os ganchos do git. Isso significa que tudo que você precisa fazer é configurar seu package.json, pom.xml etc., e qualquer pessoa em sua equipe não terá outra opção a não ser cumprir, a menos que altere o arquivo de compilação. O plugin adicionará conteúdo ao diretório .git para você.

Exemplos:

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

https://github.com/olukyrich/githook-maven-plugin

https://www.npmjs.com/package/git-hooks

yuranos
fonte
Tentei conseguir isso de uma forma genérica, para usar em meus projetos, então eu escrevi esta ferramenta: pypi.org/project/hooks4git
Lovato
3

Estamos usando soluções do Visual Studio (e, portanto, projetos) que têm eventos de pré e pós-compilação. Estou adicionando um projeto adicional chamado 'GitHookDeployer'. O projeto modifica automaticamente um arquivo no evento pós-construção. Esse arquivo está definido para copiar para o diretório de compilação. Assim, o projeto é construído sempre e nunca é ignorado. No evento de construção, ele também garante que todos os ganchos git estejam no lugar.

Observe que essa não é uma solução geral, pois alguns projetos, é claro, não têm nada para construir.

Mike de Klerk
fonte
2

Você pode usar uma solução gerenciada para gerenciamento de gancho de 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:

  1. Detecte e evite a fusão de segredos .
  2. Aplicar a configuração correta do usuário Git .
  3. Impor a integração do ticket Jira - mencione o número do ticket no nome da solicitação pull / na mensagem de confirmação.

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

Shimon Tolts
fonte
1

Você pode fazer da sua pasta hooks outro repositório git e vinculá-lo como um submódulo ... Acho que vale a pena apenas se você tiver muitos membros e hooks alterados regularmente.

Do-do-new
fonte
1

Idealmente, os ganchos são gravados no bash, se você seguir os arquivos de amostra. Mas você pode escrevê-lo em qualquer idioma disponível e apenas verifique se ele possui o sinalizador executável.

Portanto, você pode escrever um código Python ou Go para atingir seus objetivos e colocá-lo na pasta hooks. Funcionará, mas não será gerenciado junto com o repositório.

Duas opções

a) Scripts múltiplos

Você pode codificar seus ganchos dentro de sua ajuda e adicionar um pequeno fragmento de código aos ganchos, para chamar seu script perfeito, assim:

$ cat .git/hooks/pre-commit
#!/bin/bash
../../hooks/myprecommit.js

b) Script único

Uma opção mais legal é adicionar apenas um script para governar todos eles, em vez de vários. Então, você cria um hooks / mysuperhook.go e aponta todos os hooks que deseja.

$ cat .git/hooks/pre-commit
#!/bin/bash
../../hooks/mysuperhook.go $(basename $0)

O parâmetro fornecerá ao script qual gancho foi acionado e você poderá diferenciá-lo dentro do seu código. Por quê? Às vezes, você pode querer executar a mesma verificação de confirmação e envio, por exemplo.

E depois?

Em seguida, convém ter outras funcionalidades, como:

  • Ative o gancho manualmente para verificar se está tudo bem, mesmo antes de um commit ou push. Se você apenas chamar o seu script (opção a ou b), faria o truque.
  • Acione os ganchos no IC, para que você não precise reescrever as mesmas verificações para o IC, seria apenas chamar os gatilhos de confirmação e envio, por exemplo. O mesmo que o acima deve resolvê-lo.
  • Ligue para ferramentas externas, como um validador de descontos ou um validador YAML. Você pode fazer syscalls e precisa lidar com STDOUT e STDERR.
  • Certifique-se de que todos os desenvolvedores tenham uma maneira simples de instalar os ganchos, para que um bom script precise ser adicionado ao repositório para substituir os ganchos padrão pelos corretos
  • Tenha alguns auxiliares globais, como uma verificação para bloquear confirmações para desenvolver e dominar ramificações, sem precisar adicioná-lo a todos os repositórios. Você pode resolvê-lo tendo outro repositório com scripts globais.

Isso pode ser mais simples?

Sim, existem várias ferramentas para ajudá-lo a gerenciar ganchos. Cada um deles é adaptado para resolver o problema de uma perspectiva diferente, e talvez você precise entender todos eles para obter o melhor para você ou sua equipe. GitHooks.com oferece muita leitura sobre enganchar e várias ferramentas disponíveis hoje.

Atualmente, existem 21 projetos listados lá com diferentes estratégias para gerenciar o Git Hooks. Alguns fazem isso apenas para um único gancho, outros para um idioma específico e assim por diante.

Uma dessas ferramentas, escrita por mim e oferecida gratuitamente como um projeto de código- fonte aberto, é chamada hooks4git . Ele está escrito em Python (porque eu gosto), mas a idéia é manipular todos os itens listados acima em um único arquivo de configuração chamado .hooks4git.ini, que vive dentro do seu repositório e pode chamar qualquer script que você queira chamar, em qualquer idioma .

O uso de ganchos git é absolutamente fantástico, mas a maneira como eles são oferecidos geralmente apenas afasta as pessoas.

Lovato
fonte
Eu havia postado uma versão muito mais curta há um tempo atrás, e como concordado com os moderadores, isso traz uma explicação para ela e um breve link para uma ferramenta que eu mesmo escrevi, que acho que pode ajudar outros desenvolvedores.
Lovato
1

Para usuários graduados

Achei esses scripts muito úteis para projetos gradle.

build.gradle

apply from: rootProject.file('gradle/install-git-hooks.gradle')

gradle / install-git-hooks.gradle

tasks.create(name: 'gitExecutableHooks') {
    doLast {
        Runtime.getRuntime().exec("chmod -R +x .git/hooks/");
    }
}
task installGitHooks(type: Copy) {
    from new File(rootProject.rootDir, 'pre-commit')
    into { new File(rootProject.rootDir, '.git/hooks') }
}
gitExecutableHooks.dependsOn installGitHooks
clean.dependsOn gitExecutableHooks

pré-confirmar

.... your pre commit scripts goes here
a3765910
fonte