git pull VS git fetch Vs git rebase

294

Inną kwestią powiedział git pulljest jak git fetch+ git merge.

Ale jaka jest różnica między git pullVS git fetch+ git rebase?

Michał
źródło
2
ktoś powinien wyczyścić link ... i jestem zdumiony, ile głosów uzyskało to drugie pytanie.
ksenoterrakid
13
@xeno: Myślę, że to tylko liczba osób, które pytają: „Też miałem to pytanie”
bobobobo
45
Pewnego dnia znajdę czas, aby naprawdę przeczytać dokumentację git, ale do tego czasu dodaję głosy do tego rodzaju pytań
Eran Medan

Odpowiedzi:

336

Z twojego pytania powinno być całkiem oczywiste, że w rzeczywistości pytasz tylko o różnicę między git mergei git rebase.

Załóżmy, że jesteś w typowym przypadku - wykonałeś trochę pracy nad gałęzią master i wyciągnąłeś z źródła, który również wykonał trochę pracy. Po pobraniu rzeczy wyglądają tak:

- o - o - o - H - A - B - C (master)
               \
                P - Q - R (origin/master)

Jeśli scalisz w tym momencie (domyślne zachowanie git pull), zakładając, że nie ma żadnych konfliktów, kończysz się tak:

- o - o - o - H - A - B - C - X (master)
               \             /
                P - Q - R --- (origin/master)

Z drugiej strony, jeśli zrobiłeś odpowiedni rebase, skończyłbyś z tym:

- o - o - o - H - P - Q - R - A' - B' - C' (master)
                          |
                          (origin/master)

W obu przypadkach zawartość twojego drzewa pracy powinna być taka sama; właśnie stworzyłeś inną historię, która do tego doprowadziła . Rebase przepisuje twoją historię, sprawiając, że wygląda ona tak, jakbyś popełnił na nowej gałęzi master ( R) pierwotnego źródła , zamiast w miejscu, w którym pierwotnie popełniłeś ( H). Nigdy nie powinieneś używać metody rebase, jeśli ktoś inny wyciągnął już z twojej gałęzi master.

Na koniec zauważ, że możesz faktycznie skonfigurować git pulldla danej gałęzi użycie rebase zamiast scalania, ustawiając parametr config branch.<name>.rebasena true. Możesz to również zrobić dla pojedynczego pociągnięcia za pomocą git pull --rebase.

Cascabel
źródło
39
Co się stanie, jeśli będziesz bazować po tym, jak ktoś już wycofał się z twojego głównego oddziału? Czy to zepsuje repo?
Didier A.
12
Skąd wiesz, czy ktoś wycofał się z twojego głównego oddziału?
Frank,
29
Jeśli nie wiesz na pewno, że ktoś tego nie zrobił , powinieneś założyć, że tak.
Chris Down,
4
Myślałem tylko, że o ile nie popychasz również zmian w miejsce inne niż origin / master, nie widzę, aby kiedykolwiek pojawiał się problem z tym, że ktoś wyciągnął te zmiany, ponieważ gdybyś już wypchnął te zmiany do origin / Mistrzyni, w pierwszej kolejności nie byłoby czego opierać. Wydaje mi się, że to ostrzeżenie ma znaczenie tylko wtedy, gdy masz coś bardziej złożonego niż X -> origin / X, ale mogę się mylić. Jeśli ktoś wie o przeoczonym przeze mnie scenariuszu, udostępnij go.
neverfox
1
@ SteveChambers Nie, to nie jest wynik. Linie po prostu reprezentują pochodzenie zatwierdzenia, tj. A jest rodzicem B. Nie ma to wpływu na to, czy Q lub B były pierwsze w czasie. Wszystkie te operacje oparte są na wykresach zatwierdzeń, a nie na czasie. Rebase po prostu transplantuje niektóre zatwierdzenia, a wynik pokazałem bez względu na znaczniki czasu zatwierdzenia.
Cascabel,
9

TLDR:

git pulljest jak bieganie git fetchwtedy git merge
git pull --rebasejest jak git fetchwtedygit rebase

W odpowiedzi na twoje pierwsze oświadczenie

git pulljest jak git fetch+ git merge.

„W domyślnym trybie, git pull jest skrótem, git fetchpo którym następuje git mergeFETCH_HEAD” Bardziej precyzyjnie, git pulldziała git fetchz podanymi parametrami, a następnie wywołuje git mergepołączenia scalonych odzyskanych głów gałęzi z bieżącą gałęzią ”

(Patrz: https://git-scm.com/docs/git-pull )


W przypadku drugiego oświadczenia / pytania:

„Ale jaka jest różnica między git pullVS git fetch+ git rebase

Ponownie z tego samego źródła:
git pull --rebase

„W przypadku --rebase uruchamia git rebase zamiast git merge.”


Teraz, jeśli chcesz zapytać

„różnica między mergea rebase

na to również tutaj odpowiedziano:
https://git-scm.com/book/en/v2/Git-Branching-Rebasing
(różnica między zmianą sposobu rejestrowania historii wersji)

harshvchawla
źródło
2
Chciałbym wspomnieć, że „git pull --rebase” jest przez większość czasu jak „git fetch następnie git rebase” - ale nie zawsze. W niektórych sytuacjach „git pull --rebase” robi nieco więcej. Zobacz często przywoływany
Daniel K.
1
Dziękuję bardzo za odpowiedź. Naprawdę rozumiem sposób, w jaki git fetch + git rebasedziałają polecenia. Od teraz nie ma już mniej lub więcej konfliktów na naszym drzewie git :)
Travis Le