Czy w git nie jest dobrym pomysłem utworzenie tagu o takiej samej nazwie jak usunięta gałąź?

20

Mam projekt z modelem rozgałęzień git, który z grubsza odpowiada modelowi git-flow nvie .

Nasze gałęzie wydania mają nazwy SemVer , npv1.5.2

Kiedy gałąź wydania otrzyma zielone światło do produkcji, zamykamy gałąź, łącząc ją w master, stosując tag, a następnie usuwając gałąź.

Ponieważ natychmiast usuwamy gałąź wydania, używamy tego samego identyfikatora do oznaczania gałęzi, np v1.5.2

Oto polecenia, których użylibyśmy do zamknięcia gałęzi wydania:

$ git checkout master
$ git merge v1.5.2
$ git tag -a v1.5.2 -m "Version 1.5.2 - foo bar, baz, etc"
$ git branch -d v1.5.2
$ git branch -dr origin/v1.5.2
$ git push origin :v1.5.2
$ git push
$ git push --tags

Wydaje się, że działa to w większości przypadków, jednak powoduje problem w scenariuszu, w którym inne wystąpienie repozytorium git (np. Inna maszyna deweloperska lub środowisko testowe) ma lokalne pobranie z gałęzi v1.5.2.

git push origin :v1.5.2Komenda usunie oddział w pilocie, ale nie usuwa lokalną wersję oddziału (jeśli istnieje) we wszystkich repo.

Prowadzi to do niejednoznacznego odwołania podczas próby realizacji transakcji v1.5.2w tych repozytoriach:

$ git checkout v1.5.2
warning: refname 'v1.5.2' is ambiguous.

Czy można tego uniknąć bez stosowania innej składni dla gałęzi, np. release-v1.5.2Lub v1.5.2-rc?

A może jest to nieuniknione, a zatem fundamentalnie zły pomysł, aby utworzyć tag o takiej samej nazwie jak usunięta gałąź?

tommarshall
źródło

Odpowiedzi:

19

Jeśli absolutnie chcesz zachować ten schemat nazewnictwa, możesz:

Zdecyduj, że nie obchodzą Cię te ostrzeżenia

Oznacza to, że jeśli jesteś zadowolony z faktu, że:

  • git checkout <ref>sprawdzi się refs/heads/<ref>nad refs/tags/<ref>(patrz git-Checkout )
  • inne polecenia będą używane refs/tags/<ref>przez refs/heads/<ref>(zobacz gitrevisions )

Na przykład w tym repozytorium testowym v1.5.2gałąź wskazuje na zatwierdzenie B, ale v1.5.2znacznik wskazuje na zatwierdzenie A.

% git log --oneline --decorate
8060f6f (HEAD, v1.5.2, master) commit B
0e69483 (tag: v1.5.2) commit A

git checkout preferuje nazwy oddziałów:

% git checkout v1.5.2
warning: refname 'v1.5.2' is ambiguous.
Switched to branch 'v1.5.2'
% git log --decorate --oneline -1
8060f6f (HEAD, v1.5.2, master) commit B

ale git logużyje nazwy tagu:

% git log --decorate --oneline -1 v1.5.2
warning: refname 'v1.5.2' is ambiguous.
0e69483 (tag: v1.5.2) commit A

To może być mylące.

Trenuj ludzi, aby usuwali swoje lokalne oddziały, gdy zobaczą nowy tag

Może to być trudne / niezręczne w zależności od wielkości organizacji.

Napisz opakowanie wokół „git pull” i „git fetch”

To znaczy, napisz opakowanie sprawdzające, czy są jakieś tagi, które śledzą nazwy gałęzi, i ostrzegaj o tych gałęziach (lub je usuwaj). Brzmi to bolesnie i może być niepożądane, jeśli śledzona gałąź jest obecnie sprawdzana.

Niestety, wydaje się, że najłatwiejszym sposobem rozwiązania tego problemu może być zmiana sposobu nazywania oddziałów. Opublikowany link używa różnych schematów nazewnictwa dla tagów i gałęzi: jeśli już przeważnie stosujesz tę metodę, przyjęcie jej schematu nazewnictwa może być najłatwiejszym rozwiązaniem.

benj
źródło
Dzięki za odpowiedzi. Bardzo pomocny. Twoja pierwsza kula mówi, że git checkoutsprawdzi tag nad gałęzią, gdy pojawi się niejednoznaczne odniesienie, jednak nie takie zachowanie widzę, patrz: gist.github.com/tommarshall/9376724 . Czy to coś zmieniło się w bardziej nowoczesnej wersji git? Czy mogę ustawić flagę gitconfig, aby uzyskać takie zachowanie?
tommarshall
Masz rację, całkowicie się myliłem. Przepraszam! Naprawiłem swoją odpowiedź i dodałem przykład.
benj
10

Możesz jawnie określić, czy chcesz mieć oddział, czy tag, używając pełnej nazwy:

 git checkout refs/heads/v1.5.2

lub

git checkout refs/tags/v1.5.2
mastahu
źródło