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.

Wie kann ich das mit Git machen?


106
Hat git push origin --forcebei dir nicht funktioniert?


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:

            D '--- E' Thema
           /.
A ---- B ---- C 'Entwicklung

Update 3: Sie können die --force-with-leaseOption auch als "sichereren" Kraftstoß verwenden, wie von Cupcake in seiner Antwort erwähnt :

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:


5
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:

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

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

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

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:

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).

Sie können mehr lesen push.defaultEinstellungen durch Lese git help configoder 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:

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 ;)


32

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.



0

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

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.