Czy skryptami przechwytującymi Git można zarządzać razem z repozytorium?

336

Chcielibyśmy stworzyć kilka podstawowych skryptów przechwytujących, które wszyscy możemy udostępnić - na przykład w celu wstępnego formatowania komunikatów zatwierdzania. Git ma do tego skrypty przechwytujące, które normalnie są przechowywane pod <project>/.git/hooks/. Jednak skrypty te nie są propagowane, gdy ludzie wykonują klon i nie są kontrolowani pod kątem wersji.

Czy istnieje dobry sposób, aby pomóc wszystkim uzyskać odpowiednie skrypty przechwytujące? Czy mogę po prostu sprawić, aby te skrypty przechwytujące wskazywały skrypty sterowane wersją w moim repozytorium?

Pat Notz
źródło
5
Dobre pytanie. Chciałbym tylko, żeby była lepsza odpowiedź (bez skarg do @mipadi, po prostu chciałbym, aby git mógł to zrobić w bardziej automatyczny sposób - nawet jeśli tylko z opcją określoną dla git clone.)
lindes
Zgadzam się, @lindes! Ale być może celowe ograniczenie udostępniania haczyków? Sądzę, że dla użytkowników systemu Windows byłoby bałagan.
kristianlm,
@kristianlm: Istnieje wiele powodów, dla których czasami może być bałagan ... a także w czasach, gdy miło jest mieć go tam. Chciałbym tylko, żeby była jakaś opcja lub coś, co skopiowałoby haki. Chyba będę musiał kiedyś sprawdzić kod git-core i zrobić łatkę. :) (Albo
miej
pre-commitsprawia, że ​​jest to łatwe dla haków poprzedzających zatwierdzenie. Nie odpowiada na pytanie OP dotyczące zarządzania dowolnym arbitralnym hakiem git, ale haki pre-commit są prawdopodobnie najczęściej używane do celów jakości kodu.
ericsoco

Odpowiedzi:

143

Teoretycznie możesz utworzyć hookskatalog (lub dowolną inną nazwę) w katalogu projektu ze wszystkimi skryptami, a następnie utworzyć dowiązanie symboliczne .git/hooks. Oczywiście każda osoba, która sklonowała repozytorium, musiałaby skonfigurować te dowiązania symboliczne (chociaż można się naprawdę spodobać i mieć skrypt wdrażania, który kloner mógłby uruchomić, aby skonfigurować je półautomatycznie).

Aby wykonać dowiązanie symboliczne na * nix, wystarczy:

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

użyj, ln -sfjeśli jesteś gotowy, aby zastąpić zawartość.git/hooks

mipadi
źródło
38
było to nietrywialne, więc dołączam link do tego, jak prawidłowo symlinkować: stackoverflow.com/questions/4592838/...
David T.
17
git w wersji 2.9 ma teraz opcję konfiguracji core.hooksPathdo skonfigurowania pliku poza .git w celu połączenia z folderem hooks.
Aaron Rabinowitz
215

W Git 2.9 opcja konfiguracji core.hooksPathokreśla niestandardowy katalog hooków.

Przenieś swoje haki do hooksśledzonego katalogu w swoim repozytorium. Następnie skonfiguruj każde wystąpienie repozytorium, aby korzystało ze śledzonego hookszamiast $GIT_DIR/hooks:

git config core.hooksPath hooks

Zasadniczo ścieżka może być bezwzględna lub względna do katalogu, w którym uruchamiane są haki (zwykle działający katalog główny drzewa; patrz sekcja OPIS man githooks).

Max Shenfield
źródło
15
... i katalog hooków na który można wskazać może być oddzielnym repozytorium hooków;)
René Link
10
Czy ten parametr konfiguracyjny jest ustawiany automatycznie, gdy wykonujesz klon git?
Pierścień
4
Z reguły zmienne konfiguracyjne git nie mogą być ustawiane przez klonowane repozytorium. Myślę, że ma to zapobiec wykonywaniu niepożądanego kodu. git config kontroluje wykonywanie kodu poprzez przechwytywanie, nazwę użytkownika w komunikatach zatwierdzenia i inne ważne funkcje.
Max Shenfield,
1
Co się stanie, jeśli ktoś z zespołu dokona kasy w innym oddziale? Muszą to uwzględnić w każdym oddziale ...
jokerster
1
To prawda. Z drugiej strony, jeśli zaktualizujesz hooki w nowszych zatwierdzeniach, klonowane repozytoria automatycznie je otrzymają podczas pracy na gałęziach zbudowanych na tym zatwierdzeniu. Oba sposoby mają swoje zalety i wady.
fabb
15

