2009-09-04 15 views
171

Ich hatte ein Repository, das einige schlechte commits hatte (D, E und F für dieses Beispiel).Git reset --hard und ein Remote-Repository

A-B-C-D-E-F-Master und origin/master

I das lokale Repository spezifisch mit einem git reset --hard geändert haben. Ich nahm einen Zweig vor dem Reset so jetzt habe ich ein Repo, die wie folgt aussieht: Ich

A-B-C master 
    \ D-E-F old_master 

A-B-C-D-E-F origin/master 

nun einige Teile dieser schlechten Commits benötigt, damit ich Kirsche die Bits nahm ich brauchte und machte einige neue verpflichtet, so jetzt habe ich die folgenden lokal:

Jetzt möchte ich diesen Stand der Dinge auf die Remote-Repo schieben. Aber wenn ich versuche, ein git push Git gibt mir höflich den Pinsel zu tun off:

$ git push origin +master:master --force 
Total 0 (delta 0), reused 0 (delta 0) 
error: denying non-fast forward refs/heads/master (you should pull first) 
To [email protected]:myrepo.git 
! [remote rejected] master -> master (non-fast forward) 
error: failed to push some refs to '[email protected]:myrepo.git' 

Wie kann ich die Remote-Repo erhalte den aktuellen Status des lokalen Repo zu nehmen?

+2

Das ist ein "fast" Duplikat von mehreren "wie pushe ich geändert Geschichte Fragen, z. siehe die Antwort hier http://stackoverflow.com/questions/253055/how-doi-i-push-amended-commit-to-the-remote-git-repo/255080#255080 –

+2

Das stimmt und ich hatte StackOverflow gesucht eine Antwort vor dem Posten. Meine Suche hatte jedoch nur Antworten ergeben, in denen ein Git - Pushforce das Problem behoben hat. Danke für die Verlinkung zu deinem Beitrag :) – robertpostill

+1

Du wirst bald (git1.8.5, Q4 2013) in der Lage sein, [git push -force' genauer zu machen] (http://stackoverflow.com/a/18505634/6309) . – VonC

Antwort

251

einen Push Wenn zwingt hilft nicht („git push --force origin‚oder‘git push --force origin master“ sollte genug sein), könnte es bedeuten, dass der Remote-Server nicht vorspulen weigert sich entweder schiebt über receive.denyNonFastForwards Konfigurationsvariable (siehe git config manpage für die Beschreibung) oder über update/pre-receive hook.

Mit älteren Git können Sie diese Einschränkung umgehen, indem Sie "git push origin :master" löschen (siehe ':' vor dem Zweigname) und dann "git push origin master" gegebenen Zweig neu erstellen.

Wenn Sie dies nicht ändern können, dann wäre die einzige Lösung sein, statt Geschichte zu Umschreiben einer reverting Änderungen in DEF erstellen begehen:

 
A-B-C-D-E-F-[(D-E-F)^-1] master 

A-B-C-D-E-F        origin/master 
+2

@ JakubNarębski, danke. 'erhalten zurück HEAD ~ N' geholfen. 'N' ist die Anzahl der Commits. Wenn ich zum Beispiel das vorherige Commit benötige, benutze ich 'git revert HEAD ~ 1' –

+4

Ich kann bestätigen, dass' '' git push --force origin master''' funktioniert und mir viele Kopfschmerzen erspart. – FearlessFuture

23

Um Jakub Antwort zu ergänzen, wenn Sie Zugang zu der Remote-Server git in ssh, können Sie die git Remote-Verzeichnis gehen und setzen:

[email protected]$ git config receive.denyNonFastforwards false 

Dann versuchen Sie es erneut zu Ihrem lokalen Repo gehen mit --force zu tun, um Ihre zu begehen:

[email protected]$ git push origin +master:master --force 

und schließlich die Einstellung des Servers wiederherstellen im ursprünglichen geschützten Zustand:

[email protected]$ git config receive.denyNonFastforwards true 
+0

Siehe auch http://pete.akeo.ie/2011/02/denying-non-fastforward-and.html für Sourceforge zugeschnittene Informationen dazu. – hlovdal

+0

Detaillierte Anweisungen zum Deaktivieren von denyNonFastForwards mit 'vi' finden Sie in diesem SO-Post: stackoverflow.com/a/43721579/2073804 – ron190

1

Stattdessen Ihren „Master“ Zweig der Festsetzung, es ist viel einfacher, es zu tauschen mit dem „richtigen-Master“ durch Umbenennung die Äste. Siehe https://stackoverflow.com/a/2862606/2321594. Auf diese Weise würden Sie nicht einmal Spuren von mehreren Wiederherstellungsprotokollen hinterlassen.

0

Das ganze git-Reset-Geschäft sah für mich viel komplizierter aus.

Also tat ich etwas entlang der Linien zu meinen src-Ordner in dem Zustand zu erhalten hatte ich ein paar Commits vor

# reset the local state 
git reset <somecommit> --hard 
# copy the relevant part e.g. src (exclude is only needed if you specify .) 
tar cvfz /tmp/current.tgz --exclude .git src 
# get the current state of git 
git pull 
# remove what you don't like anymore 
rm -rf src 
# restore from the tar file 
tar xvfz /tmp/current.tgz 
# commit everything back to git 
git commit -a 
# now you can properly push 
git push 

diese Weise wird der Stand der Dinge in der src in einer TAR-Datei und git gehalten wird, gezwungen, diesen zustand zu akzeptieren, ohne zu viel hantieren zu müssen, wird das src-verzeichnis grundsätzlich durch den zustand ersetzt, in dem es vor einigen commits stattgefunden hat.

Verwandte Themen