Git-flow i master z wieloma równoległymi gałęziami wydania

86

Próbujemy przyjąć udany model rozgałęziania Git zaimplementowany przez git-flow. Teraz pracujemy nad co najmniej dwoma gałęziami wydania, jedną dla najnowszej stabilnej wersji, a drugą dla następnej („podglądowej”) wersji. Nie rozumiem, dlaczego wszystkie wydania wydają się „linearyzowane” do mastera i tam oznaczone. Dlaczego nie oznaczyć wydań w ich gałęziach wydań? Dlaczego w ogóle mistrz ? Albo po co rozwijać gałąź i nie używać do niej mastera ?

Mot
źródło

Odpowiedzi:

77

W modelu git-flow Twoja „najnowsza wydana” wersja faktycznie jest odwzorowywana na gałąź master, podczas gdy „wersja zapoznawcza” jest mapowana na releasegałąź git-flow . Jest rozwidlany developi ostatecznie łączony masterz momentem rzeczywistego wydania. Wtedy to stanie się Twoją „najnowszą wersją” i zazwyczaj będziesz naprawiać tylko błędy w tym wydaniu, używając hotfixgałęzi git-flow . W ten sposób Twój masterzawsze reprezentuje najbardziej stabilny stan Twojej najnowszej wydanej wersji.

Jeśli chcesz naprawić błędy dla starszych wydań lub zrobić tam coś innego, rozwidlisz supportgałąź z odpowiedniego zatwierdzenia w master(będziesz mieć wszystkie wersje, jakie kiedykolwiek zostały tam utworzone). supportgałęzie są nadal eksperymentalne ( zgodnie z dokumentacją ) i nie są dobrze udokumentowane. Ale jak widać z pomocy wiersza poleceń:

usage: git flow support [list] [-v]
       git flow support start [-F] <version> <base>

te gałęzie dopiero się rozpoczęły i nie mają być łączone z powrotem do masternor develop. Zwykle jest to w porządku, ponieważ poprawki do „starożytnych” wydań lub funkcji, o które prosili klienci, aby zostały zaimplementowane w „starożytnych” wersjach, nie mogą lub nie powinny wracać master. Jeśli nadal myślisz, że chcesz przenieść poprawkę do swojej głównej linii rozwojowej (reprezentowanej przez masteri develop), po prostu rozpocznij hotfix, wybierz najlepsze zmiany i zakończ hotfix.

mstrap
źródło
17
Nie dotyczy to powolnego przejścia od testu do kontroli jakości do produkcji. Mogą istnieć dwie (lub nawet więcej, ale na razie powiedzmy tylko dwie) otwarte gałęzie wydania, każda na innym etapie tego potoku i każda potrzebna do umożliwienia poprawek błędów znalezionych w teście. Rozwijać oddział byłby wtedy gdzie funkcje były zgromadzone na wydaniu, którego oddział nie został jeszcze wykonany. W takiej sytuacji poprawka w wydaniu n-2 zostałaby ostatecznie scalona w celu opracowania, ale pominęłaby wydanie n-1, przynajmniej zgodnie ze standardowym przepływem git. Doprowadziłoby to do regresji na n-1, naprawionej ostatecznie po wydaniu n
Brendan
Dlaczego nie miałyby być zachowane gałęzie wydań, a po utworzeniu nowszej gałęzi wydania starsze ewoluują w gałąź „wsparcia”?
lkanab
1
Dlaczego gałęzie release są „rozwidlane” od develop, a nie tylko od develop?
Sandra K,
gitflow-avh wygląda jak utrzymany (tj. nie martwy) fork oryginalnego gitflow. git flow supportnie jest oznaczona jako eksperymentalna.
Timo Verhoeven
9

Wygląda na to, że przeważnie model mentalny z nieco zbyt dużym naciskiem na gałęzie. Zgadzam się, możesz po prostu oznaczyć zatwierdzone przez siebie commity zamiast scalać je z powrotem w master.

Ale obraz jest ładny. Scalenie wszystkiego z powrotem w master daje wyraźne wskazanie wydań w porządku czasowym zamiast umieszczania tagów wersji rozrzuconych po całym wykresie.

