Supprimer les commits d'une seule branche dans Git

J'ai deux branches, master et feature1. Je travaillais sur feature1 quand j'ai réalisé que je devais travailler sur quelque chose d'autre sans rapport. Malheureusement, j'ai oublié de brancher à partir du maître, et à la place créé ma branche feature2 à partir de feature1. Maintenant, je veux fusionner feature2 en maître, mais je ne peux pas car il y a des parties de feature1 dans cette branche.

Comment supprimer les commits feature1 de la branche feature2? Implique-t-il complet?

Je sens que si je pouvais changer le point de référence de départ de feature2 pour être où master est, cela pourrait aider, mais n'a aucune idée de comment.

Modifier:

Merci pour les réponses! J'ai essayé de rebaser selon la solution de @Mark, mais j'ai réalisé que l'histoire est plus compliquée que je ne le pensais initialement. la fonctionnalité 2 a été fusionnée dans d'autres branches de fonctionnalité, et master a été fusionné dans feature2 à un moment donné. Il y a aussi des commits supplémentaires sur master qui ne sont pas liés à feature2 tout est toujours local.

Vraiment, mon histoire ressemble plus à ceci:

A - B - C - D - - - - - - - - - - - - - L - M  master  
            |                          
            |               - I - J - K  feature2                  
                          /           
             - E - F - G - H - - - - - -N - O - P  feature1

Et ce que je veux, c'est ceci:

A - B - C - D - - - - - - - - - -  L - M  master
            |                          
            |  - - - - - I - J - K  feature2                  
                                 
              - E - F - G - H - - - N - O - P  feature1

J'ai aussi essayé:

git rebase --onto 1524b824cfce5856a49e feature1 feature2
// 1524b824cfce5856a49e == D

Mais cela définit simplement la fonction de nom de branche 2 pointant vers 1524, et laisse les commits I, J, K avec leurs parents d'origine.

27
demandé sur Andrew 2011-08-31 19:31:41

2 réponses

Si c'est seulement vous qui travaillez sur votre branche feature2 et que vous ne l'avez pas partagée avec d'autres personnes, il est bon de rebaser cette branche avant de la fusionner. Vous pouvez faire ce qui suit, par exemple:

git checkout feature2
git rebase --onto master feature1 feature2

... ce qui réécrira votre branche feature2, en la laissant de sorte qu'elle se compose de tous les commits dans feature2 puisqu'elle a été ramifiée à partir de feature1, mais réappliquée sur master. Je vous suggère d'utiliser gitk --all ou une visionneuse d'historique git similaire par la suite pour vérifier que le résultat de cette opération est ce que vous vouloir.

Par ailleurs, c'est exactement le scénario utilisé pour expliquer --onto dans le git rebase documentation - voir le paragraphe commençant par:

Voici comment vous transplanter une branche de sujet basée sur une branche à une autre, pour prétendre que vous avez bifurqué la branche de sujet de cette dernière branche, en utilisant rebase -- on. [...]


mis à Jour en réponse à plus de matériel dans la question suivante:

En commençant par votre historique, qui on dirait ceci:

A - B - C - D - - - - - - - - - - - - - L - M  master  
            |                          
            |               - I - J - K  feature2                  
            \              /           \
             - E - F - G - H - - - - - -N - O - P  feature1

Vous pouvez obtenir ce que vous voulez en faisant ce qui suit:

git checkout feature2
git rebase --onto D H feature2

Cela vous laissera avec l'histoire qui ressemble à:

A - B - C - D - - - - - - - - - - - - - - - - - - - L - M  master  
            |\
            | \ - I' J' K' feature2       I - J - K                    
            \                           /           \
             - - - - - - - E - F - G - H - - - - - -N - O - P  feature1

Avant de créer la fusion que vous voulez dans feature1, vous devez noter le SHA1sum de O et P. (Je suppose que N est juste une fusion normale, et non une "fusion maléfique".)

Ensuite, faites une réinitialisation matérielle pour déplacer feature1 vers H:

git checkout feature1
git rest --hard H

, Alors vous devriez avoir le histoire:

A - B - C - D - - - - - - - - - - - - - - - - - - - L - M  master  
            |\
            | \ - I' J' K' feature2
            \
             - - - - - - - E - F - G - H feature1

Maintenant, vous apparemment souhaitez fusionner K' dans feature1:

git merge K'

A - B - C - D - - - - - - - - - - - - - - - - - - - L - M  master  
            |\
            | \ - I' - J' - - - - - - - K' feature2
            \                             \
             - - - - - - - E - F - G - H - Z feature1

Et enfin, vous pouvez piocher dans les vieux O et P sur feature1, avec:

git cherry-pick O
git cherry-pick P

... pour partir:

A - B - C - D - - - - - - - - - - - - - - - - - - - L - M  master  
            |\
            | \ - I' - J' - - - - - - - K' feature2
            \                            \
             - - - - - - - E - F - G - H - Z - - O' - P' feature1
29
répondu Mark Longair 2011-08-31 18:02:03

Si cela ne vous dérange pas que feature2 soit fusionné sur P au lieu de M, Voici une solution relativement simple.

  1. Rebase I-J-K sur D, regardez le titre de la section " rebases plus intéressants
  2. Rebase O-P sur H. de la même manière que dans l'étape 1
  3. Finalement fusionner feature2 dans feature1 avec git merge feature2 tout en ayant feature1 vérifié.

Si vous voulez K fusionné dans un commits particulier, le rebasage devient un peu plus délicat.

2
répondu Andy 2011-08-31 17:47:46