Jak radzić sobie z tym ostrzeżeniem gita? „Wyciąganie bez określenia sposobu pogodzenia rozbieżnych gałęzi jest odradzane”


167

Po git pull origin masterchwili otrzymuję następujący komunikat:

warning: Pulling without specifying how to reconcile divergent branches is
discouraged. You can squelch this message by running one of the following
commands sometime before your next pull:

  git config pull.rebase false  # merge (the default strategy)
  git config pull.rebase true   # rebase
  git config pull.ff only       # fast-forward only

You can replace "git config" with "git config --global" to set a default
preference for all repositories. You can also pass --rebase, --no-rebase,
or --ff-only on the command line to override the configured default per
invocation.

remote: Enumerating objects: 4, done.
remote: Counting objects: 100% (4/4), done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 4 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (4/4), 51.49 KiB | 850.00 KiB/s, done.

Następnie wyciąganie zostało zakończone pomyślnie. Mimo to mam wątpliwości co do tej wiadomości.
Co najlepiej zrobić w tym przypadku?


1
Zgłoś błąd, że ostrzeżenie jest mylące. Jedna opcja powinna być „zalecana”, a ostrzeżenie powinno być wyświetlane tylko na żądanie, a nie tylko z powodu zmiany wersji. Wiele automatycznych skryptów może teraz przerwać to nieoczekiwane zachowanie.
Wolfgang Fahl,

1
@WolfgangFahl, ostrzeżenie nie powinno wpływać na żadne skrypty, ponieważ zachowuje domyślne zachowanie, dopóki nie zostanie jawnie zmienione. Nie powinno to powodować, że pull zwróci niezerowy kod zakończenia (biorąc pod uwagę, że jest to ostrzeżenie, a nie błąd). Kilka skryptów CI / CD, które wdrożyłem na różnych serwerach, nadal działa bez zmian.
Qumber

@Qumber - dzięki za komentarz. Wpisy Crontab zaczną np. Wysyłać e-mail, jeśli pojawi się wynik, którego nie było lub które można było przefiltrować za pomocą prostego grepa. Nieoczekiwany wynik może mieć różnego rodzaju skutki uboczne.
Wolfgang Fahl

@WolfgangFahl, Każde pociągnięcie ma zwykle inne wyjście. Tak więc każdy skrypt, który zależy wyłącznie od tego, jest prawdopodobnie źle napisany. Nie należy także aktualizować środowiska produkcyjnego bez obszernych testów. Wolę w ogóle nie ulepszać produktu. Zamiast tego tworzę nową instancję zawierającą wszystko, co najnowsze, hostuję tam swoje aplikacje, wszystko testuję, a następnie uruchamiam produkcję.
Qumber

Odpowiedzi:


197

W swoim domyślnym trybie, git pull jest skrótem dla git fetch, po którym następuje git merge FETCH_HEAD.

Kiedy robisz git pull origin master,
git pullwykonuje scalanie, co często tworzy zatwierdzenie scalające. Dlatego domyślnie ściąganie z pilota NIE jest nieszkodliwą operacją: może stworzyć nowy commit sha, który wcześniej nie istniał. Takie zachowanie może zmylić użytkownika, ponieważ to, co wydaje się być nieszkodliwą operacją pobierania, w rzeczywistości zmienia historię zatwierdzeń w nieprzewidywalny sposób.

Aby tego uniknąć, potrzebujesz

git pull --ff-only

(czy nie? czytaj dalej, aby zobaczyć, który z nich odpowiada Twoim potrzebom)

Dzięki git pull --ff-only, Git zaktualizuje twoją gałąź tylko wtedy, gdy można ją „przewinąć do przodu” bez tworzenia nowych zatwierdzeń. Jeśli nie można tego zrobić, git pull --ff-onlypo prostu przerywa pracę z komunikatem o błędzie.

Możesz skonfigurować swojego klienta Git tak, aby zawsze używał --ff-onlygo domyślnie, więc otrzymujesz takie zachowanie, nawet jeśli zapomnisz flagi wiersza polecenia:

git config --global pull.ff only

Uwaga: --globalflaga stosuje zmianę do wszystkich repozytoriów na twoim komputerze. Jeśli chcesz, aby to zachowanie dotyczyło tylko repozytorium, w którym się znajdujesz, pomiń flagę.

Zaczerpnięte stąd



To ostrzeżenie zostało dodane w Git 2.27, jak wskazał Joe w swojej odpowiedzi.

Tak wygląda pełne ostrzeżenie:

Wyciąganie bez określania sposobu pogodzenia rozbieżnych gałęzi jest odradzane. Możesz zdusić tę wiadomość, uruchamiając jedną z następujących komend jakiś czas przed następnym wyciągnięciem:

