Rozważ następującą sytuację:
- Masz klon repozytorium git
- Masz kilka lokalnych zatwierdzeń (które nie zostały jeszcze nigdzie wypchnięte)
- W zdalnym repozytorium znajdują się nowe zatwierdzenia, których jeszcze nie uzgodniono
Więc coś takiego:
Jeśli wykonasz git pull
ustawienia domyślne, otrzymasz coś takiego:
Jest tak, ponieważ git wykonał scalenie.
Istnieje jednak alternatywa. Możesz zamiast tego powiedzieć pullowi, aby zrobił rebase:
git pull --rebase
a dostaniesz to:
Moim zdaniem, wersja rebased ma wiele zalet, które głównie skupiają się na utrzymaniu czystości zarówno twojego kodu, jak i historii, więc jestem nieco zaskoczony faktem, że git domyślnie łączy się. Tak, skróty twoich lokalnych zobowiązań zostaną zmienione, ale wydaje się, że to niewielka cena za prostszą historię, którą dostajesz w zamian.
W żadnym wypadku jednak nie sugeruję, że jest to jakaś zła lub niewłaściwa domyślna wartość. Mam problem z ustaleniem powodów, dla których scalenie może być preferowane jako domyślne. Czy mamy jakiś wgląd w to, dlaczego został wybrany? Czy istnieją korzyści, które sprawiają, że jest bardziej odpowiedni jako domyślny?
Główną motywacją tego pytania jest to, że moja firma próbuje ustalić pewne podstawowe standardy (mam nadzieję, że bardziej podobne wytyczne) dotyczące tego, jak organizujemy nasze repozytoria i zarządzamy nimi, aby ułatwić programistom dostęp do repozytorium, z którym wcześniej nie pracowali. Interesuje mnie uzasadnienie, że zwykle powinniśmy dokonywać zmian w bazie w tego typu sytuacjach (i prawdopodobnie za zalecenie programistom domyślnego ustawienia globalnej konfiguracji na bazę), ale gdybym się temu sprzeciwił, z pewnością zapytałbym, dlaczego zmiana bazy nie jest Domyślne, jeśli jest tak świetne. Zastanawiam się więc, czy czegoś mi brakuje.
Zasugerowano, że to pytanie jest duplikatem Dlaczego tak wiele stron internetowych woli „git rebase” niż „git merge”? ; pytanie to jest jednak odwrotnością tego pytania . Omówiono zalety ponownego łączenia w stosunku do scalania, podczas gdy to pytanie dotyczy korzyści płynących z scalania w stosunku do łączenia. Odpowiedzi tam odzwierciedlają to, koncentrując się na problemach ze scalaniem i korzyściach z rebase.
Odpowiedzi:
Trudno ustalić na pewno, dlaczego scalenie jest domyślne, bez wiadomości od osoby, która podjęła tę decyzję.
Oto teoria ...
Git nie może zakładać, że można - zerwać przy każdym pociągnięciu. Posłuchaj, jak to brzmi. „Rebase przy każdym pociągnięciu”. po prostu brzmi źle, jeśli używasz żądań ściągania lub podobnych. Czy zrezygnowałbyś z bazy na żądanie ściągnięcia?
W zespole, który nie korzysta tylko z Git do scentralizowanej kontroli źródła ...
Możesz ciągnąć z góry i z dołu. Niektóre osoby często ściągają od dostawców, od współpracowników itp.
Możesz pracować nad funkcjami w ścisłej współpracy z innymi programistami, czerpiąc z nich lub ze współdzielonej gałęzi tematów i wciąż od czasu do czasu aktualizując z góry. Jeśli zawsze będziesz bazować, zmienisz wspólną historię, nie mówiąc już o zabawnych cyklach konfliktów.
Git został zaprojektowany z myślą o dużym, rozproszonym zespole, w którym każdy nie ściąga i nie naciska na jedno centralne repo. Domyślnie ma to sens.
Oto dowód zamiaru, oto link do dobrze znanego e-maila od Linusa Torvaldsa z jego poglądami na temat tego, kiedy nie powinni się opierać. Dri-devel git pull email
Jeśli podążysz za całym wątkiem, zobaczysz, że jeden programista pobiera od innego programisty, a Linus ciągnie od obu. Wyraźnie wyraża swoją opinię. Ponieważ prawdopodobnie zdecydował o domyślnych ustawieniach Gita, może to wyjaśniać dlaczego.
Wiele osób korzysta teraz z Git w sposób scentralizowany, w którym wszyscy w małym zespole korzystają tylko z centralnego repozytorium i przekazują dane do tego samego pilota. W tym scenariuszu unika się niektórych sytuacji, w których zmiana bazy nie jest dobra, ale zwykle ich nie eliminuje.
Sugestia: Nie rób polityki zmiany wartości domyślnej. Za każdym razem, gdy umieścisz Git razem z dużą grupą programistów, niektórzy programiści nie zrozumieją Git aż tak głęboko (łącznie ze mną). Pójdą do Google, SO, uzyskają porady dotyczące książek kucharskich, a następnie zastanowią się, dlaczego niektóre rzeczy nie działają, np. Dlaczego
git checkout --ours <path>
otrzymano niewłaściwą wersję pliku? Zawsze możesz zmienić swoje lokalne środowisko, stworzyć aliasy itp., Aby dopasować je do swoich upodobań.źródło
Jeśli czytasz stronę git dla rebase, mówi :
Myślę, że jest to wystarczający powód, aby w ogóle nie używać bazy, a co dopiero automatycznie robić to przy każdym pociągnięciu. Niektórzy uważają, że rebase jest szkodliwy . Być może nigdy nie powinien był zostać wprowadzony do git, ponieważ wszystko, co wydaje się robić, to upiększać historię, coś, co nie powinno być konieczne w żadnym SCM, którego jednym zasadniczym zadaniem jest zachowanie historii.
Kiedy mówisz „utrzymywanie ... historii w czystości”, myśl, że się mylisz. To może wyglądać ładniej, ale w przypadku narzędzia zaprojektowanego do przechowywania historii poprawek, o wiele czystsze jest utrzymywanie każdego zatwierdzenia, abyś mógł zobaczyć, co się stało. Odkażanie historii jest jak polerowanie patyny, dzięki czemu bogaty antyk wygląda jak błyszczące repro :-)
źródło
Masz rację, zakładając, że masz tylko jedno lokalne / zmienione repozytorium. Weźmy jednak na przykład pod uwagę drugi lokalny komputer.
Gdy twoja lokalna / zmodyfikowana kopia zostanie wypchnięta gdzieś indziej, cofanie bazy spowoduje zepsucie tych kopii. Oczywiście możesz wymusić pchanie, ale szybko to się komplikuje. Co się stanie, jeśli jeden lub więcej z nich ma inne całkowicie nowe zatwierdzenie?
Jak widać, jest to bardzo sytuacyjne, ale strategia podstawowa wydaje mi się (o wiele) bardziej praktyczna w sprawach nietypowych / współpracy.
Druga różnica: strategia łączenia zachowa przejrzystą i spójną czasowo strukturę. Po zmianach bazy bardzo prawdopodobne jest, że starsze zmiany mogą śledzić nowsze zmiany, co utrudnia zrozumienie całej historii i jej przebiegu.
źródło
Głównym powodem jest prawdopodobnie to, że domyślne zachowanie powinno „po prostu działać” w publicznych repozytoriach. Odbudowywanie historii, którą inni już scalili, spowoduje kłopoty. Wiem, że mówisz o swoim prywatnym repozytorium, ale ogólnie mówiąc, git nie wie ani nie obchodzi, co jest prywatne lub publiczne, więc wybrana domyślna będzie domyślna dla obu.
Używam
git pull --rebase
całkiem sporo w moim prywatnym repozytorium, ale nawet tam ma potencjalną wadę, polegającą na tym, że historia mojegoHEAD
nie odzwierciedla już drzewa, tak jak faktycznie nad nim pracowałem.Na przykład: załóżmy, że zawsze uruchamiam testy i upewniam się, że zdają przed zatwierdzeniem. Ma to mniejsze znaczenie po zrobieniu a
git pull --rebase
, ponieważ nie jest już prawdą, że drzewo w każdym z moich zatwierdzeń przeszło testy. Dopóki zmiany nie ingeruje w żaden sposób, a kod pociągnąć został przetestowany, to prawdopodobnie to by przejść testy, ale nie wiem, bo ja nigdy nie próbowałem. Jeśli ciągła integracja jest ważną częścią twojego przepływu pracy, to każdy rodzaj bazowania w repozytorium, który jest CIed, jest kłopotliwy.Nie przeszkadza mi to, ale przeszkadza niektórym ludziom: woleliby, aby ich historia w git odzwierciedlała kod, nad którym faktycznie pracowali (a może zanim to pchnęli, uproszczoną wersję prawdy po pewnym użyciu) „naprawy”).
Nie wiem, czy ten problem jest przyczyną, dla której Linus zdecydował się na scalenie, a nie na domyślną wersję bazową. Mogą występować inne wady, z którymi się nie spotkałem. Ale ponieważ nie boi się wyrażać swojej opinii w kodzie, jestem prawie pewien, że sprowadza się to do tego, co uważa za odpowiedni przepływ pracy dla osób, które nie chcą za dużo o tym myśleć (a zwłaszcza tych, które pracują publicznie niż prywatne repozytorium). Unikanie równoległych linii na ładnym wykresie, na korzyść czystej linii prostej, która nie reprezentuje równoległego rozwoju, jak to się stało, prawdopodobnie nie jest jego najwyższym priorytetem, chociaż należy do ciebie :-)
źródło