Myślę, że ten model nie działa jednak przy naprawianiu błędów w starszych wersjach. To psuje porządek.

  1. Powiedzmy, że wydaliśmy wersję 1.0.1 i późniejszą, dodaliśmy funkcje i wydaliśmy 1.1.0.
  2. Odkrywamy błąd w wersji 1.0.1 i chcemy go naprawić w obu wersjach
  3. Musimy dodać 1.0.2 po 1.1.0 do mastera, a następnie bezpośrednio (lub wcześniej) również 1.1.1.

Odpowiadając na twoje pytanie: myślę, że jest to zestaw reguł, które w niektórych przypadkach tworzą prosty model myślowy. Nie wszystkie zasady mają sens z czysto technicznego punktu widzenia, ale to nie czyni ich złymi. Modele mentalne są dobre dla ludzi.

Sarien
źródło
1
supportgałęzie są przeznaczone do naprawiania błędów w starszych wydaniach, choć nadal są oznaczone jako „eksperymentalne”.
mstrap
2

Osobiście uważam, że wspomniany przepływ git jest zbyt skomplikowany.

Jeśli korzystasz z GitHub, wypróbuj GitHub flow(zgodnie z opisem Scotta Chacona).

Jest to szczególnie przydatne do współpracy nad wieloma funkcjami, przeglądu kodu i można go połączyć z rozwiązaniem Continuous Integration przy użyciu Commit Status API.

AKTUALIZACJA : Istnieje nowa oficjalna witryna internetowa The GitHub Flow ™

AKTUALIZACJA 2 : Jest nowy oficjalny (i uproszczony) przewodnik GitHub dla GitHub Flow ™: https://guides.github.com/introduction/flow/

Haralan Dobrev
źródło
10
Przepływ GitHub jest odpowiedni tylko dla kontekstu niezwiązanego z wydaniem: proces przepływu git jest zaprojektowany głównie w oparciu o „wydanie”. Tak naprawdę nie mamy „wydań”, ponieważ codziennie wdrażamy do produkcji - często kilka razy dziennie.
Remi Mélisson
10
Dodałbym również, że git-flow nie działa tak dobrze w kontekście zorientowanym na wydanie, który ma wydania konserwacyjne. Np. Co się stanie, gdy wydanie 1.2.1 nastąpi po wydaniu 1.3.0? Prawdopodobnie nie da się tego połączyć z masteranomalią chronologii dzieła.
Ken Williams
@KenWilliams, jak opisano w odpowiedzi mstrap , do tego supportsłużą gałęzie. Ale masz rację, to rzeczywiście anomalia, że ​​takie wydania nie są z powrotem scalane master, co - w moim rozumieniu - powinno obejmować wszystkie wydania produkcyjne.
beatngu13
2

W moim przypadku mam dwie wersje tego samego oprogramowania, w których podstawy są takie same, ale każda wersja ma inne funkcje.

Więc tworzę dwie, worktreeco oznacza, tworzę dwie odpowiednie, długo działające gałęzie obok wzorca.

$git worktree add -b version-silver ..\version-silver master
$git worktree add -b version-gold ..\version-gold master

Wtedy ja mam:

$git branch
master  # base stuff here
version-silver # some normal features
version-gold # some better features

Jest jedno repozytorium, ale mam 3 oddzielne foldery obok siebie dla każdej gałęzi powyżej. I wprowadź wspólne zmiany w master. następnie połącz go z obiema innymi wersjami.

cd master
vim basic.cpp
git add .
git commit -m "my common edit on basic.cpp"
cd ..\version-silver
vim silver.cpp
git add .
git commit -m "my specific edit on silver.cpp"
git merge master # here i get the basic.cpp latest changes for silver project
cd ..\version-gold
git merge master # here i get the basic.cpp latest changes for gold project

Konkretne zmiany każdej wersji zostaną również umieszczone w odpowiednim folderze, a prace nad każdym projektem są izolowane i nie można pomylić IDE.

Mam nadzieję, że to pomoże.

vaheeds
źródło
2

Całkowicie zgadzam się z @Mot.

Miło słyszeć te same pytania.

Nasz zespół był również poszukiwany na bardziej uniwersalny model rozgałęziania niż Successfull . To znaczy, jak wspomniano powyżej @Mot - głównym pomysłem jest uniknięcie wprowadzania dodatkowych repozytoriów do obsługi gałęzi release- * w oddzielnym repozytorium * .git, jak na przykład robi to kernel.org dla stabilnych wydań. Ale kernel.org robi to w celu zminimalizowania pobieranych rozmiarów, jak sądzę.

