Aktualizacje zostały odrzucone, ponieważ końcówka Twojej bieżącej gałęzi znajduje się za jej zdalnym odpowiednikiem

220

Jestem nowy w Git, więc możesz mnie traktować jak nowicjusza.

Nasz przepływ pracy jest taki. Mamy oddział, do devktórego mogę dotrzeć origin/dev. Kiedy dokonujemy zmian, tworzymy gałąź off dev:

git checkout -b FixForBug origin / dev

Teraz mam gałąź nazwaną FixForBugśledzącą (myślę, że to właściwe słowo) origin/dev. Tak więc, jeśli git pullto zrobię, przyniesie nowe zmiany, z origin/devktórych jest super. Teraz, kiedy skończę z poprawką, wysyłam do zdalnej gałęzi o tej samej nazwie.

Najpierw ściągam wszelkie zmiany z origin/devi robię rebase:

git pull --rebase

Następnie wprowadzam zmiany do zdalnego oddziału o tej samej nazwie:

git push origin FixForBug

Teraz istnieje gałąź na serwerze zdalnym i mogę utworzyć żądanie ściągnięcia, aby ta zmiana została zatwierdzona i włączona z powrotem do gałęzi deweloperskiej. Nie zawsze naciskać nic do origin/devsiebie. Zgaduję, że jest to dość powszechny przepływ pracy.

Za pierwszym razem git pushdziała dobrze i tworzy zdalną gałąź. Jeśli jednak wciskam drugi raz (powiedzmy podczas przeglądu kodu, ktoś wskazuje na problem), pojawia się następujący błąd:

błąd: nie udało się przesłać niektórych odnośników do „https://github.limeade.info/Limeade/product.git”.
Wskazówka: aktualizacje zostały odrzucone, ponieważ końcówka Twojej bieżącej gałęzi znajduje się za jej zdalnym odpowiednikiem. Zintegruj zdalne zmiany (np. Wskazówka: „git pull ...”) przed ponownym naciśnięciem.
Zobacz „Uwaga o szybkim przekazywaniu” w „git push --help”, aby uzyskać szczegółowe informacje.

Jeśli jednak zrobię, git statusto mówi, że wyprzedzam o origin/dev1 zmianę (co ma sens), a jeśli podążę za wskazówką i uruchomię git pull, mówi, że wszystko jest aktualne. Myślę, że dzieje się tak, ponieważ pcham się do innej gałęzi niż moja gałąź upstream. Mogę rozwiązać ten problem, uruchamiając:

git push -f origin FixForBug

W takim przypadku prześle zmiany do zdalnej gałęzi, mówiąc (wymuszona aktualizacja) i wszystko wydaje się być dobre w zdalnej gałęzi.

Moje pytania:

Dlaczego jest to -fwymagane w tym scenariuszu? Zwykle, gdy coś wymuszasz , dzieje się tak dlatego, że robiłeś coś złego lub przynajmniej wbrew standardowej praktyce. Czy mogę to zrobić w porządku, czy może to zepsuje coś w zdalnym oddziale lub spowoduje kłopoty dla każdego, kto będzie musiał ostatecznie scalić moje rzeczy w programistę?

Mike Christensen
źródło
2
Wygląda na to, że otrzymujesz wiadomość, że zdalna gałąź FixForBug wyprzedza lokalny oddział FixForBug. Powinieneś usunąć zmiany z tego zdalnego oddziału i scalić je z lokalnym oddziałem przed wypchnięciem.
mhatch
4
@mhatch - Więc w zasadzie biegnij, git pull origin FixForBugzanim nacisnę do tego? Ok, to ma sens. Zapraszam do dodania jako odpowiedzi!
Mike Christensen

Odpowiedzi:

276

