Entfernen Sie bestimmte Commits
Ich arbeitete mit einem Freund an einem Projekt, und er bearbeitete eine Reihe von Dateien, die nicht bearbeitet wurden. Irgendwie habe ich zusammengeführt, die seine arbeiten in mir, wenn ich zog es auf, oder wenn ich versuchte, wählen Sie einfach die Dateien aus, die ich wollte. Ich habe auf der Suche und spielen für eine lange Zeit, um herauszufinden, wie Sie entfernen die commits enthalten, die änderungen an diesen Dateien, es scheint ein toss up zwischen revert und Stellungswechsel, und es gibt keine einfache Beispiele, und die docs nehme an, ich weiß mehr als ich.
So, hier ist eine vereinfachte version der Frage:
Gegeben Sie das folgende Szenario, wie Entferne ich den commit-2?
$ mkdir git_revert_test && cd git_revert_test
$ git init
Initialized empty Git repository in /Users/josh/deleteme/git_revert_test/.git/
$ echo "line 1" > myfile
$ git add -A
$ git commit -m "commit 1"
[master (root-commit) 8230fa3] commit 1
1 files changed, 1 insertions(+), 0 deletions(-)
create mode 100644 myfile
$ echo "line 2" >> myfile
$ git commit -am "commit 2"
[master 342f9bb] commit 2
1 files changed, 1 insertions(+), 0 deletions(-)
$ echo "line 3" >> myfile
$ git commit -am "commit 3"
[master 1bcb872] commit 3
1 files changed, 1 insertions(+), 0 deletions(-)
Das erwartete Ergebnis ist
$ cat myfile
line 1
line 3
Hier ist ein Beispiel, wie ich versucht haben, um zurückzukehren,
$ git revert 342f9bb
Automatic revert failed. After resolving the conflicts,
mark the corrected paths with 'git add <paths>' or 'git rm <paths>'
and commit the result.
InformationsquelleAutor der Frage Joshua Cheek | 2010-05-30
Du musst angemeldet sein, um einen Kommentar abzugeben.
Algorithmus, den Git verwendet, wenn die Berechnung der diff ist, um zurückgesetzt werden, erfordert, dass
Die definition von "benachbarten" basiert auf der Standard-Anzahl der Zeilen von einem context-diff, das ist 3. Also, wenn 'myfile' wurde konstruiert wie dieser:
Dann alles wie erwartet funktioniert.
Die zweite Antwort, war sehr interessant. Es ist ein feature, welches bisher noch nicht offiziell freigegeben (obwohl es ist in Git v1.7.2-rc2) genannt Revert-Strategie. Sie rufen git wie diese:
werden und es sollte einen besseren job machen, herauszufinden, was Sie bedeutete. Ich weiß nicht, was die Liste der verfügbaren Strategien ist, noch kenne ich die definition von Strategie.
InformationsquelleAutor der Antwort Hal Eisen
Gibt es vier Möglichkeiten, dies zu tun:
Saubere Art und Weise, zurücksetzen, aber halten Sie im Protokoll den revert:
Harte Weise, entfernen Sie insgesamt nur den letzten commit:
Hinweis: Vermeiden Sie
git reset --hard
wie es auch verwerfen Sie alle änderungen an den Dateien seit der letzten übertragung. Wenn--soft
funktioniert nicht, sondern versuchen--mixed
oder--keep
.Stellungswechsel (zeigen Sie das log der letzten 5 commits und löschen Sie die Zeilen, die Sie nicht wollen, oder neu ordnen oder squash mehrere commits in einem, oder irgendetwas anderes tun, die Sie wollen, dies ist ein sehr vielseitiges Werkzeug):
Und wenn ein Fehler gemacht:
Schnelle Stellungswechsel: entfernen Sie nur einen bestimmten commit mittels seiner id:
Alternativen: Sie könnten auch versuchen:
Noch eine weitere alternative:
Als letzten Ausweg, wenn Sie die volle Freiheit der Geschichte der Bearbeitung (zB, weil git nicht erlauben, Sie zu Bearbeiten, was Sie wollen), können Sie diese sehr schnell open-source-Anwendung: reposurgeon.
Hinweis: natürlich können alle diese änderungen werden vor Ort durchgeführt, sollten Sie
git push
danach gelten die änderungen der Fernbedienung. Und falls Ihr repo nicht möchten, entfernen Sie die commit ("keine schnell-vorwärts erlaubt", was passiert, wenn Sie entfernen möchten, Begehen Sie bereits abgelegt), können Siegit push -f
zu zwingen, schieben Sie die änderungen.Hinweis 2: wenn arbeiten auf einem Zweig und müssen Sie zu zwingen, push, sollten Sie absolut vermeiden
git push --force
da diese eventuell überschrieben werden andere Zweige (wenn Sie getan haben, Veränderungen in Ihnen, auch wenn Ihre aktuelle Kasse ist auf einem anderen Zweig). Lieber immer angeben der remote-Zweigstelle, wenn Sie Kraft schieben:git push --force origin your_branch
.InformationsquelleAutor der Antwort gaborous
Ihre Wahl zwischen
Sollten Sie (1) wenn die fehlerhafte änderung wurde abgeholt von jemand anderes und (2) wenn der Fehler beschränkt sich auf ein eigenes un-Zweig geschoben.
Git revert ist ein automatisiertes tool, das zu tun (1), es erstellt einen neuen commit rückgängig machen einige der vorherigen commit. Sehen Sie den Fehler ein-und ausbau der Projekt-Geschichte, sondern Menschen, die ziehen aus Ihrem repository nicht auf Probleme stoßen, wenn Sie aktualisieren. Es funktioniert nicht in einer automatisierten Art und Weise in Ihrem Beispiel, so dass Sie Bearbeiten müssen 'myfile' (entfernen Zeile 2), tun
git add myfile
undgit commit
um mit dem Konflikt umzugehen. Sie wird dann am Ende mit vier commits in Ihrer Geschichte, die mit commit 4 zurücksetzen Begehen, 2.Wenn niemand kümmert sich, dass Sie Ihre Geschichte ändert sich, schreiben Sie es, und entfernen Sie commit 2 (Wahl 2). Der einfache Weg, dies zu tun ist die Verwendung
git rebase -i 8230fa3
. Dies bringt Sie in einen editor, und Sie können wählen, nicht an das fehlerhafte commit durch entfernen der commit (und halten Sie "wählen" neben dem anderen commit-Nachrichten. Lesen Sie auf der Folgen, dies zu tun.InformationsquelleAutor der Antwort Andrew Walker
Sehr Einfache Möglichkeit
git rebase -i HEAD~x
(x= no. von commits)
beim ausführen notepad Datei öffnen 'setzen' drop neben Ihrem commit
und das ist es Ihre getan...
synchronisieren Sie die git-Konsole und die änderungen werden geschoben, um auf der Fernbedienung. Wenn die commit drop war schon auf der Fernbedienung, Sie zu zwingen das update. Da --force als schädlich, verwenden Sie
git push --force-with-lease
.InformationsquelleAutor der Antwort JD-V
Können Sie entfernen Sie unerwünschte begeht mit
git rebase
.Sagen Sie, dass Sie enthalten einige commits von einem Kollegen das Thema Niederlassung in Ihrem topic branch, aber später entscheiden, Sie wollen nicht diejenigen verpflichtet.
Zu diesem Zeitpunkt Ihren text-editor öffnen Sie den interaktiven rebase view. Zum Beispiel
Wenn der Stellungswechsel war nicht erfolgreich, löschen Sie die temporären Zweig und versuchen eine andere Strategie. Anderenfalls fahren Sie mit den folgenden Anweisungen.
Wenn Sie schieben Sie Ihr Thema-Zweig zu einem remote ist, müssen Sie möglicherweise zu zwingen, push, da die commit-Geschichte hat sich geändert. Wenn andere arbeiten auf der gleichen Branche, geben Ihnen ein heads-up.
InformationsquelleAutor der Antwort Dennis
Aus anderen Antworten hier, ich war irgendwie verwirrt, wie
git rebase -i
verwendet werden könnten, zu entfernen, zu Begehen, so hoffe ich, es ist OK, sich zu notieren, meinem test-Fall hier (ähnlich der OP).Hier ist ein
bash
- Skript, das Sie einfügen können, erstellen Sie ein test-repository in der/tmp
Ordner:An dieser Stelle haben wir eine
file.txt
mit diesen Inhalten:An dieser Stelle, der KOPF ist auf der 5. commit, HEAD~1 wäre der 4. - und HEAD~4 wäre der 1. commit (also HEAD~5 nicht existieren würde). Sagen wir, wir möchten, entfernen Sie die 3. commit - wir herausgeben können Sie diesen Befehl in der
myrepo_git
Verzeichnis:(Beachten Sie, dass
git rebase -i HEAD~5
Ergebnisse mit "fatal: man Benötigt eine einzelne revision; invalid upstream HEAD~5".) Ein text-editor (siehe screenshot in @Dennis' Antwort) wird mit diesen Inhalten:So bekommen wir alle verpflichtet seit (aber nicht darunter) unsere gewünschte KOPF~4. Löschen Sie die Zeile
pick 448c212 3rd git commit
und speichern Sie die Datei; Sie erhalten diese Antwort vongit rebase
:Zu diesem Zeitpunkt öffnen myrepo_git/
folder/file.txt
in einem text-editor; du wirst sehen, es wurde geändert:Grundsätzlich
git
sieht, wenn der KOPF bekam nach 2. zu Begehen, da wurde Inhaltaaaa
+bbbb
; und dann hat es einen patch Hinzugefügtcccc
+dddd
die es nicht wissen, wie das Anhängen an den bestehenden Inhalt.So, hier
git
nicht für Sie entscheiden können - es ist Sie wer hat, eine Entscheidung zu treffen: durch das entfernen der 3. Begehen, Sie entweder halten Sie die änderungen (hier die Zeilecccc
) -- oder nicht. Wenn Sie nicht, entfernen Sie einfach die zusätzlichen Zeilen - einschließlich dercccc
- infolder/file.txt
mit einem text-editor, so sieht es wie folgt aus:... und dann speichern
folder/file.txt
. Jetzt können Sie die folgenden Befehle inmyrepo_git
Verzeichnis:Ah - so, um zu markieren, dass wir das gelöst haben, den Konflikt, wir muss
git add
diefolder/file.txt
vorhergit rebase --continue
:Hier ein text-editor wird erneut geöffnet, zeigt die Linie
4th git commit
- hier haben wir eine chance, zu ändern der commit-Nachricht (die könnte in diesem Fall sinnvoll geändert4th (and removed 3rd) commit
oder ähnliches). Lassen Sie uns sagen, Sie wollen nicht - so einfach beenden Sie den Texteditor ohne speichern; sobald Sie dies tun, erhalten Sie:In diesem Punkt, jetzt haben Sie eine Geschichte wie diese (die Sie könnte auch überprüfen Sie mit sagen
gitk .
oder andere Werkzeuge) der Inhaltfolder/file.txt
(mit, scheinbar, unverändert Zeitstempel des ursprünglichen commits):Und wenn zuvor haben wir beschlossen, die Linie zu halten
cccc
(der Inhalt des 3. git commit, die wir entfernt), so hätten wir:Gut, dies war die Art von Lesen, die ich hoffte, ich würde gefunden haben, starten grokking wie
git rebase
funktioniert das löschen von commits/Revisionen; so hoffen Sie, dass es helfen könnte, andere zu...InformationsquelleAutor der Antwort sdaau
So dass es klingt wie die schlecht zu Begehen war eingebunden in einen merge-commit zu einem gewissen Punkt. Hat Ihr merge-commit gezogen worden noch? Wenn ja, dann werden Sie wollen, um zu verwenden
git revert
; Sie müssen die Zähne zusammenbeißen und die Arbeit durch Konflikte. Wenn Nein, dann könnte man unter Umständen entweder Stellungswechsel machen oder wiederherstellen, aber Sie können dies tun vor den merge-commit, dann wiederholen Sie den merge.Es gibt nicht viel helfen können wir Ihnen für den ersten Fall, wirklich. Nach dem Versuch, die zurückkehren, und fand, dass die automatische gescheitert, Sie haben zu prüfen, die Konflikte und fixieren Sie entsprechend. Das ist genau der gleiche Vorgang wie die Festsetzung von Konflikten beim Zusammenführen; Sie können
git status
zu sehen, wo die Konflikte sind, Bearbeiten die individuellen Dateien, finden die Konflikte hunks, herauszufinden, wie Sie zu beheben, fügen Sie die Konflikt-Dateien, und schließlich Begehen. Wenn Siegit commit
durch sich selbst (ohne-m <message>
), die Nachricht, das erscheint in Ihrem editor sollte die Vorlage Nachricht erstellt vongit revert
; können Sie eine Notiz darüber, wie Sie behoben die Konflikte, dann speichern und beenden, zu Begehen.Für den zweiten Fall, die Lösung des Problems vor zusammenzuführen, gibt es zwei subcases, je nachdem, ob Sie mehr arbeiten seit dem merge. Wenn Sie nicht, können Sie einfach
git reset --hard HEAD^
zu knock off-der Seriendruck, gehen Sie zurück, dann wiederholen Sie den Seriendruck. Aber ich vermute, Sie haben. So werden Sie am Ende dabei so etwas wie dieses:git rebase -i <something before the bad commit> <temporary branch>
zu entfernen, das bad zu Begehen)git rebase --onto <temporary branch> <old merge commit> <real branch>
InformationsquelleAutor der Antwort Cascabel
Folgen Sie bitte unten squesnce von Aktionen, Da sind wir mit --force Sie brauchen, um admin-Rechte über das git-repo zu tun.
Schritt 1: Finden Sie den commit vor dem commit Sie entfernen möchten
git log
Schritt 2: Checkout, commit
git checkout <commit hash>
Schritt 3: Machen eine neue Filiale mit Ihrem aktuellen checkout-commit -
git checkout -b <new branch>
Schritt 4: Nun müssen Sie hinzufügen der commit nach dem entfernt verpflichten
git cherry-pick <commit hash>
Schritt 5: Jetzt wiederholen Sie Schritt 4 für alle anderen verpflichtet, die Sie behalten möchten.
Schritt 6: Einmal alle verpflichtet wurden Hinzugefügt, um Ihre neue Filiale-und wurde engagiert. Überprüfen Sie, dass alles im richtigen Zustand und arbeitet wie vorgesehen. Überprüfen alles wurde begangen:
git status
Schritt 7: Wechseln Sie zu Ihrem gebrochenen Zweig
git checkout <broken branch>
Schritt 8: Jetzt führen Sie einen hard-reset auf dem gebrochenen Zweig auf den commit vor die eine, die Ihre entfernen möchten
git reset --hard <commit hash>
Schritt 9: verbinden Sie Ihre Feste Niederlassung in diesem Zweig
git merge <branch name>
Schritt 10: Drücken Sie die zusammengeführten änderungen wieder zurück zum Ursprung. WARNUNG: Dieser Befehl überschreibt die remote-repo!
git push --force origin <branch name>
Können Sie den Vorgang ohne anlegen einer neuen Niederlassung durch ersetzen von Schritt 2 & 3 mit Schritt 8 dann nicht durchführen Schritt 7 & 9.
InformationsquelleAutor der Antwort tkr
Sodass Sie gearbeitet hatte, und drückte ihn, nennen wir Sie begeht, A und B. Ihre Mitarbeiter haben einige Arbeit als gut, begeht, C Und D. Sie zusammengeführt, Ihre Mitarbeiter arbeiten in dir (merge-commit E), dann weiter arbeiten, verpflichtet, auch (commit-F), und entdeckt, dass Ihre Mitarbeiter änderte einige Dinge, die er nicht haben sollte.
Also deine commit Historie sieht wie folgt aus:
Sie wirklich wollen, um loszuwerden, C, D und D'. Da Sie sagen, Sie zusammengeführt, Ihre Mitarbeiter arbeiten in dir, der diese begeht, ist bereits "draußen", also das entfernen der begeht mit z.B. git rebase ist ein no-no. Glauben Sie mir, ich habe versucht.
Nun, ich sehe zwei Möglichkeiten aus:
wenn Sie noch nicht geschoben, E und F bis Ihr Kollege oder jemand anderes (in der Regel Ihr "origin" - server) und doch, konnte Sie immer noch entfernen Sie diese aus der Geschichte für die Zeit. Dies ist Ihre Arbeit, die Sie speichern möchten. Diese kann getan werden, mit einem
(ersetzen Sie " D " mit dem aktuellen commit-hash, Sie kann erhalten von einem
git log
Zu diesem Zeitpunkt verpflichtet, die E und F verschwunden sind und die änderungen sind nicht festgeschriebene änderungen in Ihrem lokalen workspace wieder. An dieser Stelle möchte ich verschieben Sie Sie auf einen Zweig oder schalten Sie Sie in einen patch und speichern Sie Sie für später. Jetzt, wieder Ihre Mitarbeiter arbeiten, entweder automatisch mit einer
git revert
oder manuell. Wenn Sie das getan haben, wiederholen Ihre Arbeit auf. Sie müssen möglicherweise Zusammenführen Konflikte, aber zumindest werden Sie in den code Sie schrieb, statt Ihre Mitarbeiter den code.Wenn Sie bereits stieß die Arbeit, die Sie haben, nachdem Ihr Mitarbeiter ist verpflichtet, können Sie immer noch versuchen, einen "rückwärts-patch" entweder manuell oder über
git revert
, aber da Ihre Arbeit "im Weg", so zu sprechen, werden Sie wahrscheinlich bekommen, mehr merge-Konflikte und mehr verwirrend lieben. Sieht aus wie das ist, was Sie endete in...InformationsquelleAutor der Antwort Frans