865 Stimmen

Wie schiebe ich eine geänderte Übergabe an das entfernte Git-Repository?

Als ich ein wenig mit meinem Quellcode gearbeitet habe, habe ich mein übliches Ding Commit gemacht und dann in ein entferntes Repository gepusht. Aber dann habe ich bemerkt, dass ich vergessen habe, meine Importe im Quellcode zu organisieren. Also habe ich den Befehl amend ausgeführt, um den vorherigen Commit zu ersetzen:

> git commit --amend

Leider kann der Commit nicht in das Repository zurückgeschoben werden. Sie wird auf diese Weise abgelehnt:

> git push origin
To //my.remote.repo.com/stuff.git/
 ! [rejected]        master -> master (non-fast forward)
error: failed to push some refs to '//my.remote.repo.com/stuff.git/'

Was sollte ich tun? (Ich kann auf das entfernte Repository zugreifen.)

2 Stimmen

Was wäre, wenn ich mit --amend nur die Commit-Nachricht ändern würde? Gibt es eine Möglichkeit, die letzte Commit-Nachricht allein zu bearbeiten, wenn sie bereits an die Gegenstelle übertragen wurde? Ich habe das auf Github gemacht und erhielt die gleiche Meldung über die nicht schnelle Weiterleitung. Dann habe ich die folgende Lösung angewandt, aber der Merge hat nur weitere Commit-Nachrichten hinzugefügt.

9 Stimmen

@faB: Ich denke, das ist eine FAQ. Eine Commit-Nachricht wird zusammen mit dem Commit gehasht, so dass das Ändern es ändert den Revid (Hash). Falls es nicht klar ist: Nein, das geht nicht. IIRC kann Out-of-Band-Informationen in Notizen speichern (so dass Sie bestehende Commits mit Anmerkungen versehen können, ohne sie zu verändern). Um bestimmte Commits zu kennzeichnen, verwenden Sie Tags

1 Stimmen

In Kürze (git1.8.5, Q4 2013) werden Sie in der Lage sein eine git push -force sorgfältiger .

635voto

Ich habe tatsächlich einmal mit --force y .git Repository und wurde von Linus gescholten GROSSE ZEIT . Im Allgemeinen wird dies eine Menge Probleme für andere Menschen schaffen. Eine einfache Antwort lautet: "Tun Sie es nicht".

Wie ich sehe, haben andere das Rezept dafür bereits genannt, so dass ich es hier nicht wiederholen möchte. Aber hier ist ein Tipp, um sich von dieser Situation zu erholen nach Sie haben den geänderten Commit mit --force (oder +master) herausgeschoben.

  1. Verwenden Sie git reflog um den alten Commit zu finden, den Sie geändert haben (nennen Sie ihn old und wir nennen die neue Übertragung, die Sie durch die Änderung von new ).
  2. Erstellen Sie eine Zusammenführung zwischen old y new , die den Baum von new , wie git checkout new && git merge -s ours old .
  3. Führen Sie diese in Ihren Master mit git merge master
  4. Aktualisieren Sie Ihren Master mit dem Ergebnis mit git push . HEAD:master
  5. Drücken Sie das Ergebnis aus.

Dann werden die Leute, die das Pech hatten, ihre Arbeit auf den Commit zu stützen, den Sie durch Ändern und Erzwingen eines Pushs ausgelöscht haben, den daraus resultierenden Merge sehen und sehen, dass Sie die new über old . Ihre späteren Fusionen werden die Konflikte zwischen old y new die durch Ihre Änderung entstanden sind, damit sie nicht leiden müssen.

325voto

CB Bailey Punkte 693084

Sie sehen ein Sicherheitsmerkmal von Git. Git weigert sich, den entfernten Zweig mit Ihrem Zweig zu aktualisieren, weil der Head-Commit Ihres Zweigs kein direkter Nachkomme des aktuellen Head-Commits des Zweigs ist, in den Sie pushen.

Wäre dies nicht der Fall, dann wüssten zwei Personen, die etwa zur gleichen Zeit in dasselbe Repository pushen, nicht, dass zur gleichen Zeit ein neuer Commit eintrifft, und derjenige, der zuletzt gepusht hat, würde die Arbeit des vorherigen Pushers verlieren, ohne dass einer von ihnen dies bemerkt.

Wenn Sie wissen, dass Sie die einzige Person sind, die einen Push durchführt, und Sie einen geänderten Commit oder einen Commit, der den Zweig zurückspult, pushen wollen, können Sie Git "zwingen", den entfernten Zweig zu aktualisieren, indem Sie die -f Schalter.