W rzeczywistości -f jest to wymagane z powodu rebase. Za każdym razem, gdy wykonujesz rebase, będziesz musiał wykonać wymuszenie wypychania, ponieważ zdalna gałąź nie może zostać przewinięta do twojego zatwierdzenia. Można by zawsze chcą mieć pewność, że robisz ciągnąć przed popychanie, ale jeśli nie lubisz siły naciśnięciem do opanowania lub dev dla tej sprawy, można utworzyć nowy oddział do push to i następnie scalić lub dokonać PR .

Keif Kraken
źródło
4
Dzięki za tę bardzo pomocną odpowiedź! :)
AIM_BLB
1
Czy mógłbyś wyjaśnić kwestię „Zawsze chciałbyś mieć pewność, że pociągniesz przed pchnięciem”? Jest jasne, dlaczego wymagane jest „push -f” po ponownym bazowaniu lokalnego oddziału. W takim przypadku, czy ponowne ustawienie bazy lokalnej nie zostanie cofnięte przez pociągnięcie pilota przed naciśnięciem?
Hari
64

Aby upewnić się, że lokalny oddział FixForBug nie wyprzedza zdalnej gałęzi FixForBug, ściągnij i scal zmiany przed wypchnięciem.

git pull origin FixForBug
git push origin FixForBug
mhatch
źródło
8
OP stwierdził, że już zrobił git pull i próbował naciskać. Twoja odpowiedź nie dotyczy pytania OP.
Patrick
3
Zawsze lepiej unikać pchnięcia siłowego. Dzięki za udostępnienie tego!
Ann Kilzer,
56

the tip of your current branch is behind its remote counterpartoznacza, że ​​nastąpiły zmiany w zdalnej gałęzi, których nie masz lokalnie. a git mówi, że importujesz nowe zmiany z REMOTEi łączysz je z kodem, a następnie pushzdalnie.

Możesz użyć tego polecenia, aby wymusić zmiany na serwerze za pomocą lokalnego repo ().

git push -f origin master

ze -fznacznikiem można zastąpić Remote Brach codez kodem.

Talha Rafique
źródło
19

Jeśli chcesz uniknąć konieczności używania -f, możesz użyć po prostu

git pull

zamiast

git pull --rebase

Non-rebase pobierze zmiany z origin/devi połączy je z Twoją FixForBuggałęzią. Wtedy będziesz mógł biegać

git push origin FixForBug

bez użycia -f.

Greg Hewgill
źródło
3
Rebase jest częścią naszego przepływu pracy tutaj. Będę krzyczeć, jeśli tego nie zrobię.
Mike Christensen
1
@MikeChristensen: OK, więc oczywiście postępuj zgodnie z udokumentowaną procedurą. Z tego, co opisujesz, będziesz musiał użyć, -fponieważ zastępujesz zmiany w głównym repozytorium na inne, które mają inną historię (przeobrażoną). Jeśli miałbyś użyć produktu takiego jak Gerrit , obsługuje on tego rodzaju zmianę bazy przepływu pracy przeglądu kodu bez konieczności używania go -fpodczas wypychania. Używamy Gerrita w pracy w ten sposób i działa to bardzo dobrze.
Greg Hewgill
6

Polecenie, którego użyłem z Azure DevOps, gdy napotkałem komunikat „aktualizacje zostały odrzucone, ponieważ końcówka Twojej bieżącej gałęzi jest za” to / jest to polecenie:

git pull origin master

(lub możesz zacząć od nowego folderu i wykonać klonowanie).

Ta odpowiedź nie odnosi się do zadanego pytania, a konkretnie, Keif odpowiedział na to powyżej, ale odpowiada na tytuł / nagłówek pytania i będzie to typowe pytanie dla użytkowników Azure DevOps.

Zauważyłem komentarz: „Zawsze chciałbyś się upewnić, że pociągniesz przed pchnięciem” w odpowiedzi od Keif powyżej!

Oprócz narzędzia wiersza poleceń Git korzystałem również z narzędzia Git Gui.

(Nie byłem pewien, jak zrobić odpowiednik polecenia wiersza poleceń „git pull origin master” w Git Gui, więc wróciłem do wiersza poleceń, aby to zrobić).

