git pull
prawdopodobnie tworzy zatwierdzenie. Jeśli wykonasz lokalne zatwierdzenie, a następnie uruchomiszgit pull
po tym, jak ktoś inny umieści zatwierdzenie w repozytorium, Git pobierze zatwierdzenie innego programisty, a następnie scali go z lokalną gałęzią.
Jak uniknąć tych zatwierdzeń scalających w przyszłości
Mógłbyś użyć, git pull --rebase
aby temu zapobiec w przyszłości, ale ponowne bazowanie ma swoje niebezpieczeństwa i zalecam pull
całkowite unikanie tego .
Zamiast tego zachęcam do przestrzegania tego schematu użytkowania:
# download the latest commits
git remote update -p
# update the local branch
git merge --ff-only @{u}
# if the above fails with a complaint that the local branch has
# diverged:
git rebase -p @{u}
Wyjaśnienie
git remote update -p
pobiera wszystkie zatwierdzenia ze zdalnych repozytoriów i aktualizuje zdalne gałęzie śledzenia (np origin/master
.). NIE dotyka twojego katalogu roboczego, indeksu ani lokalnych gałęzi.
Te -p
śliwki argumentów usunięte oddziałów wydobywczych. Zatem jeśli foo
oddział zostanie usunięty z origin
repozytorium, git remote update -p
automatycznie usunie Twój origin/foo
ref.
git merge --ff-only @{u}
mówi Gitowi, aby scalił gałąź upstream ( @{u}
argument) z gałęzią lokalną, ale tylko wtedy, gdy gałąź lokalna może zostać „szybko przekazana” do gałęzi upstream (innymi słowy, jeśli się nie rozdzieliła).
git rebase -p @{u}
efektywnie przenosi zatwierdzenia, które stworzyłeś, ale nie zostały jeszcze umieszczone na górnej gałęzi, co eliminuje potrzebę tworzenia głupich zatwierdzeń scalających, których próbujesz uniknąć. Poprawia to liniowość historii rozwoju, ułatwiając przeglądanie.
Ta -p
opcja mówi Gitowi, aby zachować scalenia. Zapobiega to linearyzacji zatwierdzeń przez Git. Jest to ważne, jeśli na przykład scaliłeś gałąź funkcji z master
. Bez tego -p
każde zatwierdzenie w gałęzi feature byłoby zduplikowane master
jako część linearyzacji wykonywanej przez git rebase
. Utrudniłoby to przeglądanie historii rozwoju, a nie łatwiejsze.
Uwaga : git rebase
możesz nie robić tego, czego oczekujesz, więc przejrzyj wyniki przed naciśnięciem. Na przykład:
git log --graph --oneline --decorate --date-order --color --boundary @{u}..
Preferuję to podejście git pull --rebase
z następujących powodów:
- Pozwala to zobaczyć nadchodzące zmiany typu upstream przed zmodyfikowaniem historii w celu ich uwzględnienia.
- Umożliwia przekazanie opcji
-p
( --preserve-merges
) dogit rebase
w przypadku konieczności zmiany bazy zamierzonego scalenia (np. Scalenia już wypchniętej gałęzi funkcji do master
).
Stenografia: git up
zamiastgit pull
Aby ułatwić powyższe, polecam utworzenie aliasu o nazwie up
:
git config --global alias.up '!git remote update -p; git merge --ff-only @{u}'
Teraz wszystko, co musisz zrobić, aby zaktualizować swój oddział, to uruchomić:
git up
zamiast git pull
. Jeśli pojawi się błąd, ponieważ lokalna gałąź oddzieliła się od gałęzi upstream, jest to wskazówka do ponownej bazy danych.
Dlaczego nie git pull --rebase
?
Bieganie git pull --rebase
jest równoznaczne z bieganiem, git fetch
po którym następujegit rebase
. To próbuje szybko przewinąć do nowych zatwierdzeń upstream, ale jeśli to nie jest możliwe, to przełoży twoje lokalne zatwierdzenia do nowych zatwierdzeń upstream. Zwykle jest to w porządku, ale bądź ostrożny:
- Rebase to zaawansowany temat i przed zmianą bazy należy zrozumieć konsekwencje.
git pull --rebase
nie daje możliwości zbadania zatwierdzeń przed ich wprowadzeniem. W zależności od tego, co upstream zmieniło, to całkiem możliwe, że rebase jest zła praca-a rebase --onto
, merge
, reset
, lub push -f
może być bardziej odpowiednie niż zwykłyrebase
.
- Nie jest (obecnie) możliwe przejście
--preserve-merges
do operacji rebase, więc każde celowe scalenie gałęzi funkcji zostanie zlinearyzowane, odtwarzając (a tym samym powielając) wszystkie zatwierdzenia gałęzi funkcji.
„Naprawianie” istniejącego zatwierdzenia scalającego utworzonego przez git pull
Jeśli jeszcze nie wypchnąłeś zatwierdzenia scalającego utworzonego przez git pull
, możesz zmienić bazę zatwierdzenia scalającego. Zakładając, że nie dokonałeś żadnych celowych scaleń (np. Scalenie już wypchniętej gałęzi funkcji do bieżącej gałęzi), wykonaj następujące czynności:
git rebase @{u}
Powyższe polecenie nakazuje Gitowi wybranie wszystkich zatwierdzeń nie-scalających dostępnych z HEAD
(bieżącego zatwierdzenia), pomniejszonych o wszystkie zatwierdzenia osiągalne z @{u}
(co jest skrótem dla "gałęzi upstream", tj. origin/master
Jeśli HEAD
jest master
), powtórka (wybór wiśniowy ) je na górnej gałęzi, a następnie przenieś odwołanie do bieżącej gałęzi, aby wskazywało wynik ponownego odtworzenia zatwierdzeń. To skutecznie przenosi zatwierdzenie nie-scalające do ostatniego zatwierdzenia nadrzędnego, co eliminuje scalanie utworzone przezgit pull
.
Jeśli masz celowe zatwierdzenie przez scalanie, nie chcesz uruchamiać, git rebase @{u}
ponieważ odtworzy wszystko z innej gałęzi. Radzenie sobie z tym przypadkiem jest znacznie bardziej skomplikowane, dlatego dobrze jest go używać git up
i git pull
całkowicie unikać . Prawdopodobnie będziesz musiał użyć, reset
aby cofnąć scalenie utworzone przez, pull
a następnie to zrobić git rebase -p @{u}
. -p
Argument git rebase
nie działa niezawodnie dla mnie, więc może skończyć się konieczności korzystania reset
cofnąć celowe seryjnej, aktualizować swój lokalny oddział do @{u}
, a następnie przerobić celowe seryjnej (co jest uciążliwe, gdyby nie było dużo owłosionej seryjnej konflikty).