Czy lepiej jest łączyć „często”, czy dopiero po ukończeniu dużego scalania gałęzi obiektów?

40

Powiedzieć wiele oddziałów są opracowywane, Aa B, a także przyrostowe „bug fix” oddział C.

Teraz Cjest już „gotowy” i scalony w master. Ai Bwciąż są w fazie rozwoju i nie zostaną naprawione, zanim (być może) kolejna gałąź naprawy błędów nie zostanie połączona z master.

Czy dobrym pomysłem jest Cjak najszybsze scalenie w nowych gałęziach funkcji? Aby nowe funkcje były masterjak najbliżej? Czy może lepiej pozwolić, by nowa funkcja została opracowana we własnym „świecie” dopiero po zakończeniu?

W każdym razie będą konflikty, więc trzeba poświęcić czas na ich naprawienie.

paul23
źródło
5
@gnat, który polega na łączeniu gałęzi funkcji w linię główną, zastanawiam się, czy scalenie głównego z powrotem w funkcję podczas opracowywania funkcji jest dobre, aby „wcześnie rozwiązać konflikty”.
paul23
1
@ Paul23, powiedziałbym, że jest to praktyczna konieczność.
Berin Loritsch
3
Szczerze mówiąc, wiele problemów z wersjonowaniem zniknęło, kiedy zacząłem używać odpowiedniego projektu w moim kodzie, na przykład izolowania modułów i tworzenia dobrze zdefiniowanego modelu pracy. Jeśli podczas łączenia zbytnio natkniesz się na problemy, możesz gdzieś czaić się inny, poważniejszy problem. Dobry projekt jest niezwykle pomocny w unikaniu niepotrzebnych konfliktów.
T. Sar - Przywróć Monikę
2
Możesz regularnie łączyć się z mistrzem, aby pozostać blisko „wystarczająco”, aby połączenie nie stało się zbyt bolesne.
Thorbjørn Ravn Andersen

Odpowiedzi:

71

Im dłużej gałąź żyje, tym bardziej jest w stanie odejść od gałęzi głównej, a bałagan i bardziej skomplikowane, powstałe scalenie nastąpi, gdy w końcu zostanie zakończone. Dziesięć małych konfliktów jest łatwiejszych do rozwiązania niż 1 ogromny konflikt i może faktycznie uniemożliwić programistom kopiowanie lub marnowanie wysiłku. Biorąc to pod uwagę, powinieneś łączyć mastersię Ai Bregularnie; raz dziennie jest dość powszechną rekomendacją, ale jeśli masz dużo aktywności w swoich oddziałach, możesz chcieć połączyć kilka razy dziennie.

Oprócz ułatwienia rozwiązywania konfliktów, w szczególności wspominasz Co gałęzi z poprawkami błędów. Jako programista chciałbym, aby mój oddział miał wszystkie najnowsze poprawki błędów, aby upewnić się, że nie powtarzam zachowania prowadzącego do błędu ani nie piszę testów opartych na błędnych danych.

W każdym razie będą konflikty, więc trzeba poświęcić czas na ich naprawienie.

Jeśli wiesz, że będą konflikty, możesz zastosować inną strategię rozgałęziania. Przechowuj wiele zmian w tym samym pliku (plikach) w tej samej gałęzi, gdy tylko jest to możliwe, a redukujesz lub eliminujesz liczbę konfliktów. Zmodernizuj historie, aby były w pełni niezależne, o ile to możliwe, i przerób gałęzie, aby ewentualnie obejmowały wiele historii (gałąź, cecha i historia nie zawsze są wymienne).

mmathis
źródło
33
Scal lub rebase , ponieważ rebasing często tworzy czystszą historię zatwierdzeń.
Chrylis
11
@chrylis: Rebasing może być niebezpieczny, jeśli „oddziały obejmują wiele historii” oznacza, że ​​dwóch programistów pracuje nad tym samym oddziałem.
meriton - podczas strajku
9
@meriton z oficjalnych dokumentów: nie zmieniaj baz danych, które istnieją poza Twoim repozytorium, a ludzie mogą na nich opierać pracę. Jeśli zastosujesz się do tych wytycznych, nic ci nie będzie. Jeśli tego nie zrobisz, ludzie będą cię nienawidzić, a będziesz pogardzany przez przyjaciół i rodzinę. LOL
Xtreme Biker
6
@XtremeBiker: Baza danych w Git zmienia historię. Pod tym względem Git działa jak prawdziwy: aby zmienić historię, potrzebujesz spisku. W repozytorium znajduje się gałąź dla samego Gita, która jest regularnie zmieniana i jest bardzo publiczna. Powodem tego jest spisek: wszyscy korzystający z tego oddziału zgadzają się na ponowne zapisanie historii w określonych momentach, więc upewnią się, że będą w stanie połączyć wszystko do tego czasu.
Jörg W Mittag
1
@ paul23 Poważnie rozważ dostarczenie A i B do nowego udostępnionego oddziału, zanim dostarczysz je do master. Jeśli są to radykalne przeglądy, chcesz je razem na rundę testów przed nałożeniem kombinacji na mistrza. Jeśli jesteś pewien, możesz dostarczyć jeden bezpośrednio do master, a następnie dostarczyć do świeżo zaktualizowanego oddziału. Prawdopodobnie będziesz chciał spojrzeć na oryginalny kod z drugiej funkcji na wypadek, gdyby scalenie poszło źle lub trzeba coś przeprojektować.
Sinc
11

Zakładając, że masz zamiar ostatecznie połączyć A, B z powrotem w master i utrzymywać jedną bazę kodu, nigdy nie jest dobrym pomysłem zbyt duże odstępstwo od master. Zbyt długie odstępstwo od głównego, zwłaszcza gdy poprawki błędów i inne prace rozwojowe łączą się z głównym w trakcie opracowywania A, B, z pewnością spowoduje konflikty.