Diagram przedstawiający różne polecenia git dla różnych działań, które możesz chcieć wykonać, jest następujący:

wprowadź opis obrazu tutaj

Allan F
źródło
4

To właśnie mi się przydarzyło.

  • Wczoraj poprosiłem naszego pana o wycofanie.
  • Mój kolega przeglądał go dzisiaj i zobaczył, że nie jest zsynchronizowany z naszą główną gałęzią, więc chcąc mi pomóc, połączył mistrza z moją gałęzią.
  • Nie wiedziałem, że to zrobił.
  • Następnie połączyłem mastera lokalnie, próbowałem go przesunąć, ale nie udało się. Czemu? Ponieważ mój kolega w połączeniu z mistrzem stworzył dodatkowe zatwierdzenie, którego nie miałem lokalnie !

Rozwiązanie: ściągnij moją własną gałąź, aby uzyskać dodatkowe zatwierdzenie. Następnie odeślij go z powrotem do mojego zdalnego oddziału.

dosłownie to, co zrobiłem na mojej gałęzi, to:

git pull
git push
kochanie
źródło
3

W ten sposób rozwiązałem swój problem

Załóżmy, że gałąź upstream to ta, z której rozwidliłeś się, a źródło to twoje repozytorium i chcesz wysłać MR / PR do gałęzi upstream.

Powiedzmy, że masz już około 4 zatwierdzeń i otrzymujesz Updates were rejected because the tip of your current branch is behind.

Oto co zrobiłem

Najpierw zmiażdż wszystkie 4 zatwierdzenia

git rebase -i HEAD~4

Otrzymasz listę zatwierdzeń z pickwypisanymi na nich. (otwarty w edytorze)

przykład

pick fda59df commit 1
pick x536897 commit 2
pick c01a668 commit 3
pick c011a77 commit 4

do

pick fda59df commit 1
squash x536897 commit 2
squash c01a668 commit 3
squash c011a77 commit 4

Następnie możesz zapisać swoje połączone zatwierdzenie

Kolejny

Musisz ukryć swoje zobowiązanie

Oto jak

git reset --soft HEAD~1
git stash

teraz ponownie bazuj na swojej gałęzi upstream

git fetch upstream beta && git rebase upstream/beta

Teraz otwórz ukryty commit

git stash pop

Zatwierdź te zmiany i popchnij je

git add -A
git commit -m "[foo] - foobar commit"
git push origin fix/#123 -f
Deepesh Nair
źródło
3

To musi być spowodowane tym, że zatwierdzenie wyprzedza twoje obecne pchnięcie.

  1. git pull origin "name of branch you want to push"
  2. git rebase

Jeśli rebase git się powiedzie, to dobrze. W przeciwnym razie wszystkie konflikty dotyczące scalania należy rozwiązać lokalnie i kontynuować, dopóki ponowne bazowanie ze zdalnym nie powiedzie się.

  1. git rebase --continue
kris
źródło
3

Ustaw nazwę aktualnej gałęzi, taką jak master

git pull --rebase origin master git push origin master

Lub rozwinąć nazwę oddziału

git pull --rebase origin develop git push origin develop

Golam Sorwar
źródło
1

Miałem ten problem, gdy próbowałem wypchnąć po ponownym bazowaniu za pomocą Visual Studio Code, mój problem został rozwiązany przez skopiowanie polecenia z okna wyjściowego git i wykonanie go z okna terminala w Visual Studio Code.

W moim przypadku polecenie wyglądało mniej więcej tak:

git push origin NameOfMyBranch:NameOfMyBranch

HoloLady
źródło
1

Ja pomogę dalej:

git stash
git pull origin master
git apply
git commit -m "some comment"
git push
Alex Reuka
źródło
0

Musisz dodać nowe pliki do swoich zatwierdzeń, które nie zostały przesłane. Sprawdź plik i wypchnij go ponownie, a spróbuj wyciągnąć / wypchnąć to zadziała. To zadziałało dla mnie ...

Rahul Parab
źródło