Wymuś "git push", aby nadpisać zdalne pliki

Chcę wypchnąć moje lokalne pliki i mieć je na zdalnym repo, bez konieczności radzenia sobie z konfliktami scalania. Chcę tylko, żeby moja lokalna wersja miała pierwszeństwo przed zdalną.

Jak mogę to zrobić z Gitem?

 563
Author: opensas, 2012-05-09

4 answers

Powinieneś być w stanie wymusić lokalną wersję zdalnego repo za pomocą

git push -f <remote> <branch>

(np. git push -f origin master). Pominięcie <remote> i <branch> wymusi wypchnięcie wszystkich lokalnych gałęzi, które ustawiły --set-upstream.

Ostrzegam, jeśli inne osoby udostępnią to repozytorium, ich historia wersji będzie sprzeczna z nowym. A jeśli mają jakieś lokalne commity po zmianie, staną się nieważne.

Update : pomyślałem, że dodam notatkę poboczną. Jeśli jesteś tworzenie zmian, które inni przejrzą, nie jest rzadkością, aby utworzyć gałąź z tymi zmianami i okresowo zmieniać bazę danych, aby być na bieżąco z główną gałęzią rozwoju. Po prostu poinformuj innych deweloperów, że będzie to miało miejsce okresowo, aby wiedzieli, czego się spodziewać.

Aktualizacja 2: ze względu na rosnącą liczbę widzów chciałbym dodać kilka dodatkowych informacji na temat tego, co zrobić, gdy upstream doświadczy siły push.

Powiedz, że sklonowałem Twoje repo i dodałem kilka commitów w ten sposób:

            D----E  topic
           /
A----B----C         development

Ale później gałąź development zostanie uderzona rebase, co spowoduje, że otrzymam taki błąd, gdy uruchomię git pull:

Unpacking objects: 100% (3/3), done.
From <repo-location>
 * branch            development     -> FETCH_HEAD
Auto-merging <files>
CONFLICT (content): Merge conflict in <locations>
Automatic merge failed; fix conflicts and then commit the result.

Tutaj mógłbym naprawić konflikty i commit, ale zostawiłoby mi to naprawdę brzydką historię commitów: {]}

       C----D----E----F    topic
      /              /
A----B--------------C'  development

Może to wyglądać kusząco, aby użyć git pull --force ale bądź ostrożny, ponieważ to pozostawi cię z osieroconymi commitami:

            D----E   topic

A----B----C'         development

Więc prawdopodobnie najlepszą opcją jest wykonanie git pull --rebase. To będzie wymagał ode mnie rozwiązania wszelkich konfliktów, jak wcześniej, ale dla każdego kroku zamiast popełnienia użyję git rebase --continue. W końcu historia zmian będzie wyglądać znacznie lepiej:

            D'---E'  topic
           /
A----B----C'         development

Aktualizacja 3: Możesz również użyć opcji --force-with-lease jako "bezpieczniejszej" siły push, Jak wspomniano przez Cupcake w jego odpowiedź :

Pchanie siłą z "dzierżawą" pozwala na niepowodzenie pchania siłą, jeśli istnieje są nowe commity na zdalnym, których się nie spodziewałeś (technicznie, jeśli ty nie ściągnął je do swojej gałęzi zdalnego śledzenia), które jest przydatny, jeśli nie chcesz przypadkowo zastąpić cudzego commity, o których nawet jeszcze nie wiedziałeś, a po prostu chcesz Nadpisz własne:

git push <remote> <branch> --force-with-lease

Możesz dowiedzieć się więcej o tym, jak używać --force-with-lease przez czytanie dowolnego z poniższych:

 805
Author: Trevor Norris,
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:26:21

You want to force push

To, co w zasadzie chcesz zrobić, to wymusić naciśnięcie lokalnej gałęzi, aby zastąpić zdalną.

Jeśli chcesz bardziej szczegółowe wyjaśnienie każdego z poniższych poleceń, zajrzyj do sekcji Moje szczegóły poniżej. W zasadzie masz 4 różne opcje forsowania za pomocą Git:

git push <remote> <branch> -f
git push origin master -f # Example

git push <remote> -f
git push origin -f # Example

git push -f

git push <remote> <branch> --force-with-lease

Jeśli chcesz bardziej szczegółowe wyjaśnienie każdego polecenia, zobacz moje długie Odpowiedzi poniżej.

Warning: force naciśnięcie nadpisze zdalną gałąź stanem gałęzi, którą naciskasz. Upewnij się, że to jest to, co naprawdę chcesz zrobić, zanim go użyjesz, W przeciwnym razie możesz nadpisać commity, które chcesz zachować.

