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?
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:
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łęzibranch.<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:
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
Naorigin/master
- połącz swoją dedykowaną gałąź z
master
, zawsze zachowując commity z dedykowanej gałęzi (co oznacza tworzenie nowych wersji na górzemaster
, które będą odzwierciedlać Twoją dedykowaną gałąź).
Zobacz " git command for making one branch like another" for strategies to simulate agit merge --strategy=theirs
.
W ten sposób możesz przesunąć master do pilota bez konieczności wymuszania czegokolwiek.
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.
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