Rebasing i co oznacza zmiana bazy zatwierdzonych zatwierdzeń

109

Często mówi się, że nie powinieneś zmieniać bazy zatwierdzeń, które już wypchnąłeś. Co to może znaczyć?

Hemant Kumar
źródło

Odpowiedzi:

80

Książka ProGit ma dobre wyjaśnienie .

Dokładną odpowiedź na swoje pytanie można znaleźć w części zatytułowanej „ Niebezpieczeństwa ponownego zbrojenia ”. Cytat z tej sekcji:

Kiedy zmieniasz bazę, porzucasz istniejące zatwierdzenia i tworzysz nowe, które są podobne, ale różne. Jeśli gdzieś popchniesz zatwierdzenia, a inni ściągną je i oprze na nich pracę, a następnie przepiszesz te zatwierdzenia za pomocą git rebase i ponownie je popchniesz, Twoi współpracownicy będą musieli ponownie scalić swoją pracę, a gdy spróbujesz, wszystko się pogmatwa wciągnij ich pracę z powrotem do swojej.

Aktualizacja:
na podstawie Twojego komentarza poniżej wygląda na to, że masz problemy z przepływem pracy Git. Oto kilka referencji, które mogą pomóc:

Tim Henigan
źródło
Dziękuję za wyjaśnienie. Tak więc, żeby lepiej zrozumieć, że po wprowadzeniu pewnych zmian nie powinienem używać git rebase(--interactive?) Do przepisywania tej historii, to jest pewny przepis na porażkę. gałąź (z gałęzi X) i wypchnij ją, zupełnie normalne jest ponowne wykonanie bazy po zmianie gałęzi tematycznej przez innego programistę. Zasadniczo używam go od jakiegoś mergeczasu, ale jedziemy na tej samej łodzi co darwinweb.net/articles/86, a historia jest prawie bezużyteczna.
Hemant Kumar
@Hemant: Ponowne zatwierdzanie zatwierdzeń po wypchnięciu do publicznego repozytorium jest ogólnie złym pomysłem. To powiedziawszy, rada z cytowanego przez ciebie artykułu na darwinweb wydaje się rozsądna, jeśli twój przepływ pracy przypomina ich. Zobacz moją zaktualizowaną odpowiedź, aby uzyskać listę innych odniesień, które mogą pomóc.
Tim Henigan
Zaktualizuj link do strony „ProGit” o „Zarządzanym zespole prywatnym” na git-scm.com/book/en/ ...
Eimantas
Tak więc technicznie rzecz biorąc, zmiany git pozostają takie same, ale „porzucanie istniejących zatwierdzeń i tworzenie nowych, które są podobne, ale różne”, są tym samym zatwierdzeniem z innym identyfikatorem sha1? cóż, byłby to jedyny oczywisty sposób, w jaki mogę sobie wyobrazić, dlaczego współpracownicy musieliby ponownie scalić swoje prace!
Ciasto piekarz
@Ciastopiekarz, dzieje się tak, ponieważ przepisujesz historię w repozytorium nadrzędnym, a lokalne repozytoria innych programistów mogą mieć na to wskazówki. Teraz ich wskazówki są nieaktualne: klient git nie ma innego wyjścia, jak tylko użyć starszych wskaźników i polegać na człowieku, aby zająć się resztą. To jest ponowne scalanie i może być BARDZO bałagan z wieloma mylącymi zmianami, które muszą być ręcznie uporządkowane! Dlatego zalecenie, aby nigdy nie zmieniać bazy niczego, co zostało już przesłane do repozytorium wyższego szczebla. To dobra rada i nie należy jej ignorować, chyba że jesteś ekspertem z głęboką wiedzą.
Forbin
240

Aby to zrozumieć, musimy trochę zrozumieć, jak działa git. Repozytorium git to struktura drzewa, w której węzły drzewa są zatwierdzone. Oto przykład bardzo prostego repozytorium: Kiedy widelec

ma cztery zatwierdzenia w gałęzi głównej, a każde zatwierdzenie ma identyfikator (w tym przypadku a, b, c i d). Zauważysz, że d jest obecnie najnowszym zatwierdzeniem (lub HEAD) gałęzi master. wprowadź opis obrazu tutaj

Tutaj mamy dwie gałęzie: master i my-branch. Możesz zobaczyć, że zarówno master, jak i my-branch zawierają zatwierdzenia a i b, ale potem zaczynają się rozchodzić: master zawiera c i d, podczas gdy my-branch zawiera e i f. b jest określany jako „baza scalania” mojej gałęzi w porównaniu do nadrzędnej - lub częściej, po prostu „podstawa”. Ma to sens: widać, że moja gałąź była oparta na poprzedniej wersji mastera.

