W git, czym różni się pobieranie od ściągania i czym różni się merge od rebase?

160

Po prostu nie mogę tego zrozumieć. Dużo czytałem w internecie i książkach i coś po prostu nie zostaje w mojej głowie. Czy ktoś może mi podać fikcyjną wersję następujących elementów:

  • git fetch vs pull
  • git merge vs rebase
techsjs2013
źródło
24
Współczuję pytającemu. Dokumentacja i porady są tak ciężkie, a możliwe permutacje przepływu pracy tak ogromne, że można się bardzo zdezorientować. Właśnie eksplodowała jedna głowa i nie bardzo wiadomo, o co zapytać, po prostu nie jest to takie oczywiste.
Ed Randall,
3
Dlaczego nie wybrać odpowiedzi pestrella jako zaakceptowanej?
Arashsoft
@Arashsoft, ponieważ nie widać go od 2013 roku
VdeX

Odpowiedzi:

415

Fetch vs Pull

fetch pobierze wszelkie zmiany ze zdalnej * gałęzi, aktualizując dane repozytorium, ale pozostawiając lokalną * gałąź bez zmian.

pulldokona fetchi dodatkowo mergezmian w Twoim oddziale lokalnym.

Co za różnica? pullaktualizuje oddział lokalny zmianami z pobranej gałęzi. A fetchnie wspiera Twojego lokalnego oddziału.

merge vs rebase

Biorąc pod uwagę następującą historię:

          C --- D --- E lokalna
         /
    Pilot A --- B --- F --- G.

mergełączy dwie historie rozwoju. Robi to przez ponowne odtworzenie zmian, które zaszły w twojej lokalnej gałęzi po tym, jak rozeszła się na zdalnej gałęzi, i zapisanie wyniku w nowym zatwierdzeniu. Ta operacja zachowuje pochodzenie każdego zatwierdzenia.

Efektem mergebędzie:

          C --- D --- E lokalna
         / \
    A --- B --- F --- G --- H zdalne

rebaseweźmie zatwierdzenia, które istnieją w twojej lokalnej gałęzi i zastosuje je ponownie na zdalnej gałęzi. Ta operacja powoduje ponowne zapisanie przodków lokalnych zatwierdzeń.

Efektem rebasebędzie:

                  C '- D' - E 'lokalnie
                 /
    Pilot A --- B --- F --- G.

Co za różnica? A mergenie zmienia pochodzenia zatwierdzeń. A rebase przepisuje pochodzenie lokalnych zatwierdzeń.

*To wyjaśnienie zakłada, że obecny oddział jest lokalny oddział, a oddział określony jako argument fetch, pull, merge, czy rebasejest zdalnym oddziału. To jest zwykły przypadek. pull, na przykład, pobierze wszelkie zmiany z określonej gałęzi, zaktualizuje repozytorium i mergezmiany w bieżącej gałęzi.

pestrella
źródło
31
Jak dotąd jest to najprostsze i najlepsze wyjaśnienie bez wdawania się w debatę dotyczącą każdej praktyki. Dziękuję Ci!
Jonathan S. Fisher,
3
Absolutnie złota odpowiedź
ChaseMoskal
5
Chciałbym móc „polubić” tę odpowiedź. Może po prostu go wydrukuję i przykleję na ścianie.
LarsH
2
Powiedziałbym, że najlepsze z najlepszych odpowiedzi, jakie otrzymałem w stackoverflow, dziękuję
Shahab J
1
Jeśli funkcja Fetch pobiera tylko zmiany ze zdalnej gałęzi i aktualizuje dane repozytorium, ale pozostawia lokalną gałąź bez zmian, to jaki jest sens pobierania, jeśli katalog roboczy nie pokazuje / nie odzwierciedla zmian? Moje pierwotne pytanie dotyczyło tego, jak mogę zobaczyć zmiany dokonane przez kogoś innego, a następnie zdecydować, czy chcę je scalić z moim katalogiem roboczym (tj. Eksperymentować ze zmianami innych osób, aby upewnić się, że nie zepsują mojej pracy), ale nadal jestem nie wiesz, jak to zrobić? Czy powinienem po prostu pulchować i eksperymentować / eksplorować, a jeśli to było problematyczne, zrobić twardy reset?
28

Fetch vs Pull

Pobieranie Git tylko aktualizuje dane repozytorium, ale git pull w zasadzie wykona pobieranie, a następnie połączy wyciągniętą gałąź

Jaka jest różnica między „git pull” a „git fetch”?


Merge vs Rebase

z Atlassian SourceTree Blog, Merge or Rebase :

Łączenie łączy dwie linie rozwoju, jednocześnie zachowując pochodzenie każdej historii zatwierdzeń.

W przeciwieństwie do tego, ponowne bazowanie ujednolica linie rozwoju przez ponowne zapisywanie zmian z gałęzi źródłowej, tak że pojawiają się one jako elementy podrzędne gałęzi docelowej - skutecznie udając, że te zatwierdzenia były przez cały czas napisane na wierzchu gałęzi docelowej.

