Oto umowa, dołączyłem do nowej firmy i poproszono mnie o zakończenie pracy w oddziale, który nie był dotykany przez prawie rok. W międzyczasie gałąź master rozwijała się w stałym tempie. Idealnie chciałbym scalić wszystkie zmiany z gałęzi master do gałęzi funkcji i kontynuować pracę od tego momentu, ale nie jestem zbyt pewien, jak do tego podejść.
Jak bezpiecznie wykonać to scalanie, zachowując ważne zmiany po obu stronach oddziału?
version-control
git
gitflow
Vlad Spreys
źródło
źródło
git cherry-pick
tutaj skorzystać ?Odpowiedzi:
U podstaw tego, jak połączyć dwa (być może niekompatybilne) fragmenty kodu, jest problem programistyczny , a nie problem kontroli wersji . Polecenie scalania Git może pomóc w tym procesie, ale zależy to od kształtu problemu.
Najbardziej sensowne jest porównanie obu wersji z bazą. To da ci wyobrażenie najlepszej strategii dalszego rozwoju. Twoje podejście może być inne w zależności od charakteru i nakładania się zmian w każdej gałęzi.
Wyobraź sobie idealny scenariusz: odkryłbyś, że główna gałąź i gałąź funkcji modyfikowały tylko wykluczające się wzajemnie części kodu, więc możesz po prostu zatwierdzić wszystkie zmiany i być gotowym do pracy.
Oczywiście prawie na pewno tak nie będzie, ale pytanie brzmi: jak daleko od tego idealnego scenariusza będzie? tzn. jak przenikają się zmiany?
Jak dojrzała była stara gałąź funkcji? Czy był w dobrym stanie, czy nie (lub nieznany)? Ile funkcji zostało ukończonych?
Jeśli odpowiedni kod w głównej gałęzi bardzo się zmienił w ciągu ostatniego roku lub funkcja nie jest w bardzo dojrzałym stanie, mogę rozważyć utworzenie nowego widelca najnowszego i ręczne włączenie starej funkcji. Pozwoli ci to na stopniowe podejście do jego działania.
Jeśli zrobisz niechlujne połączenie dużej ilości kodu, ale to nie zadziała, będzie to bardzo trudne do debugowania. Jeśli główny oddział bardzo się zmienił w ciągu ostatniego roku, konieczne mogą być poważne zmiany w projekcie tej funkcji, aby działała. Nie byłoby właściwe wprowadzanie tych zmian za pomocą „rozwiązywania konfliktów”, ponieważ wymagałoby to wprowadzenia wszystkich zmian naraz i nadziei, że zadziała. Problem ten spotęgowałby możliwość błędów w starej, częściowo ukończonej gałęzi.
źródło
Z mojego ograniczonego doświadczenia w git mogę powiedzieć, że czasami szybsze jest ponowne uruchomienie gałęzi funkcji od nowa, jeśli master zaszedł zbyt daleko od punktu odłączenia.
Scalenie dwóch gałęzi bez znajomości historii kodu (biorąc pod uwagę, że właśnie dołączyłeś do projektu) jest naprawdę trudne, i założę się, że nawet programista, który śledził projekt od samego początku, prawdopodobnie popełniłby błędy podczas scalania.
Ma to oczywiście sens, jeśli gałąź funkcji nie jest ogromna, ale można po prostu pozostawić otwartą starą gałąź funkcji , gałąź ponownie z poziomu głównego i ręcznie ponownie wprowadzić zmiany, które składają się na tę funkcję. Wiem, że jest to najbardziej ręczne podejście, ale pozwala mieć pełną kontrolę w przypadku braku lub przeniesienia kodu.
Najlepszym scenariuszem byłoby sparowanie programowania ze starszym w tym przypadku, pomagając lepiej poznać kod.
Może nawet okazać się szybszy, jeśli weźmiesz pod uwagę konflikty scalania i czas testowania!
W pewnym sensie założyłem, że przynajmniej próba scalenia jest oczywiście najlepszą rzeczą do zrobienia. Jeśli to się nie powiedzie lub okaże się zbyt trudne, spróbuj zbierania wiśni, jeśli pójdzie nie tak, idź ręcznie.
źródło
git-imerge został zaprojektowany właśnie do tego celu. Jest to narzędzie git, które zapewnia metodę przyrostowego łączenia. Łącząc się stopniowo, wystarczy poradzić sobie z kolizjami między dwiema wersjami, nigdy więcej. Ponadto znacznie większa liczba połączeń może być wykonywana automatycznie, ponieważ poszczególne zestawy zmian są mniejsze.
źródło
Próba połączenia głowy głównej z jednoroczną gałęzią może być frustracją i pogłębieniem zagłębienia na biurku za pomocą czoła.
Linia główna nie dotarła do miejsca, w którym jest za jednym razem w ciągu miesięcy. To także miało zmiany i wydania. Próba aktualizacji tego wszystkiego w jednym monolitycznym połączeniu może być przytłaczająca.
Zamiast tego zacznij od scalenia od pierwszego scalenia funkcji z powrotem do linii głównej po podziale nieaktualnej gałęzi. Spraw, by scalenie działało. Następnie następna funkcja scalania. I tak dalej. Wiele z tych połączeń funkcji połączy się bez konfliktu. Nadal ważne jest, aby upewnić się, że bieżąca funkcjonalność przestarzałej gałęzi pozostaje zgodna z kierunkiem, w którym poszła linia główna.
Możesz rozgałęzić się na czele nieaktualnej gałęzi w celu scalenia innych zmian. Chodzi o to, aby upewnić się, że zatwierdzenia i historia, gdy ktoś na nie spojrzy, jest jasne i przekazuje rolę i zasady każdej gałęzi. Nieaktualna gałąź była gałąź funkcji. Ten, nad którym pracujesz, to gałąź akumulacji i pojednania.
Wiele z tego będzie łatwiejsze, jeśli stare gałęzie funkcji lub wydania nadal istnieją i są łatwo dostępne (niektóre miejsca mają zasady czyszczenia nazw gałęzi starszych niż niektóre daty, aby lista gałęzi nie była przytłaczająca ).
Ważną rzeczą w tym wszystkim jest upewnienie się, że testujesz i naprawiasz po udanym scaleniu każdej części historii głównej na swoim miejscu. Nawet jeśli coś może się łączyć bez konfliktów, oznacza to po prostu, że kod nie powodował konfliktu. Jeśli sposób dostępu do przestarzałej funkcji był przestarzały lub usunięty, po udanym scaleniu mogą być konieczne poprawki.
Nawiasem mówiąc, działa to również w przypadku innych systemów kontroli wersji. Czasami musiałem scalić określoną grupę zatwierdzeń SVN do gałęzi (wybieranie Cherry) dla jednej funkcji, naprawić gałąź do pracy z tą funkcją, a następnie scalić następną grupę zatwierdzeń SVN zamiast robić tylko hurtową SVN łączyć.
Chociaż można tutaj zrobić git cherry pick i pozwala to na wprowadzenie określonych zatwierdzeń, ma to pewne wady, które mogą skomplikować proces. Wybieranie wiśniowe nie pokaże informacji o pobranym zatwierdzeniu (możesz dołączyć je do wiadomości zatwierdzenia). To utrudnia śledzenie zmian w historii.
Co więcej, oznacza to, że nie zamierzasz skutecznie odtwarzać mistrza na nieaktualnej gałęzi - wybierasz możliwie niekompletne funkcje - i te funkcje mogą być odtwarzane poza kolejnością.
Kluczowym powodem, dla którego należy połączyć historyczne zobowiązania do opanowania starej gałęzi, jest możliwość zachowania, nazwijmy to „przyszłą historią” starej gałęzi w stanie, o którym można myśleć. Możesz wyraźnie zobaczyć połączenia z historii w przestarzałą gałąź i poprawki reintegrujące funkcjonalność. Funkcje są dodawane w tej samej kolejności, w jakiej były opanowane. A kiedy skończysz i w końcu wykonasz scalenie od głowy mistrza do przestarzałej gałęzi, wiesz, że wszystko zostało scalone i nie brakuje żadnych zobowiązań.
źródło
Krok 1. Poznaj kod, przeanalizuj jego architekturę i zmiany, które zostały wprowadzone w obu gałęziach od czasu ostatniego wspólnego przodka.
Krok 2. Jeśli funkcja wydaje się zasadniczo niezależna i dotyczy głównie różnych obszarów kodu, scalania, rozwiązywania konfliktów, testowania, naprawiania itp. To jest szczęśliwa ścieżka, którą możesz zrobić. W przeciwnym razie przejdź do kroku 3
Krok 3. Przeanalizuj obszary konfliktu, dokładnie zrozum funkcjonalny wpływ i przyczyny. Łatwo mogą pojawić się konflikty wymagań biznesowych. Porozmawiaj z licencjatami, innymi programistami, jeśli to konieczne. Poczuj złożoność związaną z usuwaniem zakłóceń.
Krok 4. W świetle powyższego, zdecyduj, czy chcesz scalić / wybrać / nawet wyciąć-wkleić tylko te części, które nie powodują konfliktu i ponownie pisać sprzeczne elementy, LUB czy ponownie napisać całą operację od zera .
źródło
1. Przejdź do gałęzi, która jest używana jako główna gałąź programisty / wydania.
To gałąź, która zawiera najnowsze zmiany w systemie. Może być
master
,core
,dev
, to zależy od firmy. W twoim przypadku jest to prawdopodobniemaster
bezpośrednio.Pociągnij, aby upewnić się, że masz najnowszą wersję głównej gałęzi rozwoju.
2. Przejdź do kasy i wyciągnij gałąź zawierającą pracę, którą chcesz zakończyć.
Ciągniesz, aby upewnić się, że rzeczywiście masz najnowszą zawartość oddziału. Sprawdzając to bezpośrednio, bez tworzenia go najpierw lokalnie, upewniasz się, że nie masz w nim nowej zawartości
master
(lub odpowiednio głównej gałęzi programistów).3. Połącz główną gałąź programistyczną z przestarzałą gałęzią.
git merge
Komenda spróbuje połączyć zawartości z określonej branży, w tym przypadkumaster
, do oddziału jesteś obecnie.Nacisk na spróbuje . Mogą występować konflikty scalania, które będą musiały zostać rozwiązane przez Ciebie i tylko Ciebie.
4. Napraw konflikty scalania, zatwierdź i wciśnij poprawkę konfliktu
Po naprawieniu konfliktu scalania we wszystkich plikach, na których się znajduje, wykonaj etap, zatwierdź i pchnij rozwiązanie konfliktu do
origin
.Zasadniczo można wywoływać
git add .
wszystkie pliki w celu zatwierdzenia. Podczas rozwiązywania konfliktów scalania chcesz zaktualizować wszystkie niezbędne pliki.Uwaga dodatkowa
Rozwiązanie konfliktu scalania może być żmudnym zadaniem. Zwłaszcza jeśli jesteś nowy w firmie. Być może jeszcze nie masz odpowiedniej wiedzy, aby samodzielnie rozwiązać wszystkie konflikty scalania.
Poświęć trochę czasu, aby dokładnie sprawdzić wszystkie konflikty, które miały miejsce, i odpowiednio je naprawić, przed kontynuowaniem pracy.
Może się zdarzyć, że zaczniesz pracować nad rocznym oddziałem, scalisz z nim obecny stan rozwoju i nie będzie żadnych konfliktów scalania.
Dzieje się tak, gdy choć system bardzo się zmienił w ciągu roku, nikt nie dotknął plików, które zostały faktycznie zmienione w rocznym oddziale.
źródło