Ecraser une branche par une autre avec Git


Mise en scène
L’ historique de commits ci-dessous illustre les explications qui suivront :

Cet historique des commits commence par la branche master sur laquelle les fonctionnalités A et B ont été commitées. La branche maBranche est alors créée à partir du commit de la fonctionnalité B. Un premier merge no fast-forward est créé pour récupérer la fonctionnalité E de master dans maBranche : le commit de merge « Merge branch ‘master’ into maBranche » est créé.
A partir de là, les nouvelles fonctionnalités F, G et H sont développées sur maBranche. Ne pouvant attendre la fin des développements de la fonctionnalité G qui résoudrait proprement le problème rencontré par les utilisateurs, est créé sur le master un contournement permettant d’y palier temporairement. Ce Hotfix est déployé en production. N’ayant aucun intérêt dans les prochaines versions de l’application, ce Hotfix ne doit être en aucun cas mergé sur maBranche. Une fois les développements de la fonctionnalité H terminés et déployés en production, l’équipe décide de faire revenir sur le master les développements de maBranche. Les 2 derniers commits de l’historique mettent en œuvre cette opération.
Commandes
Voici les 4 lignes de commandes à exécuter pour réaliser cet écrasement de branche :
- Se placer sur la branche à conserver git checkout maBranche
- Demander une fusion avec la stratégie ours (attention, ceci est différent d’un merge avec stratégie recursive et l’ option ours) qui va uniquement conserver le contenu de la branche actuelle. En effet, l’option -s ours indique à Git de fusionner la branche source dans la branche cible mais sans aucunement modifier la branche cible. Cette stratégie est habituellement utilisée pour ne pas reporter un commit d’une branche de maintenance sur le master. git merge -s ours master -m “Merge avec stratégie ours”
- Repasser sur la branche master git checkout master
- Demander une fusion de la branche maBranche vers le master tout en conservant 2 branches distinctes (un fast-forward aurait été réalisé puisque que le dernier commit n’est autre que notre fusion de la commande n°2). git merge –no-ff maBranche
Sortie console sur notre exemple de la commande Git n°4 :

Comme attendu, le fichier Hotfix.txt ayant été ajouté lors du commit Hotfix est supprimé du master. Si, dans un autre exemple, le commit Hotfix avait modifié une ligne du fichier FeatureE.txt, un revert de cette modification aurait alors été effectué.
Conclusion
Cet article explique comment Git permet d’écraser le contenu de la branche A par une branche B lorsque la branche B a pris le pas sur la branche A et qu’aucune des modifications présente dans le branche A n’a besoin d’être conservée (tout a été préalablement fusionné, reporté par cherry-pick, copié à la main ou volontairement ignoré car à ne pas reporter). Cerise sur le gâteau : ces opérations sont applicables entre 2 branches SVN par le biais du bridge git-svn.
