Jak wymusić wypchnięcie resetowania do zdalnego repozytorium?


96

Nasza zdalna główna gałąź jakoś się popsuła. Bieżący kod programistyczny znajduje się w gałęzi głównej wraz z najnowszymi zatwierdzeniami. Oczywiście kod programistyczny nie jest gotowy na gałąź główną.

Więc na moim lokalnym repozytorium, zrobiłem reset do najnowszej znacznika git reset --hard (Tag). Gałąź główna jest teraz poprawna w moim lokalnym repozytorium. Teraz, gdy próbuję wypchnąć zmiany do zdalnego repozytorium, pojawia git push origin mastersię błąd:

To (REMOTE GIT REPOSITORY LOCATION)
 ! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to '(REMOTE GIT REPOSITORY LOCATION)'
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes (e.g. 'git pull') before pushing again.  See the
'Note about fast-forwards' section of 'git push --help' for details.

Więc po rozejrzeniu się znalazłem --forceopcję. Więc nacisnąłem na zdalne repozytorium git push --force origin masteri nadal otrzymuję błąd:

Total 0 (delta 0), reused 0 (delta 0)
remote: error: denying non-fast-forward refs/heads/master (you should pull first)
To (REMOTE GIT REPOSITORY LOCATION)
 ! [remote rejected] master -> master (non-fast-forward)
error: failed to push some refs to '(REMOTE GIT REPOSITORY LOCATION)'

Nie mogę zrobić pull on master, ponieważ zawiera kod programistyczny, którego nie można wykonać na master.


3
Myślę, że ta wiadomość oznacza, że ​​nie masz uprawnień do wykonywania przewijania do przodu bez przewijania.
svick

3
Miałeś rację, dzięki. W pliku konfiguracyjnym dla repozytorium na pilocie denyNonFastforwards = true. Zmieniłem to na fałsz, wypchnąłem zmiany, a następnie zmieniłem z powrotem na prawda. Jeszcze raz dziękuję wszystkim za pomoc.
samwell

2
@samwell, proszę oznaczyć odpowiedź svicka jako zaakceptowaną
hultqvist

@samwell Czy odpowiedź Svicka zadziałała dla Ciebie, czy nie?
Songo,

Dla tych, którzy potrzebują szczegółów na temat wyłączania funkcji DenyNonFastForwards, jak zrobił to Samwell, więcej instrukcji można znaleźć tutaj: stackoverflow.com/a/43721579/2073804
ron190

Odpowiedzi:


153

Komunikat oznacza, że ​​nie możesz wykonywać wypychania bez przewijania do przodu.

Twoje zdalne repozytorium ma najprawdopodobniej denyNonFastforwards = truew swojej konfiguracji. Jeśli to zmienisz, git push --forcepowinno działać.

Aby zmienić to ustawienie, musisz mieć dostęp do komputera ze zdalnym repozytorium. Stamtąd, zrób git config receive.denynonfastforwards false.


1
Czy możesz zrobić git configdla serwera? A może używałeś tego metaforycznie. Aby pobawić się tymi pomysłami, utworzyłem repozytorium testowe w /opt/git(mojej przestrzeni serwera git), a następnie zmodyfikowałem to ustawienie w /opt/git/the_repo/the_repo.git/config. Ale po wykonaniu pracy git push --force origin SHA:branchdziałało zgodnie z wymaganiami.
HankCa

4
Komunikat o błędzie będzie miał wiersz zaczynający się od „błąd: nie udało się przesłać niektórych odnośników do <twoje repozytorium>”, gdzie <twoje repozytorium> to ścieżka kończąca się na .git, który jest katalogiem zawierającym plik o nazwie „config”. W tym pliku „config” możesz ustawić denyNonFastforwards = false
emery

1
Komentarz @ emery jest cenny. Czasami folder na serwerze będzie miał swój początek ustawiony na coś takiego jak /srv/git/repo.git. To jest konfiguracja, która ma ustawioną opcję DenyNonFastForwards, a nie folder aplikacji.
Elijah Lynn

1
@hsalimi Jeśli nie masz dostępu do serwera, musisz skontaktować się z administratorem serwera i poprosić go o tymczasowe wyłączenie, abyś mógł wymusić wypychanie, a następnie włączyć go ponownie. Jednak jest mało prawdopodobne, aby większość z nich była w stanie to zrobić. Może to być bardziej powszechne w środowisku wewnętrznym z własnym zespołem hostingowym.
Elijah Lynn

1
Jest to początkowo frustrujące, ale piękno tego polega na tym, że pilot jest domyślnie całkowicie chroniony, a jeśli jako programista celowo i poprawnie wykonujesz ponowne bazy, możesz zastąpić tę konfigurację, aby zezwolić na niebezpieczne zachowanie. Rebasing to coś, co każdy użytkownik gita powinien wiedzieć, jak to zrobić - i wiedzieć, kiedy tego nie robić. doc1 doc2
moodboom

15

Pilot nie pozwala na szybkie przewijanie do przodu.

Najlepszą opcją jest wybranie git revertwszystkich zatwierdzeń, których nie powinno tam być i być bardziej ostrożnym w przyszłości.

git revert [commit]stworzy nowe zatwierdzenie, które cofnie wszystko, co [commit]zrobił.


To były pewne ustawienia w zdalnym repozytorium, które blokowały wszystkie zmiany bez szybkiego przewijania do przodu.
samwell

Jeśli to zrobisz i będziesz musiał ponownie zastosować zatwierdzenia, historia nie zostanie usunięta podczas przywracania, tylko zmiany w kodzie i nie będziesz w stanie wybierać zatwierdzeń ani scalać
mtpultz

