Collegamento simbolico a un hook in git


86

Ho scritto il mio hook post-unione personalizzato, ora ho aggiunto una directory "hooks" alla cartella del mio progetto principale (poiché git non tiene traccia delle modifiche in .git / hooks), da qualche parte ho letto che posso creare un collegamento simbolico dagli hook a .git / hooks quindi non devo copiare il file da una cartella all'altra ogni volta che qualcuno lo cambia, quindi ho provato:

ln -s -f hooks/post-merge .git/hooks/post-merge

Ma non sembra funzionare, qualche idea perché? "ln hooks / post-merge .git / hooks / post-merge" funziona bene ma fare un hard link è lo stesso di copyin immagino ....


22
Perché il collegamento simbolico viene risolto rispetto alla sua posizione. Viene risolto un collegamento simbolico .git/hooks/che punta hooks/post-mergea .git/hooks/hooks/post-merge, che non esiste. Tu vuoi ln -s -f ../../hooks/post-merge .git/hooks/post-merge. O rendere la vita più facile: ln -s -f ../hooks .git/hooks. Il tuo problema non ha nulla a che fare con git.
Aristotele Pagaltzis

1
stackoverflow.com/questions/3462955/… e stackoverflow.com/questions/427207/… (e stackoverflow.com/questions/3703159/… ) sottolineano il fatto che il collegamento simbolico può funzionare.
VonC

Correggimi se sbaglio, ma deve ancora essere configurato un Symlink per workstation. L'unica cosa che questo salva, è copiarlo manualmente o scrivere un altro comando che copia il file hook tracciato in .git/hooks.
adi518

Risposte:


161

hai appena usato un percorso sbagliato, dovrebbe essere:

ln -s -f ../../hooks/post-merge .git/hooks/post-merge

10
Non capisco perché ho bisogno di salire di due directory per collegare una risorsa che risiede nella cartella in cui sono cdentrato. Non dovrebbe essere solo ln -s ./hooks/?
Droogans

45
Questo. Quando git valuta il collegamento simbolico, apparentemente lo fa usando .git/hookscome directory di lavoro, quindi i percorsi relativi dovrebbero essere relativi a quella directory. Questo è più auto-esplicativo se prima cdnella .git/hooksprima di fare il link simbolico, e capire il percorso relativo da lì.
Eliot

12
@Eliot né la creazione né la risoluzione dei collegamenti simbolici è influenzata dalla directory di lavoro. Qualunque cosa tu dia lnverrà memorizzata come destinazione e risolta in relazione alla posizione del collegamento.
Joó Ádám

2
@ JoóÁdám Hai ragione. Quindi il problema qui è che il comando originale specifica un percorso relativo errato. Tuttavia, cdinserire .git/hooksprima di creare il collegamento ti aiuterà a scrivere il comando, poiché puoi quindi completare automaticamente il percorso corretto.
Eliot

1
Tutto questo ha funzionato per me alla fine. L'unica differenza è che mi collego al mio prepare-commit-msg. Il problema è che se sto modificando il messaggio di commit usando nano, quindi Ctl + X out per interrompere, git completa comunque un commit invece di interromperlo come una volta prima di apportare questa modifica. C'è un modo per avere l'uscita nano senza causare il completamento di questo commit?
frakman1

15

Sebbene sia possibile utilizzare collegamenti simbolici, è anche possibile modificare la cartella hook per il progetto nelle impostazioni di git con:

git config core.hooksPath hooks/

Che è locale per impostazione predefinita, quindi non rovinerà gli hook git per gli altri progetti. Funziona per tutti gli hook in questo repository, quindi è particolarmente utile se hai più di un hook.

Se disponi già di hook personalizzati .git/hooks/che non desideri condividere con il tuo team, puoi aggiungerli negli hook / e aggiungere un in .gitignoremodo che non siano condivisi.


Molto bella! Un trucco utile :) Sembra molto più a prova di futuro rispetto al collegamento simbolico uno per uno.
jkp

2

Modifica della directory prima del collegamento

cd /path/to/project-repo/.git/hooks
ln -s -f ../../hooks/post-merge ./post-merge

Ancora più semplice, dopo il cd:ln -s -f ../../hooks/post-merge
jamesdlin

0

Il calcolo del percorso viene eseguito in relazione al collegamento simbolico. Comprendiamo usando un esempio,

ln -s path/to/file symlink/file

Qui, il percorso del file dovrebbe effettivamente essere il percorso relativo dal percorso del collegamento simbolico.
Il sistema calcola effettivamente il percorso del file come symlink/path/path/to/file
Il comando precedente dovrebbe essere riscritto come

ln -s ../path/to/file symlink/path

La struttura della cartella è,

/ code
------ collegamento simbolico / file
------ percorso / a / file


0

Utilizzando il commento di Michael Cihar, ecco un esempio di uno script bash che ho scritto per creare semplicemente questi collegamenti simbolici. Questo script si trova in git_hooks / dir che si trova nella radice del progetto. Anche la mia cartella .git / si trova nello stesso livello di directory.

#!/usr/bin/env bash

pwd=$(pwd);

# Script is designed to be ran from git_hooks/ dir
if [[ "$pwd" == *"git_hooks"* ]]; then

  files=$(ls | grep -v -e '.*\.');

   while read -r file; do

     ln -s ../../git_hooks/$file ../.git/hooks/
     echo "Linked $file -> ../.git/hooks/$file"

   done <<< "$files";

else

  echo "";
  echo "ERROR: ";
  echo "You must be within the git_hooks/ dir to run this command";
  exit 1;

fi

Il mio script deve essere eseguito dall'interno della directory git_hooks / effettiva. Puoi modificarlo per comportarsi in modo diverso, se lo desideri.

Questo script collegherà simbolicamente qualsiasi file che non ha un suffisso con un'estensione di file all'interno della directory git_hooks /. Ho un README.txt in questa directory + questo script (chiamato symlink.sh). Tutti gli attuali git hook sono chiamati "pre-commit", "pre-push", ecc., Quindi saranno collegati simbolicamente.


-2

perché non solo cp ./hooks/* .git / hooks /

questo ha funzionato per me in Mac OS


15
PerchéI don't have to copy the file from one folder to the other every time someone changes
George Dimitriadis
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.