web-dev-qa-db-fra.com

Comment puis-je fusionner plusieurs commits, mais en laisser un de côté?

Supposons que j'ai cette branche de fonctionnalité "foo". Maintenant, je veux le fusionner à nouveau dans master, mais j'ai ajouté du code de débogage que je ne veux pas dans master.

Le code de débogage est dans son propre commit, donc je pourrais utiliser git cherry-pick à chaque validation et omettez cette validation. Mais ça va être assez fatigant.

Y a-t-il un "choix inversé" qui fait cela, ou une fusion interactive?

74
Dave Vogt

Utilisez un rebase interactif:

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

Cela ouvrira quelque chose comme ça dans votre $ 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.
    #

Donc, ce que vous faites est simplement de supprimer la ligne contenant la validation de débogage, d'écrire le fichier et de fermer votre éditeur, et git vous dira quelque chose comme:

Successfully rebased and updated refs/heads/master.

Maintenant, vous pouvez simplement fusionner dans cette branche pour maîtriser.

MISE À JOUR: Il convient de noter que la modification de l'historique avec rebase devrait niquement se produire sur les branches privées. Si cette branche a été exposée au public, utilisez git revert tel que proposé par un autre répondeur.

53
Harry Vangberg

Malgré ce que les autres SCM utilisent pour signifier, dans git, git revert est un choix inversé.

68
CB Bailey

Une autre idée est d'ajouter la validation inversée de celle avec le code de débogage et de la fusionner dans votre branche principale. Ensuite, nous supprimons ce commit supplémentaire dans la branche foo.

git checkout foo
git revert COMMIT_REF_WITH_DEBUG_CODE

git checkout master
git merge foo

git checkout foo
git reset --hard HEAD~1

Assurez-vous que votre arbre de travail est propre. Créez d'abord le commit annulé. Puis fusionnez-le dans master. Réinitialisez ensuite le pointeur de branche de la branche foo sur le parent de la validation annulée, il est donc de retour dans son état d'origine.

Si vous n'aimez pas utiliser git reset vous pouvez alors créer une branche temporaire où vous créez le commit annulé. À la fin, vous supprimez la branche temporaire.

7
Paul Pladijs

Utilisez le rebase interactif pour supprimer les validations dont vous ne voulez pas.

Sur une nouvelle branche "foo-merge" créée à partir de "foo":

git rebase -i master

Une fois que vous êtes en mode d'édition de validation, supprimez les lignes contenant les validations de débogage, enregistrez et quittez de l'éditeur.

Après le rebasage, tirez simplement foo-merge dans master:

git checkout master
git pull . foo-merge
2
Yang Zhao

J'ai eu du succès avec:

git rebase -p --onto SHA^ SHA

SHA est le commit que vous souhaitez supprimer.

via http://sethrobertson.github.io/GitFixUm/fixup.html#remove_deep

0
michaeljoseph