Powiedzmy, że moja gałąź jest nieaktualna i chcesz ją zaktualizować do najnowszej wersji master. Mówiąc inaczej, moja gałąź musi zawierać c i d. Możesz wykonać scalanie, ale to powoduje, że gałąź zawiera dziwne zatwierdzenia scalania, które znacznie utrudniają przeglądanie żądania ściągnięcia. Zamiast tego możesz wykonać rebase.

wprowadź opis obrazu tutaj

Kiedy zmieniasz bazę, git znajduje podstawę twojej gałęzi (w tym przypadku b), znajduje wszystkie zatwierdzenia między tą bazą a HEAD (w tym przypadku eif) i odtwarza te zatwierdzenia na HEAD gałęzi opierasz się na (w tym przypadku mistrzu). Git faktycznie tworzy nowe zatwierdzenia, które reprezentują wygląd twoich zmian na górze master: na diagramie te zatwierdzenia nazywane są e ′ i f ′. Git nie usuwa twoich poprzednich zatwierdzeń: eif pozostają nietknięte, a jeśli coś pójdzie nie tak z rebase, możesz od razu wrócić do poprzedniego stanu.

Gdy wiele różnych osób pracuje nad projektem w sposób symulowany, żądania ściągnięcia mogą szybko się starzeć. „Nieaktualne” żądanie ściągnięcia to takie, które nie jest już aktualne w stosunku do głównej linii rozwoju i musi zostać zaktualizowane, zanim będzie można je scalić z projektem. Najczęstszym powodem, dla którego żądania ściągnięcia stają się nieaktualne, są konflikty: jeśli dwa żądania ściągnięcia zmodyfikują podobne wiersze w tym samym pliku, a jedno żądanie ściągnięcia zostanie scalone, niescalone żądanie ściągnięcia będzie teraz miało konflikt. Czasami żądanie ściągnięcia może stać się nieaktualne bez konfliktów: być może zmiany w innym pliku w bazie kodu wymagają odpowiednich zmian w żądaniu ściągnięcia, aby były zgodne z nową architekturą, lub być może gałąź została utworzona, gdy ktoś przypadkowo połączył niepowodzenia testów jednostkowych z gałąź główna. Niezależnie od powodu

pseudoCoder
źródło
68

Rebasing przepisuje historię. Jeśli nikt nie wie o tej historii, to jest w porządku. Jeśli jednak ta historia jest publicznie znana, przepisywanie historii w Git działa tak samo, jak w prawdziwym świecie: potrzebujesz spisku.

Konspiracje są naprawdę trudne do utrzymania razem, więc lepiej w pierwszej kolejności unikać ponownego budowania publicznych oddziałów.

Zauważ, że tam przykłady udanych spisków: the puoddział git repozytorium Junio C. Hamano za (oficjalnym repozytorium GIT SCM) jest często rebased. Sposób, w jaki to działa, polega na tym, że prawie każdy, kto używa, pujest również zapisany na listę mailingową programistów Git, a fakt, że pugałąź jest przekształcona, jest szeroko publikowany na liście mailingowej i na stronie internetowej Git.

Jörg W Mittag
źródło
4
+1. Myślę, że pugałąź git.git jest niezwykle pomocnym przykładem wykorzystania rebase w (publicznym) przepływie pracy. Dla tych, którzy go nie znają, ogólną ideą jest ponowne bazowanie gałęzi tematycznych, w których nie ma żadnych zatwierdzeń next(gałąź niestabilna tuż przed scaleniem do master), a następnie odbudowanie pugałęzi przez zresetowanie do nexti scalenie wszystkich gałęzi tematu. (Źródło: Documentation / howto / maint-git.txt git.kernel.org/?p=git/git.git;a=blob;f=Documentation/howto/… )
Cascabel
25
+1 za „przepisywanie historii w Git działa tak samo, jak w prawdziwym świecie: potrzebujesz konspiracji”
Sleeper Smith
„Ogłoszenie publiczne nie jest konieczne, ponieważ pu jest gałęzią jednorazowego użytku, jak opisano powyżej”. git-scm.com/docs/gitworkflows Robimy coś podobnego w pracy, "TEMP-coś-najnowsze" to gałąź do wyrzucenia będąca połączeniem najnowszych zmian, może być połączeniem wielu gałęzi funkcji, może zostać usunięta i odtworzone w dowolnym momencie i nie powinny być rozwijane dalej.
pilkch
6

Rebase zmienia historię Twojego repozytorium. Jeśli wypchniesz zobowiązania na świat, tj. Udostępnisz je innym, a potem zmienisz swój pogląd na historię zmian, trudno będzie pracować z kimkolwiek, kto ma Twoją starą historię.

Myślę, że Rebase uważany za szkodliwy to dobry przegląd.

dsolimano
źródło