Zapobiegaj zatwierdzeniom w gałęzi głównej

84

(Dla uproszczenia) Mam mastergałąź i devw moim repozytorium Git. Chcę mieć pewność, że masteroddział zawsze działa, więc cała praca, którą wykonuję, powinna znajdować się wdev oddziale.

Jednak kiedy łączę swoje zmiany z --no-ffscaleniem, zwykle zostaję w masteroddziale i po prostu kontynuuję w nim pracę (ponieważ zapominam o przejściu do kasy dev).

Czy mogę utworzyć regułę dla mastergałęzi, która mówi, że nie mogę wykonywać zatwierdzeń i szybkiego łączenia do przodu, ale tylko --no-ffscalania z innej gałęzi?

Musi to działać w przypadku prywatnych repozytoriów hostowanych (a więc nie GitHub i BitBucket).

Rasmus Bækgaard
źródło
4
„Szybkie zatwierdzanie zmian” nie jest rzeczą. Zatwierdzenia są po prostu zatwierdzeniami, git committworzy nowe, nie ma przewijania do przodu. Wygląda na to, że chcesz po prostu zabronić zwykłych zatwierdzeń, gdy bieżąca gałąź jest master, w takim przypadku, zagląda do pre-commitzaczepu.
torek

Odpowiedzi:

154

Tak to mozliwe. Musisz utworzyć punkt zaczepienia przed zatwierdzeniem, który odrzuca zatwierdzenia do gałęzi głównej. Git nie wywołuje przechwytywania przed zatwierdzeniem, kiedy wywołujesz polecenie merge , więc ten hook będzie odrzucał tylko zwykłe zatwierdzenia.

  1. Przejdź do swojego repozytorium.
  2. Utwórz plik .git / hooks / pre-commit z następującą zawartością:

    #!/bin/sh
    
    branch="$(git rev-parse --abbrev-ref HEAD)"
    
    if [ "$branch" = "master" ]; then
      echo "You can't commit directly to master branch"
      exit 1
    fi
    
  3. Spraw, aby był wykonywalny (niewymagany w systemie Windows ):

    $ chmod +x .git/hooks/pre-commit
    

Aby wyłączyć szybkie scalanie do przodu , musisz również dodać następującą opcję do pliku .git / config :

[branch "master"]
    mergeoptions = --no-ff

Jeśli chcesz również chronić gałąź główną na swoim pilocie, sprawdź odpowiedź: Jak ograniczyć dostęp do gałęzi głównej na git

qzb
źródło
To wygląda dokładnie tak, jak potrzebuję - czy to działa również w systemie Windows?
Rasmus Bækgaard
2
@ RasmusBækgaard tak, będzie: skrypt bash dla hooka zostanie zinterpretowany przez bash Git zawarty w Git dla Windows. (Po prostu nie potrzebujesz kroku chmod)
VonC
uwaga: można również zapobiec wpychaniu się do odległego masterodgałęzienia w haku przed wypychaniem. np .: gist.github.com/aaronhoffman/ffbfd36928f9336be2436cffe39feaec
Aaron Hoffman
4
Fajnie, dla każdego, kto szuka sposobu na dodanie tych reguł lub innych haków git do repozytorium projektu, sprawdź ten prosty pakiet npm: github.com/kilianc/shared-git-hooks , ponieważ nie możesz dołączyć niczego, co znajduje się w .git do repozytorium.
George Dimitriadis
9
także, to jest tylko dla naszego lokalnego repozytorium git, jak możemy wymusić reguły w różnych repozytoriach git dla wszystkich programistów bez konieczności ręcznej zmiany zawartości katalogu .git?
Alexander Mills
13

W tym celu możesz użyć narzędzia pre-commit . Ma wbudowanyno-commit-to-branch zaczepienia, którego można użyć do zapobiegania zatwierdzeniom do jednej lub więcej gałęzi.

Ustawiać

Podstawowy proces konfiguracji to:

  • Zainstaluj za pomocą pip lub brew (instrukcje na https://pre-commit.com/#install )
  • Stwórz .pre-commit-config.yaml plik w katalogu głównym projektu (zobacz poniżej pierwszą wersję roboczą)
  • Zainstaluj zaczepy w konfiguracji git, uruchamiając pre-commit install.

Podstawowa konfiguracja do ochrony gałęzi

Oto podstawowa konfiguracja, która zawiera tylko no-commit-to-branchhook:

repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
  rev: v3.3.0
  hooks:
    - id: no-commit-to-branch
      args: ['--branch', 'master']

Jeśli chcesz chronić wiele gałęzi, możesz użyć wielu --branchargumentów na liście argumentów:

repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
  rev: v3.3.0
  hooks:
    - id: no-commit-to-branch
      args: ['--branch', 'master', '--branch', 'staging']

Czy to nie przesada?

Wstępne zatwierdzenie ma wiele innych wbudowanych punktów zaczepienia i dużą kolekcję utworzonych przez społeczność punktów zaczepienia, które zmienią sposób czyszczenia i sprawdzania poprawności zatwierdzeń. Powodem, dla którego o tym wspominam, jest to, że chociaż to narzędzie może być przesadą, ponieważ po prostu zapobiega zatwierdzeniom w chronionej gałęzi, ma wiele innych funkcji, które sprawiają, że jest atrakcyjnym i prostym dodatkiem do każdego projektu git.

JGC
źródło
7

Sensowne może być zainstalowanie go globalnie za pośrednictwem

git config --global core.hooksPath ~/githooks

i przenosząc ten pre-commitplik do tego katalogu

Michel Samia
źródło
A jeśli mam wiele repozytoriów - czy nie wpłynie to na wszystkie?
Rasmus Bækgaard
1
i to właśnie możesz zrobić w większości przypadków
Michel Samia
Powiedzmy, że mam ten dziwny projekt, w którym zmienili nazwę masterna Production- czy można zrobić wyjątki?
Rasmus Bækgaard
możesz użyć operatora or w bash, aby określić więcej gałęzi, które chcesz chronić po stronie klienta
Michel Samia