Jak właściwie wymusić Git push?

Skonfigurowałem zdalny Nie Nagi" główny " repo i sklonowałem go do mojego komputera. Wprowadziłem kilka lokalnych zmian, zaktualizowałem moje lokalne repozytorium i przesunąłem zmiany z powrotem do mojego zdalnego repo. Do tego momentu wszystko było w porządku.

Musiałem coś zmienić w zdalnym repo. Potem zmieniłem coś w moim lokalnym repo. Zdałem sobie sprawę, że zmiana zdalnego repo nie była potrzebna. Więc próbowałem git push z mojego lokalnego repo do mojego zdalnego repo, ale dostałem błąd w stylu:

Aby zapobiec ty od utraty historii, nie-szybkie aktualizacje były odrzucone Połącz zdalne zmiany przed ponownym naciśnięciem. Zobacz też o fast-forwards ' sekcja git push --help dla szczegółów.

Myślałem, że prawdopodobnie

git push --force

Zmusi moją lokalną kopię do przesunięcia zmian do zdalnej i uczyni ją taką samą. wymusza aktualizację, ale kiedy wracam do zdalnego repo i robię commit, zauważam, że pliki zawierają nieaktualne zmiany (te, które główny zdalny repo wcześniej miał).

Jak wspomniałem w komentarzu do jednej z odpowiedzi :

[próbowałem wymuszać, ale wracając do serwera głównego, aby zapisać zmiany, dostaję nieaktualną inscenizację. Tak więc, kiedy commit repozytoria nie są takie same. I kiedy próbuję użyć git push ponownie, dostaję ten sam błąd.

Jak mogę rozwiązać ten problem?

Author: Community, 2011-04-01

7 answers

Po prostu zrób:

git push origin <your_branch_name> --force

Lub jeśli masz konkretny repo:

git push https://git.... --force

Spowoduje to usunięcie poprzednich commitów i przesunięcie bieżącego.

To może nie być właściwe, ale jeśli ktoś natknie się na tę stronę, pomyślałem, że może chcieć prostego rozwiązania...

Krótka flaga

Zauważ również, że -f jest skrótem od --force, więc

git push origin <your_branch_name> -f

Będzie również działać.

 1800
Author: Katie S,
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-06-21 13:19:08

A jeśli {[2] }nie zadziała, możesz to zrobić push --delete. Spójrz na 2 ND wiersz na tej instancji:

git reset --hard HEAD~3  # reset current branch to 3 commits ago
git push origin master --delete  # do a very very bad bad thing
git push origin master  # regular push
Ale uważaj...

Nigdy przenigdy nie wracaj do publicznej historii Gita!

Innymi słowy:

    Nigdy nie naciskaj na publiczne repozytorium.
  • nie rób tego ani niczego, co może złamać czyjąś pull.
  • nigdy reset lub rewrite historia w repo ktoś może już wyciągnął.

Oczywiście istnieją wyjątkowo rzadkie wyjątki nawet od tej zasady, ale w większości przypadków nie jest to konieczne, a to będzie generować problemy dla wszystkich innych.

Zamiast tego wykonaj revert.

I zawsze uważaj na to, co wciskasz do publicznego repo. Reverting:

git revert -n HEAD~3..HEAD  # prepare a new commit reverting last 3 commits
git commit -m "sorry - revert last 3 commits because I was not careful"
git push origin master  # regular push

W efekcie, obie głowice origin (z revert i z Evil reset ) będą zawierały te same pliki.


Edytuj, aby dodać zaktualizowane informacje i więcej argumentów wokół push --force

Rozważmy siłę pchania z dzierżawą zamiast pchania, ale nadal preferujemy odwrócenie]}

Inny problem push --force może przynieść jest, gdy ktoś nacisnąć cokolwiek przed tobą, ale po już pobrane. Jeśli naciśniesz siłę swojej rebased Wersja teraz zastąpi pracę z innych.

