Wie kann ich viele Commits zusammenführen, aber eines weglassen?

74

Angenommen, ich habe diesen Feature-Zweig "foo". Jetzt möchte ich es wieder in Master zusammenführen, aber ich habe Debugging-Code hinzugefügt, den ich in Master nicht möchte.

Der Debug-Code befindet sich in einem eigenen Commit, sodass ich ihn git cherry-pickbei jedem Commit verwenden und dieses Commit weglassen kann. Aber das wird ziemlich lästig.

Gibt es einen "inversen Kirschbaum", der dies tut, oder eine interaktive Zusammenführung?

Dave Vogt
quelle

Antworten:

53

Verwenden Sie interaktive Rebase:

git rebase -i SHA-OF-FIRST-COMMIT-IN-BRANCH

Das öffnet so etwas in Ihrem $ EDITOR:

    pick 8ac4783 folders and folders
    pick cf8b1f5 minor refactor
    pick 762b37a Lots of improvement. Folders adn shit.
    pick 3fae6e1 Be ready to tableview
    pick b174dc0 replace folder collection view w/ table view
    pick ef1b65b more finish
    pick ecc407f responder chain and whatnot
    pick 080a847 play/pause video
    pick 6719000 wip: movie fader
    pick c5f2933 presentation window fade transition

    # Rebase e6f77c8..c5f2933 onto e6f77c8
    #
    # Commands:
    #  p, pick = use commit
    #  e, edit = use commit, but stop for amending
    #  s, squash = use commit, but meld into previous commit
    #
    # If you remove a line here THAT COMMIT WILL BE LOST.
    # However, if you remove everything, the rebase will be aborted.
    #

Sie entfernen also einfach die Zeile mit dem Debug-Commit, schreiben die Datei und schließen den Editor. Git sagt Ihnen Folgendes:

Successfully rebased and updated refs/heads/master.

Jetzt können Sie diesen Zweig einfach zum Master zusammenführen.

UPDATE: Es soll beachtet werden , dass mit der Geschichte verändern rebasesollte nur auf private Filialen passieren. Wenn dieser Zweig der Öffentlichkeit zugänglich gemacht wurde, verwenden Sie ihn git revertwie von einem anderen Antwortenden vorgeschlagen.

Harry Vangberg
quelle
Schön ... und gibt es eine gute Möglichkeit, den SHA-OF-FIRST-COMMIT-IN-BRANCH zu bekommen?
Dave Vogt
@ DaveVogt ja! Siehe stackoverflow.com/questions/1527234/…
Boycy
68

Ungeachtet dessen, was andere SCMs damit meinen git, git reverthandelt es sich um eine inverse Kirschpickel .

CB Bailey
quelle
9
git revertzeichnet ein neues Commit auf, wobei die entsprechenden Änderungen entfernt wurden.
Mike Mazur
11
@mikem: das ist, denke ich, was ein inverser Kirschpflücker intuitiv bedeutet. Beide revertund cherry-pickhaben auch eine -nOption, die kein Commit ausführt, aber die Änderungen im Bereich Cache / Index / Staging belässt, sodass die Befehle sehr ähnlich sind.
CB Bailey
kurz und bündig - ermutigt Sie, es zu versuchen und zu denken: „So einfach kann es nicht sein! Ich werde es ihm zeigen! '... und dann ist es so einfach. Es scheint sogar für Code zu funktionieren, bei dem ich angefangen habe, Kirschen zu pflücken, aber dann einfach normal festgeschrieben habe (oops?), was gitmeiner Meinung nach Sinn macht, da es letztendlich nur um Unterschiede zwischen Schnappschüssen geht, nicht um abhängige Ereignisse. Ich weiß nicht. Ich lerne immer wieder über solche Funktionen und erwarte, dass es einen Haken gibt, aber sie scheinen jedes Mal einfach zu funktionieren!
underscore_d
7

Eine andere Idee ist, das rückgängig gemachte Commit desjenigen mit Debug-Code hinzuzufügen und es in Ihrem Hauptzweig zusammenzuführen. Danach entfernen wir dieses zusätzliche Commit im foo-Zweig.

git checkout foo
git revert COMMIT_REF_WITH_DEBUG_CODE

git checkout master
git merge foo

git checkout foo
git reset --hard HEAD~1

Stellen Sie sicher, dass Ihr Arbeitsbaum sauber ist. Erstellen Sie zuerst das zurückgesetzte Commit. Dann füge es in Master zusammen. Setzen Sie anschließend den Verzweigungszeiger des foo-Zweigs auf das übergeordnete Element des zurückgesetzten Commits zurück, damit er wieder in seinem ursprünglichen Zustand ist.

Wenn Sie die Verwendung nicht mögen, können git resetSie einen temporären Zweig erstellen, in dem Sie das zurückgesetzte Commit erstellen. Am Ende löschen Sie den temporären Zweig.

Paul Pladijs
quelle
2

Verwenden Sie die interaktive Basis, um die Commits zu entfernen, die Sie nicht möchten.

Auf einem neuen Zweig "foo-merge" erstellt aus "foo":

git rebase -i master

Wenn Sie sich im Commit-Bearbeitungsmodus befinden, entfernen Sie die Zeilen mit den Debug-Commits, speichern Sie sie und beenden Sie sie aus dem Editor.

Ziehen Sie nach dem erneuten Basieren einfach foo-merge in master:

git checkout master
git pull . foo-merge
Yang Zhao
quelle
1
Es ist etwas schwierig, über Kommentare einen Beitrag zu leisten, wenn Sie dies nicht dürfen. FWIW, ich habe Ihre Antwort abgestimmt, bevor ich entschieden habe, dass meine Antwort so unterschiedlich ist, dass sie ein separater Eintrag ist, und sie dann eingereicht habe.
Yang Zhao