Jeśli twój projekt jest projektem JavaScript i używasz go npmjako menedżera pakietów, możesz użyć współużytkowanych haczyków do wymuszania githooków npm install.

kilianc
źródło
5
Teraz wiem, do kogo natrętnie dodano te badziewie .git/hooks.
gavenkoa
Ostrzeżenie - nie obsługuje systemu Windows (chyba że jest uruchamiany jako administrator w git bash). Prostym rozwiązaniem jest dodanie „preinstall”: „git config core.hooksPath hooks” jako skryptu w pliku package.json. tzn. gdzie hooks to folder zawierający twoje skrypty git.
Shane Gannon
8

Dla Nodejs użytkowników prostym rozwiązaniem jest aktualizacja package.json z

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

Preinstalacja potrwa zanim

instalacja npm

i przekierowuje gita w poszukiwaniu haków w katalogu . \ hooks (lub jakkolwiek wybierzesz nazwę). Ten katalog powinien naśladować . \. Git \ hooks pod względem nazwy pliku (minus .sample) i struktury.

Wyobraź sobie, że Maven i inne narzędzia do budowania będą miały odpowiednik do preinstalacji .

Powinien także działać na wszystkich platformach.

Jeśli potrzebujesz więcej informacji, zobacz https://www.viget.com/articles/two-ways-to-share-git-hooks-with-your-team/

Shane Gannon
źródło
5

Co powiesz na git-hooks , przekierowuje .git/hooksinvoke do skryptu w katalogu projektu githooks.

Istnieje również wiele funkcji, które pozwalają zminimalizować kopiowanie i zawieszanie dowiązań symbolicznych w dowolnym miejscu.

Ożypałka
źródło
5

Większość współczesnych języków programowania, a raczej ich narzędzi do budowania, obsługuje wtyczki do zarządzania hakami git. Oznacza to, że wszystko, co musisz zrobić, to skonfigurować pakiet.json, pom.xml itp., A każdy w zespole nie będzie miał innej opcji, jak tylko się dostosować, chyba że zmieni plik kompilacji. Wtyczka doda zawartość do katalogu .git.

Przykłady:

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

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

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

yuranos
źródło
Próbowałem to osiągnąć w sposób ogólny, aby wykorzystać w moich projektach, więc napisałem to narzędzie: pypi.org/project/hooks4git
Lovato
3

Korzystamy z rozwiązań Visual Studio (a tym samym projektów), które mają zdarzenia przed i po kompilacji. Dodaję dodatkowy projekt o nazwie „GitHookDeployer”. Projekt samodzielnie modyfikuje plik w zdarzeniu po kompilacji. Ten plik jest ustawiony do skopiowania do katalogu kompilacji. Dlatego projekt jest budowany za każdym razem i nigdy nie jest pomijany. W przypadku kompilacji upewnia się również, że wszystkie haki git są na swoim miejscu.

Pamiętaj, że nie jest to ogólne rozwiązanie, ponieważ niektóre projekty oczywiście nie mają nic do zbudowania.

Mike de Klerk
źródło
2

Możesz użyć rozwiązania zarządzanego do zarządzania przechwytem przed zatwierdzeniem, takiego jak zatwierdzenie wstępne . Lub scentralizowane rozwiązanie dla haczyków typu git po stronie serwera, takich jak Datree.io . Ma wbudowane zasady, takie jak:

  1. Wykrywanie i zapobieganie łączeniu się sekretów .
  2. Wymuszaj prawidłową konfigurację użytkownika Git .
  3. Wymuszaj integrację biletu Jira - podaj numer biletu w komunikacie nazwa żądania ściągnięcia / zatwierdzenia.

Nie zastąpi wszystkich twoich haków, ale może pomóc twoim programistom w najbardziej oczywistych, bez konfiguracji konfiguracji instalowania haków na każdym komputerze / repozytorium każdego programisty.

Oświadczenie: Jestem jednym z założycieli Datrees

Shimon Tolts
źródło
1