git push --force-with-lease wprowadzony w git 1.8.5 (dzięki @VonC komentarz do pytania) stara się rozwiązać ten konkretny problem. Zasadniczo będzie wprowadź błąd i nie naciskaj, jeśli pilot został zmodyfikowany od ostatniego pobrania.

Jest to dobre, jeśli jesteś naprawdę pewien, że {[2] } jest potrzebny, ale nadal chcesz zapobiec większej liczbie problemów. Powiedziałbym, że powinno to być domyślne zachowanie push --force. Ale nadal nie jest to wymówka, by wymusić push. Ludzie, którzy pobrali przed Twoim rebase nadal będą mieli wiele problemów, których można łatwo uniknąć, gdybyś zamiast tego miał odwrócony.

I skoro mówimy o git --push instancjach...

Dlaczego ktoś miałby chcieć naciskać?

@linquize przyniósł dobry przykład siły nacisku na komentarze: wrażliwe dane. Źle wyciekłeś dane, których nie powinno się wypychać. Jeśli jesteś wystarczająco szybki, możesz "naprawić"* to przez wymuszenie naciśnięcia na górze.

* dane nadal będą na zdalnym , chyba że zrobisz również garbage collect , lub wyczyść je jakoś . Istnieje również oczywisty potencjał, aby mogła być rozpowszechniana przez innych, którzy już ją pobrali, ale masz pomysł.

 203
Author: cregox,
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-24 15:24:25

Po pierwsze, nie wprowadzałbym żadnych zmian bezpośrednio w" głównym " repo. Jeśli naprawdę chcesz mieć" główny " repo, Powinieneś tylko do niego naciskać, nigdy nie zmieniać go bezpośrednio.

Jeśli chodzi o błąd, który otrzymujesz, czy próbowałeś git pull z lokalnego repo, a następnie git push do głównego repo? To, co obecnie robisz (jeśli dobrze zrozumiałem), wymusza push, a następnie traci swoje zmiany w "głównym" repo. Najpierw należy scalić zmiany lokalnie.

 17
Author: ubik,
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-04-01 05:42:29

Jeśli jestem na lokalnej gałęzi A i chcę wymusić przesunięcie lokalnej gałęzi B do gałęzi origin C, mogę użyć następującej składni:

git push --force origin B:C
 13
Author: IcedDante,
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-05-28 18:25:43

Naprawdę polecam:

  • Push only to the main repo

  • Upewnij się, że główny repo jest nagim repo, aby nigdy nie mieć problemu z tym, że główne drzewo robocze repo nie jest zsynchronizowane z bazą .git. Zobacz " Jak przenieść lokalne repozytorium git na inny komputer?"

  • Jeśli musisz dokonać modyfikacji w głównym (gołym) repo, Sklonuj go (na głównym serwerze), zrób modyfikację i odepchnij do it

Innymi słowy, utrzymuj gołe repo dostępne zarówno z głównego serwera, jak i komputera lokalnego, aby mieć pojedynczy upstream repo z / do którego można wyciągnąć / wyciągnąć.

 10
Author: VonC,
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-05-23 12:02:46

To było nasze rozwiązanie do zastąpienia master w korporacyjnym repozytorium gitHub przy zachowaniu historii.

push -f opanowanie repozytoriów korporacyjnych jest często wyłączone, aby zachować historię oddziałów. To rozwiązanie zadziałało.

git fetch desiredOrigin
git checkout -b master desiredOrigin/master // get origin master

git checkout currentBranch  // move to target branch
git merge -s ours master  // merge using ours over master
// vim will open for the commit message
git checkout master  // move to master
git merge currentBranch  // merge resolved changes into master

Przesuń gałąź do desiredOrigin i stwórz Pr

 5
Author: mihai,
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
2016-05-26 21:31:51

Użyj następującego polecenia:

git push -f origin master
 4
Author: mustafa Elsayed,
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-04-10 14:00:18