git push -f origin master

Selbst dies könnte nicht funktionieren, da Git es entfernten Repositories erlaubt, nicht-fastforward-Pushes auf der Gegenseite zu verweigern, indem sie die Konfigurationsvariable receive.denynonfastforwards . Ist dies der Fall, sieht der Ablehnungsgrund wie folgt aus (beachten Sie den Teil "remote rejected"):

 ! [remote rejected] master -> master (non-fast forward)

Um dies zu umgehen, müssen Sie entweder die Konfiguration des entfernten Repositorys ändern oder Sie können den Zweig löschen und neu erstellen:

git push origin :master
git push origin master

Im Allgemeinen ist der letzte Parameter von git push verwendet das Format <local_ref>:<remote_ref> , wobei local_ref ist der Name des Zweigs im lokalen Repository und remote_ref ist der Name des Zweigs im entfernten Repository. Dieses Befehlspaar verwendet zwei Abkürzungen. :master hat eine Null local_ref, was bedeutet, dass ein Null-Zweig auf die entfernte Seite geschoben wird master , d.h. den entfernten Zweig löschen. Ein Zweigname ohne : bedeutet, dass der lokale Zweig mit dem angegebenen Namen in den entfernten Zweig mit demselben Namen verschoben wird. master ist in dieser Situation die Abkürzung für master:master .

251voto

Schnelles Schimpfen: Die Tatsache, dass niemand die einfache Antwort hier gepostet hat, zeigt die verzweifelte Benutzerfeindlichkeit, die die Git CLI an den Tag legt.

Der "offensichtliche" Weg, dies zu tun, vorausgesetzt, Sie haben nicht versucht, den Push zu erzwingen, ist, zuerst zu ziehen. Dies zieht die Änderung, die Sie geändert haben (und daher nicht mehr haben), so dass Sie es wieder haben.

Sobald Sie alle Konflikte beseitigt haben, können Sie erneut drücken.

Also:

git pull

Wenn Sie Fehler beim Ziehen erhalten, ist vielleicht etwas in der Konfiguration Ihres lokalen Repositorys falsch (ich hatte einen falschen Verweis im Abschnitt .git/config branch).

Und nach

git push

Vielleicht erhalten Sie einen zusätzlichen Commit mit dem Betreff "Trivial merge".

128voto

mipadi Punkte 377834

Kurze Antwort: Veröffentlichen Sie keine geänderten Commits in einem öffentlichen Repo.

Lange Antwort: Ein paar Git-Befehle, wie git commit --amend y git rebase die Geschichtsgrafik tatsächlich umschreiben. Das ist in Ordnung, solange Sie Ihre Änderungen noch nicht veröffentlicht haben, aber sobald Sie das tun, sollten Sie wirklich nicht mit der Historie herumspielen, denn wenn jemand Ihre Änderungen bereits hat, könnte es fehlschlagen, wenn er versucht, sie erneut zu ziehen. Anstatt einen Commit zu ändern, sollten Sie einfach einen neuen Commit mit den Änderungen machen.

Wenn Sie jedoch wirklich eine geänderte Übergabe durchführen wollen, können Sie dies wie folgt tun:

$ git push origin +master:master

Der führende + erzwingt den Push, auch wenn er nicht zu einem "Fast-forward"-Commit führt. (Ein Fast-Forward-Commit findet statt, wenn die Änderungen, die Sie pushen, eine direkter Nachkomme der Änderungen bereits im öffentlichen Repo).

78voto

Faiza Punkte 701

Hier ist eine sehr einfache und saubere Methode, um Ihre Änderungen zu veröffentlichen, nachdem Sie bereits eine commit --amend :

git reset --soft HEAD^
git stash
git push -f origin master
git stash pop
git commit -a
git push origin master

Sie bewirkt Folgendes:

  • Setzen Sie den Kopf des Zweigs auf die übergeordnete Übertragung zurück.
  • Verstecken Sie diese letzte Übertragung.
  • Druck auf die Fernbedienung erzwingen. Die Gegenstelle hat jetzt nicht die letzte Übertragung.
  • Lass deinen Vorrat platzen.
  • Sauberes Bekenntnis.
  • Drücken Sie auf die Fernbedienung.

Vergessen Sie nicht zu wechseln origin y master wenn Sie dies auf einen anderen Zweig oder ein anderes Remote-System anwenden.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X