Force pushing Detail

Określanie zdalnego i gałęzi

Możesz całkowicie określić konkretne gałęzie i zdalnego. Flaga -f jest skróconą wersją --force

git push <remote> <branch> --force
git push <remote> <branch> -f

Pominięcie gałęzi

Gdy gałąź do push branch jest pominięty, Git domyśli się tego na podstawie Twoich ustawień konfiguracyjnych. W wersji Git po 2.0, nowy repo będzie miał domyślne ustawienia, aby wypchnąć aktualnie sprawdzoną gałąź:

git push <remote> --force

Podczas gdy przed 2.0, nowe repozytoria będą miały domyślne ustawienia do wypychania wielu lokalnych gałęzi. Ustawienia, o których mowa, to ustawienia remote.<remote>.push i push.default (patrz poniżej).

Pominięcie pilota i gałęzi

Gdy pomija się zarówno zdalny, jak i gałąź, zachowanie tylko git push --force jest określone przez twoje push.default Git config settings:

git push --force
  • Od wersji Git 2.0, domyślne ustawienie, simple, po prostu przesunie bieżącą gałąź do jej zdalnego licznika. Zdalny jest określony przez ustawienie gałęzi branch.<remote>.remote, A domyślnie repo origin w przeciwnym razie.

  • Przed wersją 2.0 Git, domyślne ustawienie, matching, W zasadzie popycha wszystkie lokalne gałęzie do gałęzi o tej samej nazwie na zdalnym (który domyślnie origin).

Możesz przeczytać więcej ustawień push.default, czytając git help config lub wersję Online strony podręcznika git-config(1) .

Siła pchania bezpieczniej --force-with-lease

Force push z "dzierżawą" pozwala na niepowodzenie force push, jeśli na pilocie są nowe commity, których się nie spodziewałeś (technicznie, jeśli nie pobrałeś ich jeszcze do gałęzi remote-tracking), co jest przydatne, jeśli nie chcesz przypadkowo zastąpić kogoś commity else ' a, o których nawet jeszcze nie wiedziałeś i chcesz tylko nadpisać własne: {]}

git push <remote> <branch> --force-with-lease

Możesz dowiedzieć się więcej o tym, jak używać --force-with-lease, czytając jedną z następujących czynności:

 102
Author: Community,
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:10:31

Inną opcją (aby uniknąć wymuszonego pchnięcia, które może być problematyczne dla innych współpracowników) jest:

  • umieść nowe commity w dedykowanej gałęzi
  • zresetuj swoje master Na origin/master
  • połącz swoją dedykowaną gałąź z master, zawsze zachowując commity z dedykowanej gałęzi (co oznacza tworzenie nowych wersji na górze master, które będą odzwierciedlać Twoją dedykowaną gałąź).
    Zobacz " git command for making one branch like another" for strategies to simulate a git merge --strategy=theirs.

W ten sposób możesz przesunąć master do pilota bez konieczności wymuszania czegokolwiek.

 25
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
2018-01-16 06:59:06

Git push-f jest nieco destrukcyjny, ponieważ resetuje wszelkie zdalne zmiany, które zostały wprowadzone przez kogokolwiek innego w zespole. Bezpieczniejszą opcją jest {git push --force-with-lease}.

To, co robi {--force-with-lease}, to odmowa aktualizacji gałęzi, chyba że jest to stan, którego oczekujemy; tzn. nikt nie zaktualizował gałęzi pod prąd. W praktyce działa to poprzez sprawdzenie, czy upstream ref jest tym, czego oczekujemy, ponieważ refs są hashami i domyślnie kodują łańcuch rodziców do ich wartości. Możesz powiedz {--force-with - lease} co dokładnie sprawdzić, ale domyślnie sprawdzi bieżący zdalny ref. Oznacza to w praktyce, że gdy Alice zaktualizuje swoją gałąź i wypchnie ją do zdalnego repozytorium, ref wskazujący głowę gałęzi zostanie zaktualizowany. Jeśli Bob nie wyciągnie pilota, jego lokalne odniesienie do pilota będzie nieaktualne. Kiedy przejdzie do push używając {--force-with-lease}, git sprawdzi lokalny ref względem nowego pilota i odmówi wymusić push. {--force-with - lease} skutecznie pozwala na wymuszanie tylko wtedy, gdy nikt inny nie pchnął zmian do pilota w międzyczasie. To jest {--force} z zapiętymi pasami.

 2
Author: Lando Ke,
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-05 11:32:34