Chcę wypchnąć moje lokalne pliki i mieć je na zdalnym repozytorium, bez konieczności radzenia sobie z konfliktami scalania. Chcę tylko, aby moja wersja lokalna miała wyższy priorytet niż wersja zdalna.
Nie jest jasne, czy chcesz zastąpić tylko pliki .git lub powiązaną kopię roboczą. Jeśli jest to repozytorium git, odpowiedzią jest git push. Jeśli chcesz zaktualizować zdalną kopię roboczą, musisz użyć haka po odebraniu
Pierre-Olivier Vares
@Mike, który z jakiegoś powodu działa dla mnie ... zastanawiam się, co było z OP
Prawdopodobna przyczyna wymuszonego wypychania nie działa, ponieważ mogła zostać wyraźnie wyłączona na zdalnym repozytorium (aby upewnić się, że nic nie zostanie utracone z powodu idiotycznych i / lub złośliwych współpracowników): użyj, config receive.denyNonFastforwardsaby się dowiedzieć.
Frank Nocke,
Odpowiedzi:
1085
Powinieneś być w stanie wymusić lokalną wersję do zdalnego repozytorium za pomocą
git push -f <remote> <branch>
(np git push -f origin master.). Wyjście <remote>i <branch>wymusi wypchnięcie wszystkich lokalnych oddziałów, które zostały ustawione --set-upstream.
Ostrzegamy, że jeśli inne osoby współużytkują to repozytorium, ich historia zmian będzie w konflikcie z nowym. A jeśli mają jakieś lokalne zobowiązania po punkcie zmiany, staną się nieważne.
Aktualizacja : Myślałem, że dodam notatkę dodatkową. Jeśli tworzysz zmiany, które inni sprawdzą, nie jest rzadkością tworzenie gałęzi z tymi zmianami i okresowe wprowadzanie zmian w bazie, aby być na bieżąco z główną gałęzią programistyczną. Po prostu daj innym programistom do zrozumienia, że tak się stanie, aby wiedzieli, czego się spodziewać.
Aktualizacja 2 : Z powodu rosnącej liczby widzów chciałbym dodać dodatkowe informacje na temat tego, co robić, gdy upstreampojawia się wymuszenie.
Powiedzmy, że sklonowałem twoje repozytorium i dodałem kilka takich zmian:
D ---- E temat
/
Rozwój A ---- B ---- C.
Ale później developmentgałąź trafia z rebase, co spowoduje, że otrzymam błąd taki jak po uruchomieniu git pull:
Rozpakowywanie obiektów: 100% (3/3), gotowe.
Od <repolokalizacja>
* rozwój oddziału -> FETCH_HEAD
Automatyczne łączenie <plików>
KONFLIKT (treść): Scal konflikt w <lokalizacjach>
Automatyczne scalanie nie powiodło się; naprawić konflikty, a następnie zatwierdzić wynik.
Tutaj mogłem naprawić konflikty commit, ale to dałoby mi naprawdę brzydką historię popełnień:
Temat C ---- D ---- E ---- F.
/ /
Rozwój A ---- B -------------- C.
Może wyglądać kusząco w użyciu, git pull --forceale bądź ostrożny, ponieważ pozostawi cię z osieroconymi zatwierdzeniami:
D ---- E temat
Rozwój A ---- B ---- C '
Więc prawdopodobnie najlepszą opcją jest zrobienie git pull --rebase. Będzie to wymagać ode mnie rozwiązania wszelkich konfliktów, jak poprzednio, ale użyję każdego kroku zamiast popełnienia git rebase --continue. Na koniec historia zmian będzie wyglądać znacznie lepiej:
Wymuszone wypychanie z „dzierżawą” pozwala, aby wymuszone wypychanie nie powiodło się, jeśli na pilocie pojawią się nowe zatwierdzenia, których się nie spodziewałeś (technicznie rzecz biorąc, jeśli jeszcze nie wprowadziłeś ich do gałęzi zdalnego śledzenia), co jest przydatne, jeśli nie chcesz przypadkowo zastąpić cudzych zobowiązań, o których nawet jeszcze nie wiedziałeś, a po prostu chcesz zastąpić własne:
git push <remote> <branch> --force-with-lease
Możesz dowiedzieć się więcej o tym, jak korzystać --force-with-lease, czytając dowolne z poniższych:
Ponieważ jest to wybrana odpowiedź, skomentuję tutaj. Używanie siły nie stanowi problemu podczas samodzielnej pracy. Na przykład mój host w chmurze zaczyna się od własnego git. Jeśli pracuję lokalnie i buduję projekt i chcę go umieścić na moim hoście w chmurze (OpenShift), mam dwa osobne projekty git. Mój lokalny i mój OpenShift. Dostaję lokalny tak, jak lubię, ale teraz chcę go wyświetlić na moim OpenShift. Następnie naciskasz na OpenShift po raz pierwszy, używając -fflagi. Zasadniczo umieszczasz lokalnego git na OpenShift.
Wade
128
Chcesz wymusić push
W zasadzie chcesz wymusić wypchnięcie lokalnego oddziału, aby zastąpić zdalny.
Jeśli chcesz uzyskać bardziej szczegółowe objaśnienie każdego z poniższych poleceń, zobacz sekcję moje szczegóły poniżej. Zasadniczo masz 4 różne opcje forsowania za pomocą Git:
Jeśli chcesz uzyskać bardziej szczegółowe wyjaśnienie każdego polecenia, zobacz sekcję moich długich odpowiedzi poniżej.
Ostrzeżenie: wymuszone wypychanie zastąpi gałąź zdalną stanem gałęzi, którą wypychasz. Upewnij się, że to jest to, co naprawdę chcesz zrobić, zanim go użyjesz, w przeciwnym razie możesz zastąpić zatwierdzenia, które naprawdę chcesz zachować.
Wymuszaj pchanie szczegółów
Określanie zdalnego i rozgałęzienia
Możesz całkowicie określić określone gałęzie i pilota. -fFlaga jest krótka wersja--force
Kiedy gałąź do gałęzi push zostanie pominięta, Git odkryje ją na podstawie ustawień konfiguracji. W wersjach Git po wersji 2.0 nowe repozytorium będzie miało domyślne ustawienia wypychające aktualnie wyewidencjonowaną gałąź:
git push <remote> --force
w wersjach wcześniejszych niż 2.0 nowe repo będą miały domyślne ustawienia wypychania wielu lokalnych oddziałów. Ustawienia, o których mowa, to ustawienia remote.<remote>.pushi push.default(patrz poniżej).
Pominięcie pilota i oddziału
Gdy zarówno pilot, jak i gałąź zostaną pominięte, zachowanie just git push --forcejest określane przez push.defaultustawienia konfiguracji Git:
git push --force
Począwszy od Git 2.0, ustawienie domyślne simplepo prostu popchnie twoją obecną gałąź do jej zdalnej przeciwnej części. Zdalny jest określany przez ustawienie oddziału branch.<remote>.remote, aw przeciwnym razie domyślnie jest to repozytorium początkowe.
Przed wersją Git 2.0 ustawienie domyślne matchingpo prostu wypycha wszystkie gałęzie lokalne do gałęzi o tej samej nazwie na pilocie (domyślnie jest to początek).
Siła pchania bezpieczniej dzięki --force-with-lease
Wymuszone wypychanie z „dzierżawą” pozwala, aby wymuszone wypychanie nie powiodło się, jeśli na pilocie pojawią się nowe zatwierdzenia, których się nie spodziewałeś (technicznie rzecz biorąc, jeśli jeszcze nie wprowadziłeś ich do gałęzi zdalnego śledzenia), co jest przydatne, jeśli nie chcesz przypadkowo zastąpić cudzych zobowiązań, o których nawet jeszcze nie wiedziałeś, a po prostu chcesz zastąpić własne:
git push <remote> <branch> --force-with-lease
Możesz dowiedzieć się więcej o tym, jak korzystać --force-with-lease, czytając dowolne z poniższych:
Masz rację, ale tak naprawdę powinno się tego używać tylko w wyjątkowych sytuacjach.
Scott Berrevoets
1
@ ScottBerrevoets „ Wolałbym przesuwać to, co mam i pozwolić, aby zastąpiło je zdalnie, niż integrować. ” Dałem OP dokładnie to, o co prosił.
Wiem, ale OP może nie być świadomy konsekwencji takiego postępowania. Technicznie odpowiedziałeś na pytanie, ale myślę, że ostrzeżenie, aby tego nie robić, nie jest nie na miejscu.
Scott Berrevoets,
1
@ScottBerrevoets Staram się, aby moderator połączył moją odpowiedź w kanoniczny, ponieważ wspominam o nowej --force-with-leaseopcji;)
Inną opcją (aby uniknąć wymuszonego wypychania, które może być problematyczne dla innych autorów) jest:
umieść swoje nowe commity w dedykowanym oddziale
zresetować masterONorigin/master
połącz swój dedykowany oddział z master, zawsze zachowując zatwierdzenia z dedykowanego oddziału (co oznacza tworzenie nowych poprawek, masterktóre będą odzwierciedlały dedykowany oddział).
Zobacz „ Polecenie git, aby utworzyć jedną gałąź jak drugą ”, aby poznać strategie symulowania git merge --strategy=theirs.
W ten sposób możesz przepchnąć mistrza do pilota bez konieczności zmuszania czegokolwiek.
@alexkovelsky Każde wymuszone push zmieniłoby historię, zmuszając innych użytkowników repozytorium do zresetowania własnego repozytorium lokalnego, aby pasowało do nowo wypchniętych zatwierdzeń. Takie podejście tworzy tylko nowe zatwierdzenia i nie wymaga wymuszonego wypychania.
VonC
1
Proponuję dodać nagłówek do swojej odpowiedzi: „Nie chcesz wymuszać wypychania” :)
alexkovelsky 15.01.2018
@alexkovelsky Dobra uwaga. Odpowiednio zredagowałem odpowiedź.
VonC
4
git push -f jest nieco destrukcyjny, ponieważ resetuje wszelkie zdalne zmiany, które zostały wprowadzone przez kogoś innego w zespole. Bezpieczniejszą opcją jest {git push --force-with-lease}.
To, co robi {--force-with-lease}, to odmowa aktualizacji oddziału, chyba że tego oczekujemy; tzn. nikt nie zaktualizował oddziału powyżej. W praktyce działa to poprzez sprawdzenie, czy referencja w górę jest tym, czego oczekujemy, ponieważ referencje są skrótami i domyślnie kodują łańcuch rodziców do ich wartości. Możesz powiedzieć {--force-with-lease} dokładnie, co należy sprawdzić, ale domyślnie sprawdzi bieżący zdalny ref. W praktyce oznacza to, że kiedy Alice zaktualizuje swój oddział i wypchnie go do zdalnego repozytorium, głowa wskazująca oddział zostanie zaktualizowana. Teraz, chyba że Bob wykona ściąganie z pilota, jego lokalne odniesienie do pilota będzie nieaktualne. Kiedy pójdzie do wypychania za pomocą {--force-with-lease}, git sprawdzi lokalnego ref względem nowego pilota i odmówi wymuszenia push. {--force-with-lease} skutecznie pozwala na wymuszanie push tylko wtedy, gdy nikt inny nie przekazał w międzyczasie zmian do pilota. Jest {--force} z zapiętym pasem bezpieczeństwa.
git push origin --force
działało dla ciebie?config receive.denyNonFastforwards
aby się dowiedzieć.Odpowiedzi:
Powinieneś być w stanie wymusić lokalną wersję do zdalnego repozytorium za pomocą
(np
git push -f origin master
.). Wyjście<remote>
i<branch>
wymusi wypchnięcie wszystkich lokalnych oddziałów, które zostały ustawione--set-upstream
.Ostrzegamy, że jeśli inne osoby współużytkują to repozytorium, ich historia zmian będzie w konflikcie z nowym. A jeśli mają jakieś lokalne zobowiązania po punkcie zmiany, staną się nieważne.
Aktualizacja : Myślałem, że dodam notatkę dodatkową. Jeśli tworzysz zmiany, które inni sprawdzą, nie jest rzadkością tworzenie gałęzi z tymi zmianami i okresowe wprowadzanie zmian w bazie, aby być na bieżąco z główną gałęzią programistyczną. Po prostu daj innym programistom do zrozumienia, że tak się stanie, aby wiedzieli, czego się spodziewać.
Aktualizacja 2 : Z powodu rosnącej liczby widzów chciałbym dodać dodatkowe informacje na temat tego, co robić, gdy
upstream
pojawia się wymuszenie.Powiedzmy, że sklonowałem twoje repozytorium i dodałem kilka takich zmian:
Ale później
development
gałąź trafia zrebase
, co spowoduje, że otrzymam błąd taki jak po uruchomieniugit pull
:Tutaj mogłem naprawić konflikty
commit
, ale to dałoby mi naprawdę brzydką historię popełnień:Może wyglądać kusząco w użyciu,
git pull --force
ale bądź ostrożny, ponieważ pozostawi cię z osieroconymi zatwierdzeniami:Więc prawdopodobnie najlepszą opcją jest zrobienie
git pull --rebase
. Będzie to wymagać ode mnie rozwiązania wszelkich konfliktów, jak poprzednio, ale użyję każdego kroku zamiast popełnieniagit rebase --continue
. Na koniec historia zmian będzie wyglądać znacznie lepiej:Aktualizacja 3: Możesz również użyć tej
--force-with-lease
opcji jako „bezpieczniejszego” forsowania, jak wspomniał Cupcake w swojej odpowiedzi :źródło
-f
flagi. Zasadniczo umieszczasz lokalnego git na OpenShift.Chcesz wymusić push
W zasadzie chcesz wymusić wypchnięcie lokalnego oddziału, aby zastąpić zdalny.
Jeśli chcesz uzyskać bardziej szczegółowe objaśnienie każdego z poniższych poleceń, zobacz sekcję moje szczegóły poniżej. Zasadniczo masz 4 różne opcje forsowania za pomocą Git:
Jeśli chcesz uzyskać bardziej szczegółowe wyjaśnienie każdego polecenia, zobacz sekcję moich długich odpowiedzi poniżej.
Ostrzeżenie: wymuszone wypychanie zastąpi gałąź zdalną stanem gałęzi, którą wypychasz. Upewnij się, że to jest to, co naprawdę chcesz zrobić, zanim go użyjesz, w przeciwnym razie możesz zastąpić zatwierdzenia, które naprawdę chcesz zachować.
Wymuszaj pchanie szczegółów
Określanie zdalnego i rozgałęzienia
Możesz całkowicie określić określone gałęzie i pilota.
-f
Flaga jest krótka wersja--force
Pominięcie gałęzi
Kiedy gałąź do gałęzi push zostanie pominięta, Git odkryje ją na podstawie ustawień konfiguracji. W wersjach Git po wersji 2.0 nowe repozytorium będzie miało domyślne ustawienia wypychające aktualnie wyewidencjonowaną gałąź:
w wersjach wcześniejszych niż 2.0 nowe repo będą miały domyślne ustawienia wypychania wielu lokalnych oddziałów. Ustawienia, o których mowa, to ustawienia
remote.<remote>.push
ipush.default
(patrz poniżej).Pominięcie pilota i oddziału
Gdy zarówno pilot, jak i gałąź zostaną pominięte, zachowanie just
git push --force
jest określane przezpush.default
ustawienia konfiguracji Git:Począwszy od Git 2.0, ustawienie domyślne
simple
po prostu popchnie twoją obecną gałąź do jej zdalnej przeciwnej części. Zdalny jest określany przez ustawienie oddziałubranch.<remote>.remote
, aw przeciwnym razie domyślnie jest to repozytorium początkowe.Przed wersją Git 2.0 ustawienie domyślne
matching
po prostu wypycha wszystkie gałęzie lokalne do gałęzi o tej samej nazwie na pilocie (domyślnie jest to początek).Możesz przeczytać więcej
push.default
ustawień, czytającgit help config
lub wersję online strony podręcznika git-config (1) .Siła pchania bezpieczniej dzięki
--force-with-lease
Wymuszone wypychanie z „dzierżawą” pozwala, aby wymuszone wypychanie nie powiodło się, jeśli na pilocie pojawią się nowe zatwierdzenia, których się nie spodziewałeś (technicznie rzecz biorąc, jeśli jeszcze nie wprowadziłeś ich do gałęzi zdalnego śledzenia), co jest przydatne, jeśli nie chcesz przypadkowo zastąpić cudzych zobowiązań, o których nawet jeszcze nie wiedziałeś, a po prostu chcesz zastąpić własne:
Możesz dowiedzieć się więcej o tym, jak korzystać
--force-with-lease
, czytając dowolne z poniższych:git push
dokumentacjaźródło
--force-with-lease
opcji;)
Inną opcją (aby uniknąć wymuszonego wypychania, które może być problematyczne dla innych autorów) jest:
master
ONorigin/master
master
, zawsze zachowując zatwierdzenia z dedykowanego oddziału (co oznacza tworzenie nowych poprawek,master
które będą odzwierciedlały dedykowany oddział).Zobacz „ Polecenie git, aby utworzyć jedną gałąź jak drugą ”, aby poznać strategie symulowania
git merge --strategy=theirs
.W ten sposób możesz przepchnąć mistrza do pilota bez konieczności zmuszania czegokolwiek.
źródło
git push -f jest nieco destrukcyjny, ponieważ resetuje wszelkie zdalne zmiany, które zostały wprowadzone przez kogoś innego w zespole. Bezpieczniejszą opcją jest {git push --force-with-lease}.
To, co robi {--force-with-lease}, to odmowa aktualizacji oddziału, chyba że tego oczekujemy; tzn. nikt nie zaktualizował oddziału powyżej. W praktyce działa to poprzez sprawdzenie, czy referencja w górę jest tym, czego oczekujemy, ponieważ referencje są skrótami i domyślnie kodują łańcuch rodziców do ich wartości. Możesz powiedzieć {--force-with-lease} dokładnie, co należy sprawdzić, ale domyślnie sprawdzi bieżący zdalny ref. W praktyce oznacza to, że kiedy Alice zaktualizuje swój oddział i wypchnie go do zdalnego repozytorium, głowa wskazująca oddział zostanie zaktualizowana. Teraz, chyba że Bob wykona ściąganie z pilota, jego lokalne odniesienie do pilota będzie nieaktualne. Kiedy pójdzie do wypychania za pomocą {--force-with-lease}, git sprawdzi lokalnego ref względem nowego pilota i odmówi wymuszenia push. {--force-with-lease} skutecznie pozwala na wymuszanie push tylko wtedy, gdy nikt inny nie przekazał w międzyczasie zmian do pilota. Jest {--force} z zapiętym pasem bezpieczeństwa.
źródło
Pracuje dla mnie:
źródło
Proste kroki przy użyciu tortoisegit
GIT podający zatwierdzanie plików lokalnych i wypychanie do repozytorium git.
Kroki :
1) skrytka zmienia nazwę skrytki
2) pociągnij
3) stash pop
4) zatwierdzić 1 lub więcej plików i podać opis zmian zmian autora i datę
5) push
źródło