Nasza firma obecnie używa prostego modelu rozgałęziania magistrali / wydania / poprawek i chciałaby uzyskać porady na temat tego, które modele rozgałęziania najlepiej sprawdzają się w Twojej firmie lub w procesie rozwoju.
Przepływy pracy / modele rozgałęziające
Poniżej znajdują się trzy główne opisy tego, które widziałem, ale są one częściowo sprzeczne ze sobą lub nie idą wystarczająco daleko, aby rozwiązać kolejne problemy, na które natrafiliśmy (jak opisano poniżej). Dlatego nasz zespół do tej pory domyślał się nie tak świetnych rozwiązań. Robisz coś lepszego?
Scalanie vs rebasing (historia splątana vs sekwencyjna)
Czy powinienem
pull --rebase
albo poczekać z połączeniem z powrotem do głównej linii, aż twoje zadanie zostanie zakończone? Osobiście skłaniam się ku scaleniu, ponieważ zachowuje to wizualną ilustrację, na podstawie której zadanie zostało uruchomione i zakończone, a nawet wolęmerge --no-ff
do tego celu. Ma jednak inne wady. Również wielu nie zdawało sobie sprawy z użytecznej właściwości scalania - że nie jest on przemienny (scalenie gałęzi tematycznej w master nie oznacza scalenia master do gałęzi tematycznej).Szukam naturalnego przepływu pracy
Czasami zdarzają się błędy, ponieważ nasze procedury nie wychwytują konkretnej sytuacji za pomocą prostych zasad. Na przykład poprawka potrzebna do wcześniejszych wydań powinna oczywiście opierać się na poziomie niższego szczebla, aby umożliwić połączenie go ze wszystkimi gałęziami (czy użycie tych terminów jest wystarczająco jasne?). Jednak zdarza się, że poprawka przenosi się do wzorca, zanim deweloper zda sobie sprawę, że powinna była zostać umieszczona dalej niżej, a jeśli jest już wypchnięta (jeszcze gorzej, scalona lub coś na jej podstawie), wówczas pozostała opcja to wybranie wiśni, z związane z tym niebezpieczeństwa. Jakich prostych zasad używasz?Uwzględniono także niezręczność jednej gałęzi tematycznej, koniecznie wykluczając inne gałęzie tematyczne (zakładając, że są one rozgałęzione od wspólnej linii bazowej). Deweloperzy nie chcą kończyć funkcji, aby rozpocząć kolejną, mając wrażenie, że napisanego właśnie kodu już nie ma
Jak uniknąć tworzenia konfliktów scalania (ze względu na cherry-pick)?
Co wydaje się pewnym sposobem na utworzenie konfliktu scalania jest wybranie między oddziałami, aby nigdy więcej nie mogły zostać połączone? Czy zastosowanie tego samego zatwierdzenia podczas przywracania (jak to zrobić?) W którejkolwiek gałęzi mogłoby rozwiązać tę sytuację? To jeden z powodów, dla których nie odważę się naciskać na przepływ pracy w dużej mierze oparty na scalaniu.
Jak rozłożyć na aktualne gałęzie?
Zdajemy sobie sprawę, że składanie zakończonej integracji z gałęzi tematów byłoby niesamowite, ale często praca naszych programistów nie jest jasno zdefiniowana (czasami tak prosta, jak „grzebanie się”), a jeśli jakiś kod już przeszedł do tematu „misc”, zgodnie z powyższym pytaniem nie można go stamtąd wyciągnąć. Jak pracujesz z definiowaniem / zatwierdzaniem / ukończeniem / wydaniem gałęzi tematycznych?
Właściwe procedury, takie jak przegląd kodu i stopniowanie, byłyby oczywiście cudowne.
Ale po prostu nie możemy utrzymać rzeczy na tyle nierozpoznanych, by sobie z tym poradzić - jakieś sugestie? gałęzie integracji, ilustracje?
Poniżej znajduje się lista powiązanych pytań:
- Jakie są dobre strategie pozwalające na wdrożenie poprawionych aplikacji?
- Opis przepływu pracy dla użycia Git do tworzenia własnego oprogramowania
- Przepływ pracy Git dla korporacyjnego rozwoju jądra Linux
- Jak utrzymujesz kod programistyczny i kod produkcyjny? (dzięki za ten plik PDF!)
- git releases management
- Git Cherry-pick vs Merge Workflow
- Jak wybrać wiele zatwierdzeń
- Jak łączyć wybrane pliki z git-merge?
- Jak wiśnia wybrać zakres zobowiązań i połączyć się w inną gałąź
- ReinH Git Workflow
- przepływ pracy git do wprowadzania modyfikacji, których nigdy nie zepchniesz do źródła
- Wybierz połączenie
- Prawidłowy przepływ pracy Git dla połączonego systemu operacyjnego i prywatnego?
- Utrzymanie projektu za pomocą Git
- Dlaczego nie mogę Git scalić zmian pliku ze zmodyfikowanym rodzicem / master.
- Git rozgałęzianie / zmiany zasad dobrych praktyk
- Kiedy „git pull --rebase” wpędzi mnie w kłopoty?
- Jak DVCS jest używany w dużych zespołach?
Sprawdź także, co pisze Plastic SCM na temat rozwoju opartego na zadaniach , a jeśli Plastic nie jest twoim wyborem, zapoznaj się z modelem rozgałęziającym nvie i jego skryptami pomocniczymi .
Odpowiedzi:
Najbardziej niepokojącą cechą, którą nowi programiści DVCS muszą sobie uświadomić, jest proces publikacji :
Dzięki temu możesz przestrzegać kilku zasad, aby ułatwić sobie pytania:
Teraz:
Przepływy pracy / modele rozgałęziające :
każdy przepływ pracy służy do obsługi procesu zarządzania wersjami i jest dostosowany do każdego projektu.
To, co mogę dodać do przepływu pracy, o którym wspominasz, to: każdy programista nie powinien tworzyć gałęzi funkcji, tylko gałąź „bieżącego dewelopera”, ponieważ prawda jest taka: programista często nie wie, co dokładnie wytworzy jego gałąź: jeden funkcja, kilka (ponieważ okazało się, że jest to zbyt skomplikowana funkcja), brak (ponieważ nie jest gotowy na wydanie), kolejna funkcja (ponieważ oryginalna „zmieniła kształt”), ...
Tylko „integrator” powinien ustanowić oficjalne gałęzie funkcji na „centralnym” repozytorium, które następnie mogą zostać pobrane przez programistów w celu zmiany / scalenia części ich pracy, która pasuje do tej funkcji.
Scalanie vs rebasing (historia splątana vs sekwencyjna) :
Podoba mi się moja odpowiedź, o której wspomniałeś („ Opis przepływu pracy dla użycia gita do tworzenia własnego ”)
Szukam naturalnego przepływu pracy :
w przypadku poprawek może pomóc powiązać każdą poprawkę z biletem ze śledzenia błędów, co pomaga deweloperowi zapamiętać, gdzie (tj. w której gałęzi, tj. dedykowanej gałęzi „dla poprawek”) powinien dokonać takich modyfikacji.
Wtedy haki mogą pomóc chronić centralne repozytorium przed wypchnięciami przed niepotwierdzonymi poprawkami lub gałęziami, z których nie należy naciskać. (tutaj nie ma konkretnego rozwiązania, wszystko to musi być dostosowane do twojego środowiska)
Jak uniknąć tworzenia konfliktów scalania (ze względu na cherry-pick)?
Jak stwierdził Jakub Narębski w swojej odpowiedzi , zbieranie wiśni powinno być zarezerwowane na rzadkie sytuacje, w których jest to wymagane.
Jeśli twoja konfiguracja wymaga dużo zbierania wiśni (tj. „To nie jest rzadkie”), to coś jest nie tak.
git revert
powinien się tym zająć, ale to nie jest idealne.Tak długo, jak gałąź nie została jeszcze wszędzie wypchnięta, programista powinien reorganizować swoją historię commits (kiedy zobaczy, że rozwój nabiera bardziej definitywnego i stabilnego kształtu), w następujący sposób:
Odpowiednie procedury, takie jak przegląd kodu i stopniowanie?
Repozytorium integracji (w dedykowanej integracji) repo może pomóc deweloperowi w:
źródło
rebase --interactive --autosquash
automatyczne przenoszenie powoduje, że wszystkie zatwierdzenia zaczynają się od tego samego początku kolejnej wiadomości zatwierdzenia. Jeśli te zatwierdzenia używają numeru biletu (na przykład), nawet jeśli poprawki związane z tym biletem nie były w tym czasie wykonywane sekwencyjnie, autosquash pozwala na szybką zmianę kolejności tych zatwierdzeń.Myślę, i mogę się mylić, że jedną z rzeczy, które są najbardziej niezrozumiane w git, jest jego rozproszony charakter. To sprawia, że zupełnie inaczej jest mówić o wywrotowym sposobie działania, chociaż możesz naśladować zachowanie SVN, jeśli chcesz. Problemem jest prawie każdy przepływ pracy, co jest świetne, ale także wprowadza w błąd.
Jeśli dobrze rozumiem rozwój jądra (skupię się na tym), każdy ma swoje własne repozytorium git do rozwijania jądra. Istnieje jedno repozytorium, linux-2.6.git, pod opieką Torvaldsa, które działa jako repozytorium wydań. Ludzie klonują stąd, jeśli chcą rozpocząć tworzenie funkcji przeciwko gałęzi „release”.
Inne repozytoria wykonują pewne prace programistyczne. Chodzi o to, aby sklonować z Linuksa 2.6, rozgałęziać się tyle razy, ile chcesz, aż do momentu, gdy uzyskasz działającą „nową” funkcję. Następnie, gdy będzie gotowy, możesz udostępnić go osobie uważanej za zaufaną, która wyciągnie tę gałąź z repozytorium do swojej i połączy z głównym nurtem. W jądrze Linuksa dzieje się to na kilku poziomach (zaufani porucznicy), dopóki nie osiągnie linux-2.6.git, w którym to momencie staje się „jądrem”.
Teraz jest to mylące. Nazwy oddziałów wcale nie muszą być spójne w repozytoriach. Mogę więc
git pull origin master:vanilla-code
uzyskać gałąź odorigin
mistrza w gałęzi w moim repozytorium o nazwievanilla-code
. Pod warunkiem, że wiem, co się dzieje, to naprawdę nie ma znaczenia - jest dystrybuowane w tym sensie, że wszystkie repozytoria są równorzędne, a nie tylko współużytkowane przez kilka komputerów, takich jak SVN.Mając to na uwadze:
head
. Wersjami mogą być tagi lub gałęzie, a poprawki są prawdopodobnie gałęziami same w sobie. W rzeczywistości prawdopodobnie wydawałbym wydania jako gałęzie, abyś mógł je ciągle łatać.origin
należy w repozytorium, prawdopodobnie uczynić kolejny oddział i scalania ostatnimaster
wyourbranch
tak, że ktoś inny może pociągnąć zmiany z jak najmniejszym wysiłku, jak możliwy. Z mojego doświadczenia wynika, że bardzo rzadko trzeba naprawdę bazować.git add .
a następniegit commit
.Mam nadzieję że to pomogło. Zdaję sobie sprawę, że VonC właśnie opublikował bardzo podobne wyjaśnienie ... Nie mogę pisać wystarczająco szybko!
Edytuj dalsze przemyślenia na temat używania gita w środowisku komercyjnym, ponieważ wydaje się to istotne dla PO z komentarzy:
product.git
, jest dostępne dla wielu starszych programistów / osób technicznych odpowiedzialnych za opiekę nad samym produktem. Są one analogiczne do roli opiekunów w OSS.Co się dzieje? Cóż, wszyscy ściągają na początku każdego dnia ze źródła „upstream”, tj. Repozytorium wydań (które prawdopodobnie będzie również zawierało najnowszy materiał z rozwoju z poprzednich dni). Każdy robi to bezpośrednio. To przejdzie do oddziału w ich repozytorium, prawdopodobnie o nazwie „master”, a może jeśli to ja o nazwie „najnowsze”. Następnie programista wykona trochę pracy. Ta praca może być czymś, czego nie są pewni, więc tworzą gałąź, wykonują pracę. Jeśli to nie zadziała, mogą usunąć gałąź i wrócić. Jeśli tak, będą musieli połączyć się z główną gałęzią, nad którą aktualnie pracują. Powiemy, że pracuje nad
latest-ui
tym programista interfejsu użytkownika,git checkout latest-ui
a potem następujegit merge abc-ui-mywhizzynewfeature
. Następnie mówi swojemu szefowi technicznemu (prowadzącemu do interfejsu użytkownika) hej, wykonałem takie zadanie, odciągnij ode mnie. Tak robi interfejs użytkownikagit pull user-repo lastest-ui:lastest-ui-suchafeature-abc
. Kierownik interfejsu użytkownika następnie patrzy na to w tej gałęzi i mówi, właściwie to bardzo dobrze, połączę toui-latest
. Mógłby wtedy powiedzieć wszystkim pod nim, aby wyciągnęli go zui-latest
gałęzi lub jakiejkolwiek nazwy, którą im nadali, tak więc twórcy badają tę funkcję. Jeśli zespół jest szczęśliwy, kierownik interfejsu użytkownika może poprosić lidera testowego o pobranie go i scalenie zmian. Rozchodzi się to do każdego (poniżej zmiany), który go testuje i przesyła raporty o błędach itp. Wreszcie, jeśli funkcja przejdzie testy itp., Jeden z najlepszych potencjalnych klientów technicznych może połączyć ją z bieżącą wersją roboczą programu, w którym to momencie wszystkie zmiany są następnie propagowane z powrotem w dół. I tak dalej.Nie jest to „tradycyjny” sposób pracy i jest zaprojektowany tak, aby był „sterowany równorzędnie”, a nie „hierarchiczny” jak SVN / CVS. Zasadniczo każdy ma dostęp dostępu, ale tylko lokalnie. Jest to dostęp do repozytorium i repozytorium, które wyznaczasz jako repozytorium wydania, które umożliwia korzystanie z hierarchii.
źródło
Model, który wykorzystałem z dobrymi wynikami, jest następujący:
„Błogosławione” repozytorium, które wszyscy popychają i wyciągają do / z, w zasadzie topologii klient-serwer.
Nie ma gałęzi master, więc żaden programista nie może wypchnąć żadnego kodu do „mainline”.
Wszystkie zmiany dotyczą gałęzi tematycznych. Nazwaliśmy przestrzeń nazw, aby łatwo wykryć, kto jest za to odpowiedzialny: jn / newFeature lub jn / issue-1234
Istnieje również mapowanie prawie 1 do 1 między gałęziami a kartami Kanban / Scrum na tablicy.
Aby zwolnić gałąź, jest ona wypychana do błogosławionej repozytorium, a karta Kanban jest przenoszona do gotowości do przeglądu.
Następnie, jeśli oddział zostanie zaakceptowany przez przegląd, jest on kandydatem do wydania.
Wydanie następuje, gdy zestaw zaakceptowanych gałęzi jest scalany ze sobą i oznaczany numerem wersji.
Przesuwając nowy tag do błogosławionej repozytorium, istnieje nowa możliwa podstawa dla nowych funkcji.
Aby uniknąć konfliktów scalania, programiści proszeni są o aktualizację (scalenie) swoich niewydanych gałęzi do najnowszego tagu wydania.
źródło
Osobiście staram się zachować tylko kod gotowy do wydania w gałęzi master.
Kiedy pracuję nad nową funkcją lub poprawką, robię to w oddziale. Testuję także w oddziale. Jeśli wszystko się powiedzie, tylko wtedy scalam / rebase z powrotem w master.
Staram się również używać typowych konwencji nazewnictwa gałęzi, takich jak:
źródło