Miałem repozytorium z kilkoma złymi zatwierdzeniami (D, E i F w tym przykładzie).
ABCDEF master i origin / master
Zmodyfikowałem lokalne repozytorium specjalnie za pomocą git reset --hard
. Przed resetem wziąłem gałąź, więc teraz mam repozytorium, które wygląda następująco:
A-B-C master
\ D-E-F old_master
A-B-C-D-E-F origin/master
Teraz potrzebowałem części tych złych zatwierdzeń, więc wybrałem potrzebne bity i zrobiłem kilka nowych zatwierdzeń, więc teraz mam następujące lokalnie:
A-B-C-G-H master
\ D-E-F old_master
Teraz chcę przekazać ten stan rzeczy do zdalnego repozytorium. Jednak, gdy próbuję zrobić git push
Git, uprzejmie daj mi odpocząć:
$ git push origin +master:master --force
Total 0 (delta 0), reused 0 (delta 0)
error: denying non-fast forward refs/heads/master (you should pull first)
To [email protected]:myrepo.git
! [remote rejected] master -> master (non-fast forward)
error: failed to push some refs to '[email protected]:myrepo.git'
Jak sprawić, by zdalne repozytorium przyjęło bieżący stan repozytorium lokalnego?
git push -force
ostrożniej .Odpowiedzi:
Jeśli wymuszenie wypychania nie pomaga ( powinno wystarczyć „
git push --force origin
” lub „git push --force origin master
”), może to oznaczać, że serwer zdalny odmawia wypychania niezwiązanego z szybkim przewijaniem albo przez zmienną konfiguracyjną receive.denyNonFastForwards (zobacz opis instrukcji git config ) lub za pośrednictwem haka aktualizacji / odbioru wstępnego.W starszej wersji Git możesz obejść to ograniczenie, usuwając „
git push origin :master
” (patrz „:” przed nazwą oddziału), a następnie ponownie tworząc „git push origin master
” dany oddział.Jeśli nie możesz tego zmienić, jedynym rozwiązaniem byłoby zamiast przepisywania historii, aby utworzyć zmiany cofające zmiany w DEF :
źródło
get revert HEAD~N
pomógł.N
to liczba zatwierdzeń. Np. Jeśli potrzebuję poprzedniego zatwierdzenia, użyjęgit revert HEAD~1
Aby uzupełnić odpowiedź Jakuba, jeśli masz dostęp do zdalnego serwera git w ssh, możesz przejść do zdalnego katalogu git i ustawić:
Następnie wróć do lokalnego repozytorium, spróbuj ponownie wykonać zatwierdzenie za pomocą
--force
:I w końcu przywróć ustawienia serwera w pierwotnym stanie chronionym:
źródło
vi
znajdują się w tym poście SO: stackoverflow.com/a/43721579/2073804Zamiast naprawiać gałąź „master”, o wiele łatwiej jest zamienić ją na „pożądany master”, zmieniając nazwy gałęzi. Zobacz https://stackoverflow.com/a/2862606/2321594 . W ten sposób nie zostawisz nawet śladu wielu dzienników przywracania.
źródło
Cały proces resetowania gitów wydawał mi się skomplikowany.
Zrobiłem więc coś, co sprawiło, że mój folder src znalazł się w stanie, który kilka razy temu zatwierdziłem
W ten sposób stan rzeczy w src jest przechowywany w pliku tar, a git jest zmuszony zaakceptować ten stan bez zbytniej manipulacji, w zasadzie katalog src zostaje zastąpiony stanem, który miał kilka zatwierdzeń wcześniej.
źródło
Dla użytkowników GitHub działało to dla mnie:
git reset --hard <full_hash_of_commit_to_reset_to>
git push --force
Spowoduje to „skorygowanie” historii gałęzi na twoim komputerze lokalnym i serwerze GitHub, ale każdy, kto zsynchronizował tę gałąź z serwerem od czasu złego zatwierdzenia, będzie miał historię na swoim komputerze lokalnym. Jeśli mają uprawnienia do bezpośredniego przesyłania do oddziału, wówczas te zatwierdzenia będą wyświetlane od razu po zsynchronizowaniu.
Wszystko, co wszyscy muszą zrobić, to
git reset
polecenie z góry, aby „poprawić” gałąź na lokalnym komputerze. Oczywiście musieliby uważać na wszelkie lokalne zobowiązania dokonane w tym oddziale po haszu docelowym. Cherry pick / backup i zastosuj je ponownie, jeśli to konieczne, ale jeśli jesteś w chronionym oddziale, liczba osób, które mogą bezpośrednio do niego zaangażować, jest prawdopodobnie ograniczona.źródło