Zobacz także Learn Git Branching , która jest fajną grą, która właśnie została opublikowana w HackerNews ( link do posta ) i uczy wielu sztuczek związanych z rozgałęzianiem i łączeniem. Wierzę, że będzie to bardzo pomocne w tej sprawie.

Felipe Sabino
źródło
dzięki Felips .. więc jeśli zrobię pobieranie ze zdalnego, moja gałąź główna nie będzie miała aktualizacji? też wygląda na to, że powinienem zrobić rebase bardziej niż scalę
techsjs2013
rebase vs merge zależy od twojego zamiaru, pamiętając, że rebase przepisuje całą historię zatwierdzeń. I tak, jeśli pobierzesz tylko, gałąź główna nie zostanie zmieniona, będziesz musiał scalić (lub wyciągnąć), aby zastosować zdalne zmiany
Felipe Sabino
git merge <remote>/<branch>. na przykład, jeśli jesteś główną gałęzią, a twój pilot nosi nazwę pochodzenia, możesz to zrobić git merge origin/master.
Felipe Sabino
więc wygląda na to, że zawsze powinienem robić git checkout master git fetch git diff origin / master git rebase origin master
techsjs2013
8

pull vs fetch :

Sposób, w jaki to rozumiem, jest taki, że git pullpo prostu git fetchnastępuje po git merge. Oznacza to, że pobierasz zmiany ze zdalnej gałęzi, a następnie scalasz je z bieżącą gałęzią.


merge vs rebase :

Scalanie nastąpi zgodnie z poleceniem; scal różnice między bieżącą gałęzią a określoną gałęzią (do bieżącej gałęzi). To znaczy polecenie git merge another_branchpołączy another_branchsię z bieżącą gałęzią.

Rebase działa trochę inaczej i jest fajny. Powiedzmy, że wykonujesz polecenie git rebase another_branch. Git najpierw znajdzie najnowszą wspólną wersję między bieżącą gałęzią a another_branch. To znaczy punkt, zanim gałęzie się rozeszły. Następnie git przesunie ten rozbieżny punkt na początek another_branch. Na koniec wszystkie zatwierdzenia w bieżącej gałęzi, ponieważ pierwotny punkt rozbieżności są odtwarzane z nowego punktu rozbieżnego. Tworzy to bardzo przejrzystą historię z mniejszą liczbą rozgałęzień i połączeń.

Jednak nie jest to pozbawione pułapek! Ponieważ historia wersji jest „przepisywana”, powinieneś to zrobić tylko wtedy, gdy zatwierdzenia istnieją tylko w lokalnym repozytorium git. To znaczy: Nigdy nie rób tego, jeśli przekazałeś zatwierdzenia do zdalnego repozytorium.

Wyjaśnienie zmiany podstawy podane w tej książce online jest całkiem dobre, z łatwymi do zrozumienia ilustracjami.


pull z rebasing zamiast scalać

Właściwie często używam rebase, ale zwykle jest to połączone z pull:

git pull --rebase

będzie pobierać zdalne zmiany, a następnie ponownie bazować zamiast scalać. Oznacza to, że odtworzy wszystkie lokalne zatwierdzenia od ostatniego wykonania pull. Uważam, że jest to o wiele czystsze niż zwykłe wyciąganie z scalaniem, które spowoduje utworzenie dodatkowego zatwierdzenia przy scalaniu.

Steinar
źródło
więc jeśli pracuję w i rozgałęziam się i chcę scalić go z powrotem w master, zanim wykonam push. Powinienem przejść do kasy, a następnie uzyskać poprawkę rebase?
techsjs2013
Nadal nie rozumiem, scalanie vs rebase
techsjs2013
Myślę, że ilustracje dostarczone przez odpowiedź z pestrella dość wyraźnie pokazują różnicę. Sprawdź również: git-scm.com/book/en/Git-Branching-Rebasing - który całkiem przyzwoicie go wyjaśnia (ten sam link, co ten w odpowiedzi, ale podany ponownie dla leniwych).
Steinar
0

Merge - gałąź HEAD wygeneruje nowy commit, zachowując pochodzenie każdej historii zmian. Historia może zostać skażona, jeśli zatwierdzenia scalenia są dokonywane przez wiele osób pracujących równolegle w tej samej branży.

Rebase - Ponownie zapisuje zmiany z jednej gałęzi na inną bez tworzenia nowego zatwierdzenia. Historia kodu jest uproszczona, liniowa i czytelna, ale nie działa z żądaniami ściągnięcia, ponieważ nie możesz zobaczyć, jakie drobne zmiany ktoś wprowadził.

Używałbym, git mergegdy mam do czynienia z przepływem pracy opartym na funkcjach lub jeśli nie jestem zaznajomiony z rebase. Ale jeśli chcę bardziej przejrzystej, linearnej historii, wtedy git rebasejest to bardziej odpowiednie. Aby uzyskać więcej informacji, zapoznaj się z tym artykułem o scalaniu lub rebase .

Nesha Zoric
źródło