Erzwinge "git push", um entfernte Dateien zu überschreiben
767
Ich möchte meine lokalen Dateien pushen und auf einem Remote-Repo speichern, ohne mich mit Zusammenführungskonflikten befassen zu müssen. Ich möchte nur, dass meine lokale Version Vorrang vor der Remote-Version hat.
Es ist unklar, ob Sie nur die Git-Dateien oder die zugehörige Arbeitskopie überschreiben möchten. Wenn es das Git-Repository ist, ist Git-Push die Antwort. Wenn Sie die Remote-Arbeitskopie aktualisieren möchten, müssen Sie einen Post-Receive-Hook verwenden
Pierre-Olivier Vares
@ Mike, der aus irgendeinem Grund für mich funktioniert ... frage mich, was mit dem OP
Eine wahrscheinliche Ursache dafür, dass Force Push nicht funktioniert, ist, dass es auf dem Remote-Repo möglicherweise explizit deaktiviert wurde (um sicherzustellen, dass nichts durch idiotische und / oder bösartige Mitwirkende verloren geht): Verwenden Sie diese Option config receive.denyNonFastforwards, um dies herauszufinden.
Frank Nocke
Antworten:
1086
Sie sollten in der Lage sein, Ihre lokale Revision mit dem Remote-Repo zu erzwingen
git push -f <remote> <branch>
(zB git push -f origin master). Wenn Sie aufhören <remote>und <branch>alle lokalen Zweige erzwingen, die sich gesetzt haben --set-upstream.
Seien Sie gewarnt, wenn andere Personen dieses Repository freigeben, wird ihr Revisionsverlauf mit dem neuen in Konflikt stehen. Und wenn sie nach dem Zeitpunkt der Änderung lokale Commits haben, werden sie ungültig.
Update : Ich dachte, ich würde eine Randnotiz hinzufügen. Wenn Sie Änderungen erstellen, die von anderen überprüft werden, ist es nicht ungewöhnlich, einen Zweig mit diesen Änderungen zu erstellen und regelmäßig neu zu starten, um sie mit dem Hauptentwicklungszweig auf dem neuesten Stand zu halten. Lassen Sie andere Entwickler wissen, dass dies regelmäßig geschieht, damit sie wissen, was sie erwartet.
Update 2 : Aufgrund der zunehmenden Anzahl von Zuschauern möchte ich einige zusätzliche Informationen hinzufügen, was zu tun ist, wenn bei Ihnen upstreamein Force-Push auftritt.
Angenommen, ich habe Ihr Repo geklont und einige Commits wie folgt hinzugefügt:
D ---- E Thema
/.
A ---- B ---- C Entwicklung
Aber später wird der developmentZweig mit einem getroffen rebase, was dazu führt, dass ich beim Ausführen einen Fehler wie diesen erhalte git pull:
Objekte auspacken: 100% (3/3), fertig.
Von <Reposition>
* Filialentwicklung -> FETCH_HEAD
Automatisches Zusammenführen von <Dateien>
KONFLIKT (Inhalt): Konflikt in <Standorte> zusammenführen
Automatische Zusammenführung fehlgeschlagen; Beheben Sie Konflikte und schreiben Sie das Ergebnis fest.
Hier könnte ich die Konflikte beheben und commit, aber das würde mich mit einer wirklich hässlichen Commit-Geschichte zurücklassen:
C ---- D ---- E ---- F Thema
///
A ---- B -------------- C 'Entwicklung
Die Verwendung mag verlockend aussehen, git pull --forceaber seien Sie vorsichtig, da Sie sonst gestrandete Verpflichtungen haben:
D ---- E Thema
A ---- B ---- C 'Entwicklung
Die wahrscheinlich beste Option ist also, eine git pull --rebase. Dies erfordert, dass ich alle Konflikte wie zuvor löse, aber für jeden Schritt, anstatt mich zu verpflichten, werde ich verwenden git rebase --continue. Am Ende wird der Commit-Verlauf viel besser aussehen:
Beim Force-Pushing mit einem "Lease" schlägt der Force-Push fehl, wenn auf der Fernbedienung neue Commits vorhanden sind, die Sie nicht erwartet haben (technisch gesehen, wenn Sie sie noch nicht in Ihren Remote-Tracking-Zweig abgerufen haben). Dies ist hilfreich, wenn Sie möchten nicht versehentlich die Commits anderer Personen überschreiben, von denen Sie noch nicht einmal wussten, und Sie möchten nur Ihre eigenen überschreiben:
git push <remote> <branch> --force-with-lease
Weitere Informationen zur Verwendung finden Sie --force-with-leasein den folgenden Abschnitten:
Da dies die ausgewählte Antwort ist, werde ich hier einen Kommentar abgeben. Gewalt anzuwenden ist kein Problem, wenn Sie alleine arbeiten. Zum Beispiel beginnt mein Cloud-Host mit einem eigenen Git. Wenn ich lokal arbeite und ein Projekt erstelle und es auf meinem Cloud-Host (OpenShift) ablegen möchte, habe ich zwei separate Git-Projekte. Mein lokaler und mein OpenShift. Ich bekomme mein Lokal nach Belieben, möchte es aber jetzt in meinem OpenShift in der Vorschau anzeigen. Anschließend drücken Sie zum ersten Mal mit -fflag auf OpenShift . Stellen Sie Ihren lokalen Git im Wesentlichen auf OpenShift.
Wade
128
Sie möchten Push erzwingen
Was Sie im Grunde tun möchten, ist, Ihren lokalen Zweig zwangsweise zu pushen, um den entfernten Zweig zu überschreiben.
Wenn Sie eine detailliertere Erläuterung der folgenden Befehle wünschen, lesen Sie meinen Abschnitt mit den Details unten. Grundsätzlich haben Sie 4 verschiedene Optionen für das Force-Pushing mit Git:
Wenn Sie eine detailliertere Erläuterung der einzelnen Befehle wünschen, lesen Sie meinen Abschnitt mit langen Antworten weiter unten.
Warnung: Beim Force-Push wird der Remote-Zweig mit dem Status des Zweigs überschrieben, den Sie drücken. Stellen Sie sicher, dass Sie dies wirklich tun möchten, bevor Sie es verwenden. Andernfalls können Sie Commits überschreiben, die Sie tatsächlich behalten möchten.
Drücken Sie Details
Angabe der Fernbedienung und des Zweigs
Sie können bestimmte Zweige und eine Fernbedienung vollständig angeben. Die -fFlagge ist die Kurzversion von--force
Wenn der Zweig zum Verschieben des Zweigs weggelassen wird, ermittelt Git dies anhand Ihrer Konfigurationseinstellungen. In Git-Versionen nach 2.0 verfügt ein neues Repo über Standardeinstellungen, um den aktuell ausgecheckten Zweig zu verschieben:
git push <remote> --force
Vor 2.0 haben neue Repos Standardeinstellungen, um mehrere lokale Zweige zu pushen. Bei den fraglichen Einstellungen handelt es sich um die Einstellungen remote.<remote>.pushund push.default(siehe unten).
Weglassen der Fernbedienung und des Zweigs
Wenn sowohl die Fernbedienung als auch der Zweig weggelassen werden, wird das Verhalten von just git push --forcedurch Ihre push.defaultGit-Konfigurationseinstellungen bestimmt:
git push --force
Ab Git 2.0, der Standardeinstellung simple, wird Ihr aktueller Zweig im Grunde nur zu seinem vorgelagerten Remote-Gegenstück verschoben. Die Fernbedienung wird durch die branch.<remote>.remoteEinstellung des Zweigs bestimmt und verwendet ansonsten standardmäßig das Ursprungs-Repo.
Vor Git Version 2.0, der Standardeinstellung, matchingwerden im Grunde alle lokalen Zweige zu Zweigen mit demselben Namen auf der Fernbedienung verschoben (standardmäßig Ursprung).
Beim Force-Pushing mit einem "Lease" schlägt der Force-Push fehl, wenn auf der Fernbedienung neue Commits vorhanden sind, die Sie nicht erwartet haben (technisch gesehen, wenn Sie sie noch nicht in Ihren Remote-Tracking-Zweig abgerufen haben). Dies ist hilfreich, wenn Sie möchten nicht versehentlich die Commits anderer Personen überschreiben, von denen Sie noch nicht einmal wussten, und Sie möchten nur Ihre eigenen überschreiben:
git push <remote> <branch> --force-with-lease
Weitere Informationen zur Verwendung finden Sie --force-with-leasein den folgenden Abschnitten:
Sie haben Recht, aber dies sollte wirklich nur in Ausnahmesituationen verwendet werden.
Scott Berrevoets
1
@ScottBerrevoets " Ich würde es vorziehen, das, was ich habe, zu pushen und es aus der Ferne überschreiben zu lassen, anstatt es zu integrieren. " Ich gab dem OP genau das, wonach er fragte.
Ich weiß, aber OP ist sich möglicherweise der Konsequenzen nicht bewusst. Sie haben die Frage technisch beantwortet, aber ich denke, eine Warnung, dies nicht zu tun, ist nicht unangebracht.
Scott Berrevoets
1
@ScottBerrevoets Ich versuche, einen Moderator meine Antwort in die kanonische zusammenführen zu lassen, weil ich die neue --force-with-leaseOption ;)
Eine andere Option (um jeden erzwungenen Druck zu vermeiden, der für andere Mitwirkende problematisch sein kann) ist:
Legen Sie Ihre neuen Commits in einer eigenen Niederlassung ab
Setzen Sie Ihr masterauf zurückorigin/master
masterFühren Sie Ihren dedizierten Zweig mit zusammen , und behalten Sie immer Commits aus dem dedizierten Zweig bei (dh, Sie erstellen neue Revisionen, masterdie Ihren dedizierten Zweig widerspiegeln).
Unter " git-Befehl zum Erstellen eines Zweigs wie einen anderen " finden Sie Strategien zur Simulation von a git merge --strategy=theirs.
Auf diese Weise können Sie den Master auf die Fernbedienung schieben, ohne etwas erzwingen zu müssen.
Wie unterscheidet sich das Ergebnis von "Push-Force"?
Alexkovelsky
6
@alexkovelsky Jeder erzwungene Push würde den Verlauf neu schreiben und andere Benutzer des Repos dazu zwingen, ihr eigenes lokales Repo zurückzusetzen, um den neu gepussten Commits zu entsprechen. Dieser Ansatz erzeugt nur neue Commits und erfordert keinen erzwungenen Push.
VonC
1
Ich schlage vor, dass Sie Ihrer Antwort eine Überschrift hinzufügen: "Sie wollen keinen Druck erzwingen" :)
alexkovelsky
@alexkovelsky Guter Punkt. Ich habe die Antwort entsprechend bearbeitet.
VonC
4
git push -f ist etwas destruktiv, da es alle Remote-Änderungen zurücksetzt, die von anderen Mitgliedern des Teams vorgenommen wurden. Eine sicherere Option ist {git push --force-with-lease}.
Was {--force-with-lease} tut, ist sich zu weigern, einen Zweig zu aktualisieren, es sei denn, es ist der Zustand, den wir erwarten; dh niemand hat den Zweig stromaufwärts aktualisiert. In der Praxis funktioniert dies, indem überprüft wird, ob der vorgelagerte Verweis das ist, was wir erwarten, da Verweise Hashes sind und die Kette der Eltern implizit in ihren Wert kodieren. Sie können {--force-with-lease} genau mitteilen, worauf zu prüfen ist, aber standardmäßig wird die aktuelle Remote-Referenz überprüft. In der Praxis bedeutet dies, dass, wenn Alice ihren Zweig aktualisiert und in das Remote-Repository überträgt, der Referenzzeigerkopf des Zweigs aktualisiert wird. Wenn Bob nicht von der Fernbedienung zieht, ist sein lokaler Verweis auf die Fernbedienung veraltet. Wenn er mit {--force-with-lease} pusht, prüft git den lokalen Ref gegen die neue Fernbedienung und weigert sich, den Push zu erzwingen. Mit {--force-with-lease} können Sie Push-Push nur dann erzwingen, wenn in der Zwischenzeit niemand anderes Änderungen auf die Fernbedienung übertragen hat. Es ist {--force} mit angeschnalltem Sicherheitsgurt.
git push origin --force
bei dir nicht funktioniert?config receive.denyNonFastforwards
, um dies herauszufinden.Antworten:
Sie sollten in der Lage sein, Ihre lokale Revision mit dem Remote-Repo zu erzwingen
(zB
git push -f origin master
). Wenn Sie aufhören<remote>
und<branch>
alle lokalen Zweige erzwingen, die sich gesetzt haben--set-upstream
.Seien Sie gewarnt, wenn andere Personen dieses Repository freigeben, wird ihr Revisionsverlauf mit dem neuen in Konflikt stehen. Und wenn sie nach dem Zeitpunkt der Änderung lokale Commits haben, werden sie ungültig.
Update : Ich dachte, ich würde eine Randnotiz hinzufügen. Wenn Sie Änderungen erstellen, die von anderen überprüft werden, ist es nicht ungewöhnlich, einen Zweig mit diesen Änderungen zu erstellen und regelmäßig neu zu starten, um sie mit dem Hauptentwicklungszweig auf dem neuesten Stand zu halten. Lassen Sie andere Entwickler wissen, dass dies regelmäßig geschieht, damit sie wissen, was sie erwartet.
Update 2 : Aufgrund der zunehmenden Anzahl von Zuschauern möchte ich einige zusätzliche Informationen hinzufügen, was zu tun ist, wenn bei Ihnen
upstream
ein Force-Push auftritt.Angenommen, ich habe Ihr Repo geklont und einige Commits wie folgt hinzugefügt:
Aber später wird der
development
Zweig mit einem getroffenrebase
, was dazu führt, dass ich beim Ausführen einen Fehler wie diesen erhaltegit pull
:Hier könnte ich die Konflikte beheben und
commit
, aber das würde mich mit einer wirklich hässlichen Commit-Geschichte zurücklassen:Die Verwendung mag verlockend aussehen,
git pull --force
aber seien Sie vorsichtig, da Sie sonst gestrandete Verpflichtungen haben:Die wahrscheinlich beste Option ist also, eine
git pull --rebase
. Dies erfordert, dass ich alle Konflikte wie zuvor löse, aber für jeden Schritt, anstatt mich zu verpflichten, werde ich verwendengit rebase --continue
. Am Ende wird der Commit-Verlauf viel besser aussehen:Update 3: Sie können die
--force-with-lease
Option auch als "sichereren" Kraftstoß verwenden, wie von Cupcake in seiner Antwort erwähnt :quelle
-f
flag auf OpenShift . Stellen Sie Ihren lokalen Git im Wesentlichen auf OpenShift.Sie möchten Push erzwingen
Was Sie im Grunde tun möchten, ist, Ihren lokalen Zweig zwangsweise zu pushen, um den entfernten Zweig zu überschreiben.
Wenn Sie eine detailliertere Erläuterung der folgenden Befehle wünschen, lesen Sie meinen Abschnitt mit den Details unten. Grundsätzlich haben Sie 4 verschiedene Optionen für das Force-Pushing mit Git:
Wenn Sie eine detailliertere Erläuterung der einzelnen Befehle wünschen, lesen Sie meinen Abschnitt mit langen Antworten weiter unten.
Warnung: Beim Force-Push wird der Remote-Zweig mit dem Status des Zweigs überschrieben, den Sie drücken. Stellen Sie sicher, dass Sie dies wirklich tun möchten, bevor Sie es verwenden. Andernfalls können Sie Commits überschreiben, die Sie tatsächlich behalten möchten.
Drücken Sie Details
Angabe der Fernbedienung und des Zweigs
Sie können bestimmte Zweige und eine Fernbedienung vollständig angeben. Die
-f
Flagge ist die Kurzversion von--force
Verzweigung der Verzweigung
Wenn der Zweig zum Verschieben des Zweigs weggelassen wird, ermittelt Git dies anhand Ihrer Konfigurationseinstellungen. In Git-Versionen nach 2.0 verfügt ein neues Repo über Standardeinstellungen, um den aktuell ausgecheckten Zweig zu verschieben:
Vor 2.0 haben neue Repos Standardeinstellungen, um mehrere lokale Zweige zu pushen. Bei den fraglichen Einstellungen handelt es sich um die Einstellungen
remote.<remote>.push
undpush.default
(siehe unten).Weglassen der Fernbedienung und des Zweigs
Wenn sowohl die Fernbedienung als auch der Zweig weggelassen werden, wird das Verhalten von just
git push --force
durch Ihrepush.default
Git-Konfigurationseinstellungen bestimmt:Ab Git 2.0, der Standardeinstellung
simple
, wird Ihr aktueller Zweig im Grunde nur zu seinem vorgelagerten Remote-Gegenstück verschoben. Die Fernbedienung wird durch diebranch.<remote>.remote
Einstellung des Zweigs bestimmt und verwendet ansonsten standardmäßig das Ursprungs-Repo.Vor Git Version 2.0, der Standardeinstellung,
matching
werden im Grunde alle lokalen Zweige zu Zweigen mit demselben Namen auf der Fernbedienung verschoben (standardmäßig Ursprung).Sie können mehr lesen
push.default
Einstellungen durch Lesegit help config
oder eine Online - Version des git-config (1) Handbuch Seite .Drücken Sie sicherer mit
--force-with-lease
Beim Force-Pushing mit einem "Lease" schlägt der Force-Push fehl, wenn auf der Fernbedienung neue Commits vorhanden sind, die Sie nicht erwartet haben (technisch gesehen, wenn Sie sie noch nicht in Ihren Remote-Tracking-Zweig abgerufen haben). Dies ist hilfreich, wenn Sie möchten nicht versehentlich die Commits anderer Personen überschreiben, von denen Sie noch nicht einmal wussten, und Sie möchten nur Ihre eigenen überschreiben:
Weitere Informationen zur Verwendung finden Sie
--force-with-lease
in den folgenden Abschnitten:git push
Dokumentationquelle
--force-with-lease
Option;)
Eine andere Option (um jeden erzwungenen Druck zu vermeiden, der für andere Mitwirkende problematisch sein kann) ist:
master
auf zurückorigin/master
master
Führen Sie Ihren dedizierten Zweig mit zusammen , und behalten Sie immer Commits aus dem dedizierten Zweig bei (dh, Sie erstellen neue Revisionen,master
die Ihren dedizierten Zweig widerspiegeln).Unter " git-Befehl zum Erstellen eines Zweigs wie einen anderen " finden Sie Strategien zur Simulation von a
git merge --strategy=theirs
.Auf diese Weise können Sie den Master auf die Fernbedienung schieben, ohne etwas erzwingen zu müssen.
quelle
git push -f ist etwas destruktiv, da es alle Remote-Änderungen zurücksetzt, die von anderen Mitgliedern des Teams vorgenommen wurden. Eine sicherere Option ist {git push --force-with-lease}.
Was {--force-with-lease} tut, ist sich zu weigern, einen Zweig zu aktualisieren, es sei denn, es ist der Zustand, den wir erwarten; dh niemand hat den Zweig stromaufwärts aktualisiert. In der Praxis funktioniert dies, indem überprüft wird, ob der vorgelagerte Verweis das ist, was wir erwarten, da Verweise Hashes sind und die Kette der Eltern implizit in ihren Wert kodieren. Sie können {--force-with-lease} genau mitteilen, worauf zu prüfen ist, aber standardmäßig wird die aktuelle Remote-Referenz überprüft. In der Praxis bedeutet dies, dass, wenn Alice ihren Zweig aktualisiert und in das Remote-Repository überträgt, der Referenzzeigerkopf des Zweigs aktualisiert wird. Wenn Bob nicht von der Fernbedienung zieht, ist sein lokaler Verweis auf die Fernbedienung veraltet. Wenn er mit {--force-with-lease} pusht, prüft git den lokalen Ref gegen die neue Fernbedienung und weigert sich, den Push zu erzwingen. Mit {--force-with-lease} können Sie Push-Push nur dann erzwingen, wenn in der Zwischenzeit niemand anderes Änderungen auf die Fernbedienung übertragen hat. Es ist {--force} mit angeschnalltem Sicherheitsgurt.
quelle
Funktioniert bei mir:
quelle
Einfache Schritte mit Schildpatt
GIT, das lokale Dateien festschreibt und in das Git-Repository pusht.
Schritte :
1) Stash ändert den Stash-Namen
2) ziehen
3) Stash Pop
4) begehen 1 oder mehr Dateien und gibt commit Änderungen Beschreibung Set Autor und Datum
5) drücken
quelle