git config pull.rebase false # merge (strategia domyślna)
git config pull.rebase true # rebase
git config pull.ff only # fast-forward only

Możesz zamienić „git config” na „git config --global”, aby ustawić domyślne preferencje dla wszystkich repozytoriów. Możesz także przekazać --rebase, --no-rebase lub --ff-only w wierszu poleceń, aby przesłonić skonfigurowane domyślne dla każdego wywołania.

Ostrzeżenie przedstawia trzy polecenia jako opcje, wszystkie z nich pomijają ostrzeżenie. Ale służą różnym celom:

git config pull.rebase false     # merge (the default strategy)

Zachowuje to domyślne zachowanie i pomija ostrzeżenie.

git config pull.rebase true      # rebase

To faktycznie zatwierdza się na zdalnej gałęzi, utrzymując pojedynczą gałąź zarówno lokalnie, jak i zdalnie (w przeciwieństwie do domyślnego zachowania, w którym zaangażowane są dwie różne gałęzie - jedna lokalna, a druga zdalna - i aby połączyć te dwie, wykonywane jest scalanie ).

git config pull.ff only          # fast-forward only

To wykonuje ściąganie tylko wtedy, gdy lokalną gałąź można przewinąć do przodu. Jeśli nie, po prostu przerywa pracę z komunikatem o błędzie (i nie tworzy żadnych zatwierdzeń).


Aktualizacja:

Jeśli masz Git 2.29lub powyżej, można teraz ustawić pull.ffna false, truelub onlypozbyć się ostrzeżenia.

git config pull.ff true

true- To jest zachowanie domyślne. Pociągnięcie jest przewijane do przodu, jeśli to możliwe, w przeciwnym razie jest scalane.

git config pull.ff false

false - Ciągnięcie nigdy nie jest przewijane do przodu, a scalanie jest zawsze tworzone.

git config pull.ff only

only - Jeśli to możliwe, polecenie Pull jest przewijane do przodu, w przeciwnym razie operacja zostanie przerwana z komunikatem o błędzie.


9
Doceniam czas i wysiłek, jaki włożyłeś w swoją odpowiedź, ale szczerze mówiąc, nadal jest to dla mnie całkowicie niezrozumiałe.
Jared Nedzel

1
Jak skomentowano tutaj , na ostrzeżenie nie ma wpływu to, czy gałąź faktycznie się rozbiega. Początek „Twoja gałąź prawdopodobnie się rozchodzi”. może wprowadzać w błąd.
Joe

3
Muszę powiedzieć, że trzy opcje w komunikacie nie zadziałały, aby ukryć komunikat. Jednak odpowiedź tutaj ( git config --global pull.ff only) tak .
DiskJunky

1
Aha! Dzięki @Qumber. Próbowałem już pull.rebase false, ale nie działało zgodnie z opisem. To było zawsze tworząc scalającej, a nie fast-spedycja. Główną przyczyną było to, że miałem merge.ff falseustawienie. Po wyczyszczeniu tego ustawienia przewija do przodu, kiedy powinno. Dokumenty tutaj (prawie identyczne z dokumentami git pull )
stwr667

1
Dodałeś opcję Git 2.29, o której wspomniałem poniżej, dobra uwaga. Głosowano za.
VonC

65

To jest nowe ostrzeżenie dodane w Git 2.27 :

 * "git pull" issues a warning message until the pull.rebase
   configuration variable is explicitly given, which some existing
   users may find annoying---those who prefer not to rebase need to
   set the variable to false to squelch the warning.

Aby usunąć to ostrzeżenie, należy ustawić jedną z sugerowanych wartości do preferowanego domyślne zachowanie dla git pulljeśli nie określają zachowanie w wierszu poleceń (za pomocą --ff, --no-ff, --ff-only, --rebase). We wszystkich przypadkach, jeśli to możliwe , gitspróbuje przeprowadzić szybkie przewijanie do przodu ( Co to jest git fast-forwarding? ). Ustawienia kontrolują, co się dzieje, gdy w oddziale są zmiany, ale nie ma ich w oddziale zdalnym.

  git config pull.rebase false  # merge (the default strategy)

To jest istniejące domyślne zachowanie; ustaw to bez ostrzeżenia i bez zmiany zachowania; gitpołączy zdalną gałąź z lokalną.

  git config pull.rebase true   # rebase

Tutaj gitspróbuje ponownie bazować na twoich zmianach na zdalnej gałęzi. Zobacz Kiedy należy używać git pull --rebase? aby uzyskać więcej informacji, dlaczego możesz tego chcieć.

  git config pull.ff only       # fast-forward only