Rozważę strategie podobne do następujących

  1. Ktokolwiek jest odpowiedzialny za A, B, powinien uważnie obserwować mistrza i scalać wszelkie zmiany.
  2. Jeszcze lepiej, jeśli masz wbudowaną i testowaną automatyzację, upewnij się, że A, B łączą się w trybie master i zdają testy co noc.
  3. Opierając się na komentarzach do innych odpowiedzi, wydaje się, że opracowanie A, B może trochę potrwać. W takim przypadku możesz nawet rozważyć połączenie A, B, aby w końcu nie mieć większych problemów z połączeniem obu z powrotem w master.
  4. Na wyższym poziomie zastanów się, dlaczego potrzebujesz 2 osobnych linii długiego rozwoju. Czy możesz podzielić na mniejsze połączenia? Czy możesz włamać się do oddzielnych mikrousług?
kenchew
źródło
5

Zwykle często jest lepszy niż masywny.

Mniejsze, częstsze żądania ściągania są prawie zawsze lepsze.

Zacząłem używać flag konfiguracji przede wszystkim po to, aby móc wykonywać wczesne mniejsze żądania ściągania, aby z kolei móc łatwiej scalać kod, ale pozostawić tę funkcję nieaktywną. Im mniejsze żądanie ściągnięcia, tym łatwiej jest przejrzeć kod, nawet jeśli jest więcej żądań ściągnięcia ogółem. Większość ludzi nie będzie w stanie dokonać sensownych recenzji masowych żądań ściągnięcia. To zbyt trudne dla pamięci RAM, aby zrozumieć wszystkie możliwe implikacje ogromnej zmiany kodu.

Tworzenie flagi konfiguracji wiąże się z dodatkowymi kosztami, więc w przypadku mniejszych funkcji nie warto. Ale wtedy twoje żądanie ściągnięcia i tak będzie niewielkie.

Mogą jednak wystąpić sytuacje, w których funkcja musi zostać wypuszczona jednocześnie. Nawet wtedy może być lepiej wykonać mniejsze żądania ściągania do innego oddziału wykonanego w tym celu.

Większość moich kolegów jęczy, gdy ktoś wysyła masowe żądanie ściągnięcia, i w większości słusznie.

Zauważ też, że czasami muszę wybijać zobowiązania do oddzielnych gałęzi. Jeśli to, co musi zostać zebrane w wiśni, można umieścić w jednym zatwierdzeniu, ułatwia to przenoszenie go do innych gałęzi. Jest to przypadek, w którym posiadanie niewielkiej liczby zatwierdzeń jest lepsze, ale nie jest to dokładnie standardowy proces, jeśli wybieracie wiśnię.

Mark Rogers
źródło
1
Flagi obiektów mogą być kosztowne (450 milionów USD w 45 minut). Ten przykład jest również wspomniany przez wuja Boba (ale bez żadnych technicznych (jak można by się spodziewać)).
Peter Mortensen
1
Tak, jest to koszt związany z ich ostatecznym usunięciem, chociaż zwykle nie jest to takie trudne. Można je utrzymywać dłużej, ale flaga zapewnia większe wykorzystanie. Zgadzam się, że jeśli dzieje się to przypadkowo lub bez dalszych działań, sprawy mogą pójść źle. Choć sytuacja może się pogorszyć, gdy trudne jest sprawdzenie dużego żądania ściągnięcia. Z drugiej strony niektóre osoby mogą nie być w stanie dodać czegoś takiego jak flaga konfiguracji do aplikacji, którą pracują. Zasadniczo pomaga to w UAT i wdrażaniu funkcji.
Mark Rogers
3

W Refactoring autorstwa Martina Fowlera rada, której udziela, nigdy nie pozwala rozgałęzić się od mistrza na dłużej niż jeden dzień. IIRC, powinieneś wprowadzić małą zmianę, przetestować, aby upewnić się, że niczego nie złamałeś, a następnie scalić z powrotem.

JohnnyApplesauce
źródło
2
Cóż Ai Bprzeprowadzaj gruntowne nowe zmiany w działaniu aplikacji, nie zostaną one „wykonane” w ciągu miesiąca. Jednak są też bezużyteczne, zanim
skończą
8
Mogą nie być bezużyteczne, zanim zostaną wykonane - zapewniają wartość, ponieważ są krokiem w kierunku pełnego wyniku i zmniejszają nakład pracy wymagany w przyszłości. Używając technik takich jak przełączanie cech, rozgałęzienie według abstrakcji lub po prostu wykonanie części interfejsu użytkownika na końcu, powinno być możliwe bezpieczne scalenie niekompletnej pracy do opanowania.
bdsl
1
dlatego bazowanie na lokalnych zmianach nad wszelkimi zmianami w gałęzi master jest przydatne dla długoterminowego rozwoju. Utrzymuje twoją pracę tak, jakby była rozgałęziona od najnowszego
NKCampbell
2

Inną opcją dla naprawdę długo trwających zmian, które mogą być zakończone, ale nie są gotowe do użycia, jest umieszczenie ich za flagą funkcji, aby można je było scalić w celu opanowania, ale nie ma ryzyka uszkodzenia niczego. Następnie, gdy są gotowe do użycia, można usunąć flagę funkcji.

Qwertie
źródło
1
Flagi funkcji = kod zombie (do wskrzeszenia)?
Peter Mortensen
@PeterMortensen Cóż, musisz dążyć do jak najszybszego usunięcia flag, ale może to działać w niektórych sytuacjach
Qwertie
3
@PeterMortensen nie, jeśli flaga jest włączona dla co najmniej jednej osoby
Ian