12

Spróbuj użyć -fflagi i umieścić ją po nazwie zdalnego oddziału.

git push origin master -f


1
Nie, to też nie zadziałało. Spróbowałem też git push -f origin masteri ten sam wynik. Za każdym razem, gdy próbowałem, otrzymałem drugą wersję komunikatu o błędzie.
samwell

12

Kroki umożliwiające trwałe włączenie pchania siłowego w następującym stylu

git push -f myrepo my-branch

Edytuj plik o nazwie „config” w folderze kończącym się na „.git” w swoim zdalnym repozytorium

W danych wyjściowych wiersza polecenia git z nieudanego wypychania poszukaj wiersza, który mówi mniej więcej tak:

error: failed to push some refs to 'ssh://user@some-remote-server.mycompany.com/srv/git/myrepo.git

następnie

ssh user@some-remote-server.mycompany.com
cd /srv/git/myrepo.git
vi config

Ustaw „denyNonFastforwards” na false

W „config” ustaw

[receive]
        denyNonFastforwards = false

Teraz możesz wypchnąć z lokalnego komputera za pomocą -f

git push -f myrepo my-branch

Jak to zrobić bez dostępu do SSH do samego repozytorium Git?
Vladimir Vukanac

Może użyj polecenia git revert, jak sugeruje richo? Jeśli najpierw utworzysz kopię zapasową bieżącego stanu repozytorium, nadal możesz scalić kod, przechodząc do przodu.
emery

git revertjest trochę skomplikowane w przypadku fuzji. Aby być bardziej skomplikowanym, mój przypadek ma 3 scalenia, z których jeden jest z bardzo starym ~ 20 zatwierdzeniem odbiegającym od develop, drugi to rodzaj scalenia z mistrzem - brzydki jak diabli.
Vladimir Vukanac

1
Może rozwiązaniem jest zresetowanie do żądanego stanu, wykonanie kopii zapasowej (skrytka), ponowne ściągnięcie i zastosowanie kopii zapasowej (skrytka).
Vladimir Vukanac

1
mrW, nadal możesz scalić żądaną bazę kodu na podstawie przywróconego / ściągniętego kodu podstawowego
emery

2

Nie możesz robić git push, które nie jest przewijane do przodu.

  1. Jeśli pilot to GitHub, przejdź do https://github.com/$USER/$REPO/settings/branchesi wyłącz ochronę danej gałęzi.

    wprowadź opis obrazu tutaj

    Aby to zrobić, musisz być administratorem repozytorium.

  2. Jeśli zdalny jest twoim własnym serwerem git, uruchom git config receive.denynonfastforwards falsetam.


Należy pamiętać, że w przypadku instancji Git Hub Enterprise wypychanie do gałęzi domyślnej (zwykle „głównej”) można wyłączyć na poziomie instancji. Oznacza to, że nawet jeśli „master” nie jest chroniony, a nawet jeśli jesteś administratorem witryny, nie będziesz w stanie wykonać push-push do domyślnej gałęzi. Zakładając, że masz uprawnienia, możesz tymczasowo obejść ten problem, przełączając domyślną gałąź na coś innego, wykonując pchnięcie siły, a następnie przełączając się z powrotem.
Christopher Hunter,

2

Najlepszym sposobem obejścia tego jest usunięcie zdalnej gałęzi i ponowne jej wysłanie:

git push origin master --delete
git push origin master

0

Problem występuje, ponieważ bieżąca gałąź nie jest poprawnie skonfigurowana dla PULL . Najpierw sprawdź, czy gałąź upstream jest poprawnie skonfigurowana do ściągania, używając - git remote show origin. Możesz go znaleźć w sekcji - Lokalne gałęzie skonfigurowane dla 'git pull': . Jeśli nie, skonfiguruj go za pomocą:

git config branch.MYBRANCH.merge refs/heads/MYBRANCH

Podaj odpowiednią nazwę gałęzi dla symbolu zastępczego - MYBRANCH


0

Używam tej grupy poleceń, aby zresetować moje zdalne repozytorium, spowoduje to ponowne zainicjowanie lokalnego repozytorium i ponowne połączenie ze zdalnym repozytorium, a następnie wymusi wypchnięcie aktualizacji.

Myślę, że ten sposób nie zadziała w twoim przypadku, ale może być przydatny dla kogoś innego

przejdź do folderu źródłowego, a następnie uruchom polecenia: zwróć uwagę, że https://github.com/*.gitjest to łącze do zdalnego repozytorium

git init
git remote add origin https://github.com/*.git
git add .
git commit -m "initial commit"
git push origin master -f
git push --set-upstream origin master

**Note: this will clear all your git history on your master branch**


0

Dla mnie wskazówka @svick wskazywała we właściwym kierunku. Ponieważ serwer git, który chciałem zmodyfikować, jest w rzeczywistości moim urządzeniem, zalogowałem się do niego i zrobiłem, git config --global receive.denynonfastforwards falseaby zmienić wszystkie repozytoria, aby akceptowały wymuszone wypychanie bez ff. Nie wyszło z pudełka. Odkryłem, że w konfiguracji jest już receive.denynonfastforwards=trueustawiony i nie można go usunąć git config --global --unset receive.denynonfastforwards. vi configJednak ręczne wykonanie edycji w repozytorium ( ) działało.


0

Rozwiązałem przez usunięcie gałęzi głównej z chronionej, a także domyślnej, która jest nieco ponad regułami gałęzi chronionej w ustawianiu repozytorium.

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.