Możesz uczynić folder hooków innym repozytorium git i połączyć go jako submoduł ... Myślę, że warto, tylko jeśli masz dużo członków i hooki zmieniane regularnie.

Zrób coś nowego
źródło
1

Idealnie, haki są pisane bash, jeśli podążasz za przykładowymi plikami. Ale możesz napisać go w dowolnym dostępnym języku i upewnić się, że ma flagę wykonywalną.

Możesz więc napisać kod Python lub Go, aby osiągnąć swoje cele, i umieścić go w folderze hooks. Będzie działał, ale nie będzie zarządzany wraz z repozytorium.

Dwie opcje

a) Wiele skryptów

Możesz zakodować haki w pomocy i dodać do nich mały fragment kodu, aby wywołać swój idealny skrypt, jak poniżej:

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

b) Pojedynczy skrypt

Fajniejszą opcją jest dodanie tylko jednego skryptu, aby rządzić nimi wszystkimi, zamiast kilku. Więc tworzysz hooks / mysuperhook.go i celujesz każdym hakiem, który chcesz mieć.

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

Ten parametr dostarczy Twojemu skryptowi, który hook został wyzwolony, i możesz rozróżnić go w kodzie. Dlaczego? Czasami możesz na przykład uruchomić tę samą kontrolę zatwierdzania i wypychania.

I wtedy?

Następnie możesz chcieć mieć dodatkowe funkcje, takie jak:

  • Ręcznie uruchom zaczep, aby sprawdzić, czy wszystko jest w porządku, nawet przed zatwierdzeniem lub wypchnięciem. Jeśli po prostu wywołasz skrypt (opcja a lub b), załatwi sprawę.
  • Uruchom zaczepy na CI, więc nie musisz przepisywać tych samych sprawdzeń dla CI, byłoby to na przykład po prostu wywołanie wyzwalacza zatwierdzenia i wypchnięcia. To samo co powyżej powinno to rozwiązać.
  • Wywołaj narzędzia zewnętrzne, takie jak walidator przeceny lub walidator YAML. Możesz wykonywać połączenia systemowe i obsługiwać STDOUT i STDERR.
  • Upewnij się, że wszyscy programiści mają prosty sposób na zainstalowanie hooków, więc do repozytorium należy dodać ładny skrypt, aby zastąpić domyślne hooki poprawnymi
  • Mieć globalnych pomocników, takich jak czek, aby zablokować zatwierdzenia do opracowania i opanowania gałęzi, bez konieczności dodawania go do każdego repozytorium. Możesz go rozwiązać, mając inne repozytorium ze skryptami globalnymi.

Czy to może być prostsze?

Tak, istnieje kilka narzędzi, które pomogą ci zarządzać haczykami. Każdy z nich jest dostosowany do rozwiązania problemu z innej perspektywy i być może będziesz musiał zrozumieć je wszystkie, aby uzyskać ten, który jest najlepszy dla Ciebie lub Twojego zespołu. GitHooks.com oferuje wiele informacji na temat zaczepiania oraz kilka dostępnych dziś narzędzi.

Na dzień dzisiejszy wymieniono tam 21 projektów z różnymi strategiami zarządzania hakami git. Niektóre robią to tylko dla jednego haka, inne dla określonego języka i tak dalej.

Jedno z tych narzędzi, napisane przeze mnie i oferowane za darmo jako projekt typu open source, nazywa się hooks4git . Jest napisany w Pythonie (bo mi się podoba), ale pomysł polega na obsłudze wszystkich elementów wymienionych powyżej w jednym pliku konfiguracyjnym o nazwie .hooks4git.ini, który znajduje się w twoim repozytorium i może wywoływać dowolny skrypt, który chcesz wywołać, w dowolnym języku .

Korzystanie z haków git jest absolutnie fantastyczne, ale sposób, w jaki są oferowane, zwykle tylko odciąga ludzi od tego.

Lovato
źródło
Jakiś czas temu opublikowałem bardzo krótszą wersję i, zgodnie z ustaleniami z moderatorami, zawiera ona wyjaśnienie i krótki link do narzędzia, które sam napisałem, które moim zdaniem może pomóc innym programistom.
Lovato,
1

Dla stopniowych użytkowników

Uważam, że te skrypty są bardzo przydatne w projektach stopniowych.

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

wstępnie zatwierdzić

.... your pre commit scripts goes here
a3765910
źródło