Kiedy powinienem użyć git pull -- rebase?

Znam niektórych ludzi, którzy używają git pull --rebase domyślnie i innych, którzy nalegają, aby nigdy go nie używać. Wydaje mi się, że rozumiem różnicę między scalaniem a rebasingiem, ale staram się umieścić to w kontekście git pull. Czy chodzi tylko o to, aby nie chcieć zobaczyć wielu komunikatów merge commit, czy też są inne problemy?

 851
git
Author: tshepang, 2010-03-18

9 answers

Należy użyć git pull --rebase Kiedy

  • twoje zmiany nie zasługują na oddzielną gałąź
W rzeczy samej - dlaczego nie wtedy? Jest bardziej przejrzysty i nie narzuca logicznego grupowania Twoim commitom.
Ok, przypuszczam, że to wymaga wyjaśnienia. W Git, jak zapewne wiesz, zachęcamy cię do rozgałęziania i scalania. Twoja lokalna gałąź, do której ściągasz zmiany, oraz gałąź zdalna są w rzeczywistości różnymi gałęziami i git pull polega na ich scalaniu. On rozsądne, ponieważ naciskasz niezbyt często i zwykle gromadzisz szereg zmian, zanim staną się one ukończoną funkcją. Jednakże, czasami-z jakiegokolwiek powodu-myślisz, że byłoby lepiej, gdyby te dwie-odległe i lokalne-były jedną gałęzią. Jak w SVN. To tutaj git pull --rebase wchodzi w grę. Nie łączysz się już-w rzeczywistości zatwierdzasz na szczycie zdalnej gałęzi. O to właśnie chodzi.

Czy to niebezpieczne czy nie pytanie, czy traktujesz lokalną i zdalną gałąź jako jedną nierozłączną rzecz. Czasami jest to rozsądne (gdy twoje zmiany są małe lub jesteś na początku solidnego rozwoju, gdy ważne zmiany są wprowadzane przez małe commity). Czasami tak nie jest (gdy normalnie tworzyłeś inną gałąź, ale byłeś na to zbyt leniwy). Ale to inne pytanie.

 612
Author: P Shved,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-02 22:50:50

Chciałbym przedstawić inne spojrzenie na to, co właściwie oznacza "git pull --rebase", ponieważ wydaje się, że czasem się gubi.

Jeśli kiedykolwiek używałeś Subversion( lub CVS), możesz być przyzwyczajony do zachowania "svn update". Jeśli masz zmiany w commicie, a zatwierdzenie nie powiedzie się, ponieważ zmiany zostały wprowadzone od samego początku, "svn update". Subversion przechodzi przez scalanie zmian wcześniejszych z Twoimi, co może prowadzić do konfliktów.

To, co właśnie zrobił Subversion, było zasadniczo "pull -- rebase". Akt ponownego formułowania lokalnych zmian w stosunku do nowszej wersji jest częścią "rebasingu". Jeśli wykonałeś "SVN diff" przed nieudaną próbą zatwierdzenia i porównałeś wynikowe różnice z wynikiem" svn diff " później, różnica między tymi dwoma różnicami jest taka, jak zrobiła to operacja rebasingu.

Główna różnica między Gitem a Subversion w tym przypadku polega na tym, że w Subversion" twoje " zmiany istnieją tylko jako niezaangażowane zmiany w twojej pracy Kopiuj, podczas gdy w Git masz rzeczywiste commity lokalnie. Innymi słowy, w Git masz rozwidloną historię; Twoja historia i historia upstream zostały rozdzielone, ale masz wspólnego przodka.

Moim zdaniem, w normalnym przypadku, gdy Twoja lokalna gałąź po prostu odzwierciedla gałąź upstream i robi na niej ciągły rozwój, właściwą rzeczą jest zawsze "--rebase", ponieważ to właśnie robisz semantycznie . Ty i inni hackujecie na planowana liniowa historia oddziału. Fakt, że ktoś inny nieco popchnął przed twoją próbą, jest nieistotny i wydaje się przeciwny do produktywności, aby każdy taki wypadek czasu skutkował połączeniem w historii.

Jeśli rzeczywiście czujesz potrzebę, aby coś było gałęzią z jakiegokolwiek powodu, to moim zdaniem jest to inna sprawa. Ale jeśli nie masz konkretnego i aktywnego pragnienia reprezentowania swoich zmian w formie połączenia, domyślne zachowanie powinno, moim zdaniem be "git pull -- rebase".

Proszę wziąć pod uwagę inne osoby, które muszą obserwować i zrozumieć historię twojego projektu. Czy chcesz, aby historia była pełna setek połączeń w całym miejscu, czy tylko kilka wybranych połączeń, które reprezentują prawdziwe połączenia celowych rozbieżnych wysiłków na rzecz rozwoju?

 757
Author: scode,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-16 00:11:25

Być może najlepszym sposobem na wyjaśnienie tego jest przykład:

  1. Alicja tworzy gałąź tematyczną a i pracuje nad nią
  2. Bob tworzy niezwiązaną gałąź tematyczną B i pracuje nad nią]}
  3. Alicja robi git checkout master && git pull. Master jest już na bieżąco.
  4. Bob robi git checkout master && git pull. Master jest już na bieżąco.
  5. Alicja robi git merge topic-branch-A
  6. Bob robi git merge topic-branch-B
  7. Bob robi git push origin master przed Alice
  8. Alicja robi git push origin master, co jest odrzucane, ponieważ nie jest to przewijanie do przodu / align = "left" /
  9. Alice spogląda na origin/master ' s log i widzi, że commit nie ma związku z jej commitem.
  10. Alicja robi git pull --rebase origin master
  11. commit scalający Alicji jest rozwijany, commit Boba jest wyciągany, a commit Alicji jest stosowany po commicie Boba.
  12. Alice robi git push origin master i wszyscy są szczęśliwi, że nie muszą czytać bezużytecznego commita scalającego, gdy spojrzą na dzienniki w przyszłości.

