Risposte:
In genere sono d'accordo con Scytale, con un paio di suggerimenti aggiuntivi, abbastanza da meritare una risposta separata.
Innanzitutto, è necessario scrivere uno script che crei i collegamenti simbolici appropriati, soprattutto se questi hook riguardano l'applicazione della politica o la creazione di notifiche utili. Le persone avranno molte più probabilità di usare gli hook se possono semplicemente digitare bin/create-hook-symlinks
che se devono farlo da soli.
In secondo luogo, i hook di collegamento simbolico diretto impediscono agli utenti di aggiungere i propri hook personali. Ad esempio, mi piace piuttosto l'hook pre-commit di esempio che assicura che non ci siano errori di spazi bianchi. Un ottimo modo per aggirare questo problema è inserire uno script wrapper nel repository e collegare simbolicamente tutti gli hook ad esso. Il wrapper può quindi esaminare $0
(supponendo che sia uno script bash; un equivalente come argv[0]
altrimenti) per capire quale hook è stato invocato come, quindi invocare l'hook appropriato all'interno del repository, nonché l'hook dell'utente appropriato, che dovrà essere rinominato , passando tutti gli argomenti a ciascuno. Esempio rapido dalla memoria:
#!/bin/bash
if [ -x $0.local ]; then
$0.local "$@" || exit $?
fi
if [ -x tracked_hooks/$(basename $0) ]; then
tracked_hooks/$(basename $0) "$@" || exit $?
fi
Lo script di installazione sposta tutti gli hook preesistenti sul lato (aggiungi i .local
loro nomi) e collega simbolicamente tutti i nomi di hook noti allo script precedente:
#!/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
.
No, inserirli nel repository va bene, suggerirei anche di farlo (se sono utili anche per gli altri). L'utente deve abilitarli esplicitamente (come hai detto, ad esempio tramite collegamento simbolico), che da un lato è un po 'una seccatura, ma dall'altro protegge gli utenti dall'esecuzione di codice arbitrario senza il loro consenso.
Al giorno d'oggi è possibile effettuare le seguenti operazioni per impostare una directory che è sotto il controllo di versione per essere la vostra directory di ganci git, per esempio, MY_REPO_DIR/.githooks
sarebbe
git config --local core.hooksPath .githooks/
Ancora non direttamente applicabile ma, se aggiungi una nota nel tuo README (o qualsiasi altra cosa), ciò richiede un minimo sforzo da parte di ogni sviluppatore.
Da http://git-scm.com/docs/git-init#_template_directory , è possibile utilizzare uno di questi meccanismi per aggiornare la directory .git / hooks di ogni repository git appena creato:
La directory del modello contiene file e directory che verranno copiati in $ GIT_DIR dopo la sua creazione.
La directory dei template sarà una delle seguenti (in ordine):
l'argomento fornito con l'opzione --template;
il contenuto della variabile d'ambiente $ GIT_TEMPLATE_DIR;
la variabile di configurazione init.templateDir; o
la directory dei template predefinita: / usr / share / git-core / templates.
Come altri affermano nella loro risposta, se i tuoi hook sono specifici per i tuoi progetti particolari, includili nel progetto stesso, gestito da git. Vorrei proseguire ulteriormente e dire che, dato che è buona prassi far costruire il progetto usando un singolo script o comando, i hook devono essere installati durante la compilazione.
Ho scritto un articolo su gestione degli hook git , se sei interessato a leggere questo argomento in modo un po 'più approfondito.
Dichiarazione di non responsabilità completa; Ho scritto il plugin Maven descritto di seguito.
Se stai gestendo la gestione build con Maven per i tuoi progetti Java, il seguente plug-in Maven gestisce l'installazione di hook da una posizione nel tuo progetto.
https://github.com/rudikershaw/git-build-hook
Metti tutti i tuoi hook Git in una directory nel tuo progetto, quindi configura il tuo pom.xml
per includere la seguente dichiarazione, obiettivo e configurazione del 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 esegui la compilazione del tuo progetto, il plugin configurerà git per eseguire hook dalla directory specificata. Questo imposterà efficacemente gli hook in quella directory per tutti coloro che lavorano al tuo progetto.
Per NPM esiste una dipendenza chiamata Husky che consente di installare hook inclusi quelli scritti in JavaScript.
// package.json
{
"husky": {
"hooks": {
"pre-commit": "npm test",
"pre-push": "npm test",
"...": "..."
}
}
}
Inoltre, ci sono pre-commit per progetti Python, progetti Overcommit per Ruby e progetti Lefthook per Ruby o Node.
Il pacchetto https://www.npmjs.com/package/pre-commit npm gestisce questo elegantemente consentendo di specificare hook pre-commit in package.json.
Ecco uno script, add-git-hook.sh, che puoi spedire come un normale file nel repository e può essere eseguito per aggiungere l'hook git al file di script. Regola quale hook utilizzare (pre-commit, post-commit, pre-push, ecc.) E la definizione di hook nell'eredità del gatto.
#!/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
Questo script potrebbe avere senso avere autorizzazioni eseguibili o l'utente può eseguirlo direttamente. Ho usato questo per git-pull automatico su altre macchine dopo che mi sono impegnato.
EDIT-- Ho risposto alla domanda più semplice che non era quello che era stato chiesto e non era quello che l'OP stava cercando. Ho commentato i casi d'uso e gli argomenti per la spedizione di script hook nel repository rispetto a gestirli esternamente nei commenti qui sotto. Spero che sia quello che stai cercando.
Per i progetti PHP basati su Composer è possibile distribuire automaticamente agli ingegneri. Ecco un esempio di hook pre-commit e commit-msg.
Crea una hooks
cartella, quindi nel tuo composer.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);\"",
],
Quindi puoi anche aggiornarli mentre il progetto continua mentre tutti sono in esecuzione composer install
su base regolare.
È possibile utilizzare una soluzione gestita per la gestione hook pre-commit come pre-commit . O una soluzione centralizzata per git-hooks lato server come Datree.io . Ha politiche integrate come:
Non sostituirà tutti i tuoi hook, ma potrebbe aiutare i tuoi sviluppatori con quelli più ovvi senza l'inferno di configurazione di installare i hook su ogni computer / repository di sviluppatori.
Disclaimer: sono uno dei fondatori di Datrees
chmod +x .git/hooks/*
a tebin/create-hook-symlinks
per farlo funzionare.