Dowiązanie symboliczne do hooka w git

86

Napisałem własny, niestandardowy hook post-merge, teraz dodałem katalog "hooks" do mojego głównego folderu projektu (ponieważ git nie śledzi zmian w .git / hooks), gdzieś przeczytałem, że mogę utworzyć symboliczne łącze z hooków do .git / hooks, więc nie muszę kopiować pliku z jednego folderu do drugiego za każdym razem, gdy ktoś go zmieni, więc spróbowałem:

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

Ale to nie działa, jakieś pomysły dlaczego? "ln hooks / post-merge .git / hooks / post-merge" działa dobrze, ale tworzenie twardego linku jest takie samo jak kopiowanie.

Mateusz Dymczyk
źródło
22
Ponieważ łącze symboliczne jest rozwiązywane względem jego lokalizacji. Dowiązanie symboliczne .git/hooks/wskazujące na hooks/post-mergezostanie rozwiązane na .git/hooks/hooks/post-merge, które nie istnieje. Chcesz ln -s -f ../../hooks/post-merge .git/hooks/post-merge. Lub ułatwić Ci życie: ln -s -f ../hooks .git/hooks. Twój problem nie ma nic wspólnego z git.
Arystoteles Pagaltzis
1
stackoverflow.com/questions/3462955/ ... i stackoverflow.com/questions/427207/ ... (i stackoverflow.com/questions/3703159/ ... ) wskazują na fakt, że dowiązanie symboliczne może działać.
VonC
Popraw mnie, jeśli się mylę, ale nadal trzeba skonfigurować łącze Symlink dla każdej stacji roboczej. Jedyną rzeczą, którą to zapisuje, jest ręczne skopiowanie go lub napisanie innego polecenia, które kopiuje śledzony plik przechwytywania .git/hooks.
adi518

Odpowiedzi:

161

właśnie użyłeś złej ścieżki, powinno to być:

ln -s -f ../../hooks/post-merge .git/hooks/post-merge
Michal Čihař
źródło
10
Nie rozumiem, dlaczego muszę przejść o dwa katalogi w górę, aby połączyć zasób znajdujący się w folderze, w którym się cdznajdowałem. Czy nie powinno tak być ln -s ./hooks/?
Droogans
45
To. Kiedy git ocenia dowiązanie symboliczne, najwyraźniej robi to używając .git/hooksjako swojego katalogu roboczego, więc ścieżki względne powinny być względne w stosunku do tego katalogu. Jest to bardziej oczywiste, jeśli najpierw cdsię .git/hooksprzed podjęciem dowiązania i dowiedzieć się ścieżki względnej stamtąd.
Eliot,
12
@Eliot Katalog roboczy nie ma wpływu na tworzenie ani rozwiązywanie dowiązań symbolicznych. Cokolwiek podasz, lnzostanie zapisane jako cel i rozstrzygnięte w zależności od lokalizacji łącza.
Joó Ádám
2
@ JoóÁdám Masz rację. Problem polega na tym, że oryginalne polecenie określa nieprawidłową ścieżkę względną. Mimo to cdwejście do programu .git/hooksprzed utworzeniem łącza pomoże ci napisać polecenie, ponieważ możesz następnie automatycznie uzupełnić do prawidłowej ścieżki.
Eliot
1
Wszystko to w końcu zadziałało. Jedyna różnica polega na tym, że łączę się ze swoim własnym prepare-commit-msg. Problem polega na tym, że jeśli edytuję komunikat o zatwierdzeniu za pomocą nano, a następnie Ctl + X wychodzi, aby przerwać, git i tak nadal kończy zatwierdzanie zamiast przerywać, tak jak przed wprowadzeniem tej zmiany. Czy istnieje sposób na wyjście z nano bez powodowania zakończenia tego zobowiązania?
frakman1
15

Chociaż możesz używać dowiązań symbolicznych, możesz także zmienić folder hooks dla swojego projektu w ustawieniach git za pomocą:

git config core.hooksPath hooks/

Który jest domyślnie lokalny, więc nie zepsuje przechwytywania git dla innych projektów. Działa dla wszystkich haków w tym repozytorium, więc jest szczególnie przydatne, jeśli masz więcej niż jeden punkt zaczepienia.

Jeśli masz już niestandardowe hooki .git/hooks/, których nie chcesz udostępniać swojemu zespołowi, możesz dodać je w hookach / i dodać, .gitignoreaby nie były udostępniane.

Pierre Sassoulas
źródło
Bardzo dobrze! Poręczna sztuczka :) Wydaje się o wiele bardziej przyszłościowa niż łączenie symboliczne jeden po drugim.
jkp
2

Zmiana katalogu przed połączeniem

cd /path/to/project-repo/.git/hooks
ln -s -f ../../hooks/post-merge ./post-merge
Jekis
źródło
Jeszcze prościej, po cd:ln -s -f ../../hooks/post-merge
jamesdlin
0

Obliczanie ścieżki odbywa się względem łącza symbolicznego. Rozumiemy na przykładzie,

ln -s path/to/file symlink/file

Tutaj ścieżka do pliku powinna faktycznie być ścieżką względną ze ścieżki dowiązania symbolicznego.
System faktycznie oblicza ścieżkę pliku, jak symlink/path/path/to/file
Powyższe polecenie powinno zostać ponownie zapisane jako

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

Struktura folderów jest taka ,

/ kod
------ dowiązanie symboliczne / plik
------ ścieżka / do / pliku

swayamraina
źródło
0

Korzystając z komentarza Michaela Cihara, oto przykład skryptu bash, który napisałem, aby po prostu utworzyć te dowiązania symboliczne. Ten skrypt znajduje się w git_hooks / dir, który znajduje się w katalogu głównym projektu. Mój folder .git / również znajduje się na tym samym poziomie katalogu.

#!/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

Mój skrypt musi być uruchamiany z rzeczywistego katalogu git_hooks /. Jeśli chcesz, możesz go zmodyfikować, aby zachowywał się inaczej.

Ten skrypt dowiązuje symbolicznie do każdego pliku, który nie ma rozszerzenia pliku w katalogu git_hooks /. Mam plik README.txt w tym katalogu + ten skrypt (o nazwie symlink.sh). Wszystkie rzeczywiste punkty zaczepienia gita noszą nazwy „pre-commit”, „pre-push” itd., Więc będą dowiązane symbolicznie.

cchoe1
źródło
-1

dlaczego nie tylko cp ./hooks/* .git / hooks /

to działało dla mnie w systemie Mac OS

Frazko
źródło
15
PonieważI don't have to copy the file from one folder to the other every time someone changes
George Dimitriadis