Jeśli szybkie scalanie nie jest możliwe, gitodmówi kontynuowania. Jako różnica między git pull --rebase i git pull --ff-only cudzysłowy:

Odmów połączenia i wyjdź ze statusem niezerowym, chyba że bieżący HEAD jest już aktualny lub scalenie można rozwiązać jako szybkie do przodu


20
To jest właściwie najbardziej poprawna odpowiedź, ponieważ wyjaśnia, dlaczego ludzie (tacy jak ja) nagle widzą to ostrzeżenie po prawie dziesięciu latach używania git. Jednak byłoby przydatne, gdyby podano pewne wskazówki dotyczące oferowanych opcji. na przykład wskazanie, że ustawienie pull.ff na „only” nie uniemożliwia wykonania polecenia „pull --rebase” w celu zastąpienia go.
kdopen

Jaka jest różnica między pull.rebase = truei branch.autoSetupRebase = always?
tekumara


1
„gdy są zmiany w Twojej gałęzi, ale nie ma ich w zdalnej gałęzi”. Wtedy wydaje mi się, że git powinien rzucać to ostrzeżenie tylko wtedy, gdy tak jest. Jeśli ciągnę swoją główną linkę (a główna jest używana prawidłowo), nie powinienem się tym martwić.
Keith Tyler

5
@Joe Podoba mi się twoja odpowiedź i myślę, że to właściwa odpowiedź, ale widzisz to niezależnie od tego, czy git faktycznie coś zrobił . Uważam, że odpowiednim momentem na wydanie tego ostrzeżenia jest to, że jeśli git musi coś zrobić , powinien zawieść tę wiadomość. Nie tylko spamuj użytkowników tą wiadomością z góry. Kolejna rzecz, która przyczynia się do mojej miłości / nienawiści do gita.
Jon V

7

git config pull.ff onlylub równoważnie git pull --ff-onlyjest najbezpieczniejszy. Powodem jest to, że rebase może nadpisać historię i może spowodować utratę zatwierdzeń, jeśli inny programista wymusił przesunięcie do tej samej gałęzi.

Ale wszystkie z nich są ważne.


3

Uwaga: Wcześniej nauczyliśmy „ git pull( man ), aby ostrzegał, gdy użytkownik nie mówi, że historie muszą zostać scalone, ponownie oparte lub akceptuje tylko przewijanie do przodu, ale ostrzeżenie jest wyzwalane dla tych, którzy ustawili pull.ffzmienną konfiguracyjną.

Tak już nie jest (co oznacza: koniec z ostrzeżeniami ) w Git 2.29 (Q4 2020).

Zobacz zatwierdzenie 54200ce (24 września 2020) autorstwa Alexa Henrie ( alexhenrie) .
(Scalone przez Junio ​​C Hamano - gitster- w zobowiązaniu 299deea , 29 września 2020 r.)

pull: nie ostrzegaj, jeśli pull.ffzostało ustawione

Podpisał: Alex Henrie

Użytkownik, który rozumie wystarczająco dużo, aby ustawić pull.ff, nie potrzebuje dodatkowych instrukcji.


Przed Git 2.31 (Q1 2021), gdy użytkownik nie mówi " git pull" ( man ), aby użył rebase lub merge, polecenie wydaje głośny komunikat informujący użytkownika o wyborze między rebase a merge, ale i tak tworzy scalanie, zmuszając użytkowników, którzy chcieliby chcesz zmienić bazę, aby powtórzyć operację.

Napraw wczesną część tego problemu, zaostrzając warunek, aby przekazać komunikat - nie ma powodu, aby zatrzymywać lub zmuszać użytkownika do wyboru między ponownym bazowaniem a scalaniem, jeśli historia przyspiesza do przodu.

Zobacz commit 7539fdc , commit b044db9 (14 grudnia 2020) autorstwa Junio ​​C Hamano ( gitster) .
Zobacz commit c525de3 , commit 278f4be , commit 77a7ec6 (12 grudnia 2020) autorstwa Felipe Contreras ( felipec) .
(Scalone przez Junio ​​C Hamano - gitster- w zatwierdzeniu d3fa84d , 6 stycznia 2021 r.)

pull: wyświetla domyślne ostrzeżenie tylko wtedy, gdy nie jest ff

Sugestie: Junio ​​C Hamano
Podpisał: Felipe Contreras

Nie ma potrzeby wyświetlania irytującego ostrzeżenia przy każdym pociągnięciu ... tylko te, które nie są przewijane do przodu.

Obecne testy ostrzeżeń nadal kończą się powodzeniem, ale nie z powodu argumentów lub konfiguracji, ale dlatego, że wszystkie są przewijane do przodu.

Musimy teraz przetestować sytuacje bez szybkiego przewijania do przodu.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.