2009-10-26 11 views
74

Angenommen, ich habe diese Funktion Zweig "foo". Jetzt möchte ich es wieder in Master zusammenführen, aber ich habe einige Debugging-Code hinzugefügt, die ich nicht in Master wollen.Wie kann ich viele Commits verschmelzen, aber eins auslassen?

Der Debug-Code ist in seinem eigenen Commit, so dass ich git cherry-pick bei jedem Commit verwenden und dieses Commit weglassen konnte. Aber das wird ziemlich ermüdend sein.

Gibt es einige "inverse cherry-pick", die dies tun, oder eine interaktive Zusammenführung?

Antwort

54

Nutzung interaktives Fütterungsmaterial:

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

dass so etwas wie dies in Ihrem $ EDITOR öffnet:

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. 
    # 

Also, was Sie tun, ist einfach die Zeile zu entfernen, enthält die Debug begeht, schreiben die Datei und schließen Sie Ihren Editor, und Git wird Ihnen etwas sagen in Richtung:

Successfully rebased and updated refs/heads/master. 

Jetzt yo Sie können einfach in diesem Zweig zum Master zusammenführen.

UPDATE: Es sollte beachtet werden, dass die Änderung der Geschichte mit rebasenur auf privaten Zweigen passieren sollte. Wenn diese Zweigstelle der Öffentlichkeit zugänglich gemacht wurde, verwenden Sie git revert wie von anderen Beantwortern vorgeschlagen.

+0

Nizza .. und ist es eine gute Möglichkeit, die SHA-OF-FIRST-COMMIT-IN-BRANCH zu bekommen? –

+0

@DaveVogt ja! Siehe http://stackoverflow.com/questions/1527234/finding-a-branch-point-with-git – boycy

67

Trotz was andere SCMs es zu verwenden, in git, git revert ist eine inverse Kirsche-Pick.

+9

'git revert' zeichnet ein neues Commit mit den entsprechenden Änderungen auf. –

+11

@mikem: was ist, denke ich, was ein inverser Cherry-Pick intuitiv bedeutet. Sowohl "revert" als auch "cherry-pick" haben auch eine "-n" -Option, die kein Commit durchführt, sondern die Änderungen im Cache/Index/Staging-Bereich belässt, so dass die Befehle sehr ähnlich sind. –

+0

kurz und bündig - ermutigt Sie, es zu versuchen und denkt, es gibt keine Möglichkeit, dass es so einfach sein kann! Ich werde es ihm zeigen! "... und dann ist es so einfach. es scheint sogar für code zu funktionieren, dass ich mit dem cherry-picking begonnen habe, aber dann normal normal gemacht habe (oops?), was sinn macht, da git ja nur diffs zwischen snapshots und nicht abhängigen ereignissen ist. Ich weiß nicht. Ich lerne immer wieder über solche Features und erwarte, dass es einen Haken gibt, aber sie scheinen jedes Mal zu funktionieren! –

2

Verwenden Sie interaktives Rebase, um die Commits zu entfernen, die Sie nicht möchten.

Auf einem neuen Zweig „foo-merge“ erstellt von „foo“:

git rebase -i master 

Sobald Sie im Modus bearbeiten begehen werden, entfernen Sie die Zeilen enthalten, die Debug verpflichtet, speichern und aus dem Editor beenden.

Nach Rebasieren, einfach ziehen foo-verschmelzen zu Master:

git checkout master 
git pull . foo-merge 
+0

Viel wiederholen? –

+1

Ein wenig schwierig, über Kommentare zu schreiben, wenn Sie nicht dürfen. FWIW, ich habe deine Antwort abgegeben, bevor du entschieden hast, dass meine anders sein würde, um ein separater Eintrag zu sein, dann füge ich sie ein. –

7

Eine weitere Idee begeht die zurück hinzuzufügen, ist der ein mit Debug-Code und es in Ihren Master-Zweig zu verschmelzen. Danach entfernen wir diesen zusätzlichen 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 umgekehrte Commit. Dann füge es in den Master ein. Setzen Sie danach den Verzweigungszeiger des foo-Zweiges auf das Elternelement des zurückgesetzten Commits zurück, so dass es wieder in seinem ursprünglichen Zustand ist.

Wenn Sie die Verwendung von git reset nicht mögen, können Sie eine temporäre Verzweigung erstellen, in der Sie die umgekehrte Festschreibung erstellen. Am Ende löschen Sie den temporären Zweig.

Verwandte Themen