2011-01-07 18 views
78

Unter Berücksichtigung, dass es mehr git Befehle, die keinen Sinn in einem kahlen Repository machen (weil bare Repositories keine Indizes verwenden und ein Arbeitsverzeichnis nicht haben),Wie kann ich das letzte Commit in einem git bare Repository commommieren?

git reset --hard HEAD^ 

ist keine Lösung für uncommit die letzte Änderung in einem solchen Repository.

durch die Suche im Internet, alles, was ich zu dem Thema finden konnte, ist this, in dem ich vorgestellt habe drei Möglichkeiten, dies zu tun:
1. „update der Schiedsrichter manuell (die Sanitär beinhaltet)“;
2. "git push -f aus einem nicht-bare-Repository";
3. "git branch -f this $that".

Welche Lösung halten Sie für besser geeignet oder welche anderen Möglichkeiten gibt es? Leider ist die Dokumentation, die ich über git bare Repositories gefunden habe, ziemlich dürftig.

+7

@ Lavinia-Garbriela Dobrovol Verwenden Sie nicht die komplizierten Sachen unten. Du versuchst, HEAD zu einem anderen Commit zu bewegen und dafür ist git reset auch in einem bloßen Repo gedacht. Pro meine Antwort unten, benutze: git reset --soft Mit --soft, versuchen Sie nicht, ändern Sie eine funktionierende Struktur und Index, der nicht existiert, so Git lässt Sie den Reset kein Problem. – Hazok

Antwort

107

Sie können den Befehl git update-ref verwenden. So entfernen Sie die letzten begehen, verwenden Sie:

$ git update-ref HEAD HEAD^ 

Oder wenn Sie nicht in der Branche sind, von dem Sie kippen entfernen die letzte commit:

$ git update-ref refs/heads/branch-name branch-name^ 

Sie könnten auch einen SHA1 passieren, wenn Sie wollen:

$ git update-ref refs/heads/branch-name a12d48e2 

finden Sie in der Dokumentation des git-update-ref Befehl.

+0

Was ist der Kopf auf dem bloßen Repo ist nicht auf der rechten Seite? – VonC

+0

@ Lavinia-Gabriela Dobrovolschi: Richtig, ich kannte die genaue Syntax nicht. – VonC

+0

@VonC Sie können die in 'git update-ref ' als den richtigen Zweig angeben, wie zB "refs/heads/master" anstelle von HEAD. Ich hoffe, ich habe deine Frage nicht falsch verstanden. –

7

Die git push -f sollte funktionieren:
, wenn Sie das nackte Repo-Klon, entfernen Sie den letzten Commit (git reset --hard HEAD^ wie Sie erwähnen, aber in einem lokalen nicht-bare Repo) und zurückzudrängen (-f):

  • Sie ändern keinen SHA1 für die anderen Commits, die dem entfernten vorausgehen.
  • Sie sind sicher, dass Sie den genauen Inhalt des leeren Repos abzüglich der Extra-Commit zurückschieben (weil Sie es zuerst geklont haben).
+0

@ VonC Hi Von, Ich habe gesehen, dass du viel auf Git geantwortet hast, also wollte ich dich fragen ... Ich war neugierig, warum würde 'git reset --soft ' nicht wie in meiner Antwort unten gezeigt die empfohlene Praxis sein um HEAD auf einem bloßen Repo zu bewegen? – Hazok

+0

Ich denke, ein weiterer Grund, warum ich frage, ist, dass Soft Reset für bare Repos keine leicht verfügbaren Informationen sind und viele Foren unnötig komplexe Workarounds zu haben scheinen, wenn es so aussieht, als wäre der Soft Reset der beste Weg Möglichkeit für Fehler. – Hazok

+1

@Zach: Ein 'reset --soft' sollte funktionieren, wenn es direkt auf einem leeren Repo ausgeführt wird. Ich vermute, dass dies selten getan wird, weil ein bloßer Repo im Allgemeinen ein ** upstream Repo ** ist (dh ein Repo, zu dem Sie Daten pushen), und die meiste Zeit haben Sie keinen direkten lokalen Zugriff darauf . Aber wenn Sie das tun, dann ist dies sicherlich ein weiteres gutes Beispiel für die Verwendung von "reset --soft" (wie in http://stackoverflow.com/questions/5203535/practical-uses-of-git-reset-soft) +1 zu deiner Antwort. – VonC

25

Wenn Sie die folgenden in einem kahlen Repo:

git reset --soft <commit> 

dann laufen Sie nicht in die Probleme, die Sie haben --hard und --mixed Optionen in einem kahlen Repo verwenden, da Sie nicht, etwas zu ändern versuchen, das bloße Repo hat nicht (dh funktionierenden Baum und Index).In Ihrem Fall speziell würden Sie (aus dem bloßen Repo) zu verwenden:

git reset --soft HEAD^ 

Um switch branches on the remote repo tun:

git symbolic-ref HEAD refs/heads/<branch_name> 
+2

Wie wählen Sie den Zweig aus, den Sie verschieben möchten? Ihr Beispiel funktioniert gut auf Master aber 'git checkout other_branch' funktioniert nicht in einem bare. – Gauthier

+1

Hmmm ... Ich frage mich, wer mich dafür gewählt hat. In der Frage wurde nicht gefragt, wie man in einem Remote-Repo die Filialen wechseln soll. Verwenden Sie git symbolic-ref HEAD refs/heads/, um den Standardzweig in einem Remote-Repo zu ändern. – Hazok

2

Sie auch git Refspec Schreibweise verwenden können, und tun Sie etwas wie folgt aus:

git push -f origin +<commit you want to revert to>:<destination_head | branch_name>

Dies erzwingt die Aktualisierung der Zielverzweigung (wie durch die Referenz angegeben) zum Quellfestschreiben, wie vonangegebenTeil.

+2

außer wenn es einen Acl auf dem Zweig gibt - was normalerweise der Fall ist, wenn Sie "es auf dem bloßen Repo selbst tun müssen" ... –