Wydaje mi się, że łatwiej jest mieć mistrza jako główną linię rozwoju .

Istnieją również pewne konflikty w łączeniu modelu wydania * do mastera i oznaczaniu go później pomysłem

użyj skryptu przechwytującego Git, aby automatycznie budować i wdrażać nasze oprogramowanie na nasze serwery produkcyjne za każdym razem, gdy nastąpiło zatwierdzenie na serwerze głównym

ponieważ zakończenie (scalanie i tagowanie) nie jest transakcją atomową:

$ git checkout master
Switched to branch 'master'
$ git merge --no-ff release-1.2
Merge made by recursive.
(Summary of changes)
$ git tag -a 1.2

a jeśli git hook rozpocznie kompilację z automatyczną obsługą wersji:

$git describe --tags --long >.ver

wtedy można zbudować błędną wersję dla:

$ git merge --no-ff release-1.2

Wiem, że wersjonowanie w wersji Successfull wprowadza jakiś proces wersji bump, ale nie jest to automatyczne.

Podsumowując - kluczowe różnice, które wprowadzamy do modelu gałęzi dla wydań - * scalanie i tagowanie to: - oznaczanie wydania podczas tworzenia gałęzi - zachowanie gałęzi wydania, aby umożliwić jej utrzymanie w przyszłości

mdn
źródło
-2

Gałąź główna powinna ZAWSZE reprezentować bazę kodu produkcyjnego, dlatego zawsze scalasz kod z powrotem do mastera zaraz po wydaniu produkcyjnym.

Tagowanie służy do „zapamiętywania” dokładnego kodu, który trafił do wydania produkcyjnego, dzięki czemu można wrócić później i przeanalizować kod, jeśli coś poszło nie tak.

Z tego teoretycznie nie powinno mieć znaczenia, czy otagujesz swój kod w gałęzi wydania, czy w gałęzi głównej po ponownym scaleniu z głównym. Osobiście wolę otagować kod w gałęzi wydania, ponieważ jest to dokładnie kod, który trafił do kompilacji / wydania (zakładając, że coś może pójść nie tak podczas scalania).

Problem z koncepcją gałęzi rozwoju polega na tym, że jest ona jednowątkowa. Brendan w tym wątku wspomniał o strategii, którą można by zastosować, obejmując koncepcję branży rozwojowej.

Bernie Lenz
źródło
4
Co to jest „baza kodu produkcyjnego”, jeśli równolegle zarządzasz wieloma wydaniami, np. 1.0, 1.1, 1.5?
Thomas S.,
Produkcja Code Base jest tym, co jest teraz w produkcji, np. V1.0. Gałęzie zawierają zmiany dla wersji, które mają zostać wdrożone w przyszłości, np. V1.0.1, v1.1 i v2.0. Gdy „przyszłe” wydanie zostanie wdrożone w środowisku produkcyjnym, jest ono scalane z powrotem do wersji głównej, tak aby wersja główna odzwierciedlała to, co jest w produkcji. Jest również scalany do przodu (np. Wersja 1.0.1 do 1.1 i wersja 2.0), więc zmiany w wersji 1.0.1 nie zostaną utracone po wydaniu wersji 1.1 do produkcji.
Bernie Lenz,
4
Mówię o utrzymywaniu wielu wydanych wersji, a nie o przyszłych wersjach.
Thomas S.,
4
Wydaje się, że mnie nie rozumiesz. Czy nie możesz sobie wyobrazić, że w niektórych firmach obsługiwane są różne wersje? Na przykład Microsoft utrzymuje również aktualizacje dla Windows 7, 8, 8.1 i 10, więc dlaczego nie inne firmy?
Thomas S.,
1
Zgadza się Thomas. Model ten jest ukierunkowany na produkty, które mają jedno wydanie produkcyjne w danym momencie, takie jak np. Strony internetowe. Użyłem również tego modelu do kompilacji mobilnych, np. Androida i iPhone'a, gdzie kompilacja jest sparametryzowana w celu utworzenia kompilacji na Androida lub iPhone'a (lub obu) przy użyciu tego samego numeru wersji. Jestem ciekawy, aby poznać wasze uwagi na temat struktury modelu kompilacji dla produktu, który ma wiele wersji na żywo w produkcji w dowolnym momencie, być może z niektórymi współdzielonymi, a innymi innymi. Daj nam znać ...
Bernie Lenz