Zauważ, że konkretna gałąź, do której zostanie scalona, nie ma znaczenia dla przykładu. Mistrz w przykładem może być równie łatwo gałąź release lub dev. Najważniejsze jest to, że Alice i Bob jednocześnie łączą swoje lokalne gałęzie ze współdzieloną gałęzią zdalną.

 252
Author: Cody Poll,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-29 15:12:10

Myślę, że powinieneś używać git pull --rebase podczas współpracy z innymi na tej samej gałęzi. Znajdujesz się w swoim cyklu work → commit → work → commit, a kiedy zdecydujesz się przesunąć swoją pracę, Twoje przesunięcie zostanie odrzucone, ponieważ równolegle prowadzono pracę w tej samej gałęzi. W tym momencie Ja Zawsze robię pull --rebase. Nie używam squasha( do spłaszczania commitów), ale rebase, aby uniknąć dodatkowych commitów scalających.

Wraz ze wzrostem wiedzy na temat Gita, odkrywasz, że bardziej patrzysz na historię niż na jakąkolwiek inną inne systemy kontroli wersji, z których korzystałem. Jeśli masz mnóstwo małych commitów scalających, łatwo jest stracić koncentrację na szerszym obrazie, który dzieje się w twojej historii.

To właściwie jedyny raz, kiedy robię rebasing (*), a reszta mojego przepływu pracy jest oparta na scalaniu. Ale tak długo, jak robią to twoi najczęściej popełniający błędy, historia w końcu wygląda o wiele lepiej.

(*) Ucząc kursu Git, miałem studenta, który mnie aresztował, ponieważ opowiadałem się również za rebasingiem gałęzi w w pewnych okolicznościach. I przeczytał tę odpowiedź ;) takie rebasowanie też jest możliwe, ale zawsze musi być zgodne z wcześniej ustalonym / uzgodnionym systemem i jako takie nie powinno być" zawsze " stosowane. I w tym czasie zwykle nie robię pull --rebase, o co chodzi w pytaniu;)

 153
Author: krosenvold,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-16 00:07:06

Nie wydaje mi się, aby kiedykolwiek istniał powód , aby nie używać -- dodałem kod do Gita specjalnie po to, aby moje polecenie git pull zawsze zmieniało bazę przed zatwierdzeniem.

Przeglądając historię, nigdy nie jest interesujące wiedzieć, kiedy facet/dziewczyna pracująca nad tą funkcją zatrzymała się, aby się zsynchronizować. Może to być przydatne dla faceta / dziewczyny podczas gdy on / ona to robi, ale po to jest reflog. To tylko dodawanie hałasu dla wszystkich innych.

 54
Author: Dustin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-16 00:08:29

Tylko pamiętaj:

  • pull = fetch + merge
  • pull --rebase = fetch + rebase

Więc wybierz sposób, w jaki chcesz obsługiwać swoją gałąź.

Lepiej znaj roznice miedzy merge a rebase :)

 44
Author: leohxj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-08 03:26:02

Myślę, że sprowadza się to do osobistych preferencji.

Czy chcesz ukryć swoje głupie błędy przed przesunięciem zmian? Jeśli tak, to git pull --rebase jest doskonałe. Pozwala na późniejsze zmiksowanie commitów do kilku (lub jednego) commitów. Jeśli masz już w swojej (nieużywanej) historii, nie jest tak łatwo zrobić git rebase później.

Ja osobiście nie mam nic przeciwko publikowaniu wszystkich moich głupich błędów, więc mam tendencję do scalania zamiast rebase.
 9
Author: hasen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-16 00:02:59

git pull --rebase może ukryć przepisywanie historii od współpracownika git push --force. Polecam do użycia git pull --rebase tylko jeśli wiesz, że zapomniałeś wcisnąć commity, zanim ktoś inny zrobi to samo.

Jeśli nic nie popełniłeś, ale Twoja przestrzeń robocza nie jest czysta, po prostu git stash przed git pull. W ten sposób nie będziesz w milczeniu przepisywać historii (co może po cichu upuścić część twojej pracy).

 9
Author: Habax,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-24 09:21:32

Jeden przypadek praktyki jest, gdy pracujesz z Bitbucket PR. Jest PR otwarty.

Następnie decydujesz się na rebase zdalnej gałęzi PR na najnowszej gałęzi Master. Spowoduje to zmianę identyfikatorów commita twojego PR.

Następnie chcesz dodać nowy commit do gałęzi PR.

Ponieważ zrebasowałeś zdalną gałąź za pomocą GUI, najpierw zsynchronizujesz lokalną gałąź na komputerze z gałąź zdalną.

W tym przypadku git pull --rebase działa jak magia.

Po git pull --rebase Twojej zdalnej gałęzi i lokalna gałąź ma tę samą historię z tymi samymi identyfikatorami commitów.

Teraz możesz ładnie wcisnąć nowy commit bez użycia siły czy czegokolwiek.

 0
Author: Deepak Sharma,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-11-17 01:58:04