Co to są konflikty scalania?
W tym miejscu omówimy, w jaki sposób rozwiązywanie konfliktów scalania pomaga deweloperom uzyskać najlepszy wynik z dwóch nakładających się źródeł.
Przepływ w usłudze GitHub
Oprócz udostępniania platformy do współpracy nad tworzeniem oprogramowania usługa GitHub oferuje również wstępnie ustawiony przepływ pracy zaprojektowany w celu optymalizacji użycia jego różnych funkcji. Chociaż w tej lekcji opisano w szczególności konflikty scalania, zalecamy najpierw zapoznanie się z omówieniem przepływu usługi GitHub.
Scalanie gałęzi
Rozważmy scenariusz, w którym deweloper tworzy gałąź o nazwie feature-branch
opartą na gałęzi main
i tworzy dwa zatwierdzenia. Podczas wykonywania tej pracy ktoś inny scala niepowiązane żądanie ściągnięcia z gałęzią main
. Co się stanie, gdy nasz deweloper podejmie próbę scalenia gałęzi feature-branch
z powrotem z gałęzią main
?
Odpowiedź: to zależy.
Mimo feature-branch
że został utworzony na podstawie main
elementu , nie był oparty na samej gałęzi. Bazowała raczej na zatwierdzeniu NAGŁÓWKA gałęzi main
w danym momencie. Nie jest świadomy wszystkich zatwierdzeń, które zostały zastosowane main
od tego czasu. Zatwierdzenia, które obecnie śledzi, nie muszą być składane do bieżącego stanu gałęzi bez zastępowania ostatnich zmian.
Jeśli okaże się, że feature-branch
zatwierdzenia nie nakładają się na zatwierdzenia równoległe wykonane main
od momentu utworzenia gałęzi, nie ma problemów. Nowe pliki można dodać. Nienaruszone pliki można usunąć. Wiersze kodu, które zostały zmienione w gałęzi main
, można zmienić w gałęzi feature-branch
do czasu, gdy nie zostaną one zmienione w wyniku wykonywanych równolegle działań od czasu utworzenia gałęzi feature-branch
.
Ale co zrobić, jeśli oba zestawy zatwierdzeń zawierają zmiany dotyczące tych samych wierszy kodu? Ta próba scalania zakończy się niepowodzeniem z powodu konfliktu scalania.
Co to są konflikty scalania?
Konflikty scalania są zgłaszane, gdy deweloper podejmie próbę scalenia zmian, które spowodują nieumyślne nadpisanie zmian wprowadzonych równolegle. Nie ma przy tym znaczenia, w jaki sposób te zmiany zostały scalone z gałęzią bazową. Usługa Git nie zastępuje automatycznie jednego zestawu zmian na rzecz innego. Zamiast tego zwraca uwagę na osobę próbującą scalić, aby móc rozwiązać je w gałęzi porównania przed próbą scalenia ponownie.
Rozwiązywanie konfliktów scalania
Aby ułatwić rozwiązywanie konfliktów scalania, usługa GitHub generuje tymczasowy plik hybrydowy zawierający różnice między poszczególnymi gałęziami. Przyjęto konwencję, że tekst z gałęzi porównawczej jest wyświetlany nad tekstem z gałęzi bazowej. Oba teksty są rozdzielone wierszem składającym się ze znaków równości (=======
).
Jeśli zmiany są niewielkie, możesz bezpośrednio edytować ten plik w tym widoku. Jeśli zdecydujesz się go zachować, końcowy wynik zostanie zatwierdzony do gałęzi porównania. Alternatywnie, jeśli scalanie jest bardziej zaangażowane, możesz pracować nad nim przy użyciu innych narzędzi programistycznych. W obu przypadkach pamiętaj o usunięciu wszystkich znaczników gałęzi przed przeprowadzeniem zatwierdzenia. Jeśli zapomnisz usunąć te znaczniki podczas zatwierdzania rozwiązywania konfliktów, pozostają one w pliku i nie są komentowane.
Uwaga
W tej lekcji opisano proces rozwiązywania konfliktów scalania w kontekście przeglądarki. Istnieje również wiele platform programistycznych, takich jak Visual Studio, które oferują zintegrowane środowisko rozwiązywania konfliktów scalania.
Po rozwiązaniu wszystkich konfliktów scalania w gałęzi można ponowić próbę scalenia.
Unikanie konfliktów scalania
Niektórych konfliktów scalania nie da się uniknąć. Każde scalanie może potencjalnie spowodować konflikty scalania z innymi żądaniami ściągnięcia oczekującymi na zatwierdzenie. Jednym ze skutecznych sposobów zmniejszania złożoności konfliktów scalania jest częste ściąganie swojej gałęzi.
Wczesne i częste ściąganie
Polecenie git pull
ściąga wszystkie zatwierdzenia gałęzi podstawowej, które nie zostały jeszcze zastosowane do bieżącej gałęzi. Jest to koncepcyjnie podobne do polecenia Get Latest , którego używa wiele systemów kontroli wersji, aby umożliwić aktualizowanie kodu lokalnego do najnowszej wersji. Podczas ściągania aktualizacji gałęzi scalasz wszystkie zmiany, które wystąpiły od momentu utworzenia gałęzi (lub ostatniego ściągnięcia).
Ściąganie aktualizacji do gałęzi może spowodować konflikty scalania, ale jest to w porządku. W każdym razie dostaniesz je później, a przez ich wcześniejsze, często łatwiej jest rozwiązać problem.
Oprócz ograniczania wpływu konfliktów scalania ściąganie aktualizacji pozwala także integrować zatwierdzone zmiany z gałęzią w trakcie pracy. Dzięki temu można rozwiązać potencjalne problemy wcześniej. Na przykład w innych plikach mogą występować zmiany definicji klas, które powodują, że kod nie będzie już kompilowany. Ta zmiana nie spowoduje konfliktu scalania podczas scalania później, ale spowoduje to przerwanie kompilacji, jeśli nie została ona przetestowana jako pierwsza. Najlepszym rozwiązaniem jest częste ściąganie aktualizacji, aby Twoja gałąź była jak najbardziej podobna do gałęzi bazowej.
Czyszczenie historii za pomocą polecenia git rebase
Polecenie git rebase
(lub git pull --rebase
) ponownie zapisuje historię gałęzi, aby użyć bieżącego zatwierdzenia NAGŁÓWKA gałęzi bazowej jako bazy. Innymi słowy gałąź jest aktualizowana tak, aby zachowywała się tak, jakby była rozgałęziona tylko z bieżącego stanu gałęzi bazowej. Ta baza danych oznacza, że wszystkie zmiany są porównywane z najnowszym stanem gałęzi bazowej, a nie oryginalne zatwierdzenie, z którego pierwotnie rozgałęziono. Ponowne łączenie może ułatwić śledzenie historii po ewentualnej scalaniu, ponieważ zatwierdzenia będą zgodne z poprzednimi zatwierdzeniami równoległymi w sposób liniowy. Dobrym rozwiązaniem jest zmiana bazy gałęzi bezpośrednio przed przeprowadzeniem scalenia nadrzędnego.
Dowiedz się więcej na temat polecenia git rebase i rozwiązywania konfliktów scalania po zmianie bazy repozytorium Git.