1779 votes

Comment puis-je fusionner plusieurs commits sur une autre branche en un seul commit écrasé ?

J'ai un serveur Git distant, voici le scénario que je veux réaliser :

  • Pour chaque bogue/caractéristique, je crée une branche Git différente.

  • Je continue à commiter mon code dans cette branche Git avec des messages Git non officiels.

  • Dans le dépôt supérieur, nous devons faire un commit pour un bug avec le message officiel de Git.

Donc, comment puis-je fusionner ma branche avec la branche distante de sorte qu'ils obtiennent un seul commit pour tous mes check-ins (je veux même fournir un message de commit pour cela) ?

1 votes

Je ne suis pas sûr d'avoir bien compris, mais vous pourriez vouloir une "fusion pieuvre".

1 votes

Voulez-vous garder les commits individuels sur ces autres branches ?

36 votes

J'utilise généralement git rebase -i pour regrouper tous mes commits en un seul et réécrire le message de commit. Puis je l'envoie en amont.

2822voto

abyx Points 15304

Disons que votre branche de correction de bogues s'appelle bugfix et vous voulez le fusionner avec master :

git checkout master
git merge --squash bugfix
git commit

Cela prendra tous les commits du bugfix les regrouper en un seul commit, et le fusionner avec la branche master branche.


Explication :

git checkout master

Passez à votre master branche.

git merge --squash bugfix

Prend tous les commits du bugfix et la regroupe pour un commit 1 avec votre branche actuelle.
(aucun commit de fusion n'apparaît ; vous pouvez résoudre les conflits manuellement avant le commit suivant)

git commit

Crée un seul commit à partir des changements fusionnés.

En omettant le -m vous permet de modifier un brouillon de message de commit contenant tous les messages de vos commits écrasés avant de finaliser votre commit.

268 votes

Si vous voulez garder des références aux anciens messages de livraison, vous pouvez écrire git commit (sans -m param) et vous pourrez modifier un message de commit ébauché contenant tous les messages de commit que vous avez écrasés.

20 votes

Vous pouvez obtenir la même chose en faisant git commit --amend -m '...' plus tard.

2 votes

@abyx J'ai utilisé votre solution pour déplacer les corrections de bogues et les fonctionnalités de notre développement vers master en un seul commit, mais il semble que les commits revert ne sont pas inclus dans le merge squash. Je sélectionne les commits revert comme solution de contournement, mais il doit y avoir une meilleure solution pour ce cas particulier. Des idées ?

188voto

dankohn Points 6999

Ce qui a finalement clarifié la situation pour moi, c'est un commentaire montrant que :

git checkout main
git merge --squash feature

est l'équivalent de faire :

git checkout feature
git diff main > feature.patch
git checkout main
patch -p1 < feature.patch
git add .

Lorsque je veux fusionner une branche de fonctionnalité avec 105 ( !!) commits et les avoir tous écrasés en un seul, je ne veux pas git rebase -i origin/master parce que je dois résoudre séparément les conflits de fusion pour cada des commits intermédiaires (ou du moins ceux que git ne peut pas déterminer lui-même). Utilisation de git merge --squash me permet d'obtenir le résultat que je souhaite, à savoir un seul commit pour fusionner une branche entière de fonctionnalités. Et, je n'ai besoin de faire qu'une seule résolution manuelle de conflit.

101 votes

Je suggère fortement d'effectuer la fusion dans la branche des fonctionnalités en premier lieu. git merge master et seulement à ce moment-là git merge --squash feature dans la branche principale.

2 votes

Oui, une des choses qui est géniale à propos de la merge --squash est que vous pouvez continuellement fusionner origin/master dans votre branche et cela rend la fusion éventuelle plus facile.

13 votes

@dotancohen Désolé de déterrer un vieux commentaire :) Qu'est-ce que cela apporte de fusionner dans la branche des fonctionnalités avant d'effectuer les modifications ? git merge --squash feature à partir de la branche principale ?

135voto

Adam Dymitruk Points 34999

Vous voulez fusionner avec l'option de la courge. C'est si vous voulez le faire une branche à la fois.

git merge --squash feature1

Si vous voulez fusionner toutes les branches en même temps en tant que commits uniques, alors rebasez d'abord interactivement et écrasez chaque fonctionnalité puis fusionnez avec octopus :

git checkout feature1
git rebase -i master

Réduire en un seul commit puis répéter pour les autres fonctionnalités.

git checkout master
git merge feature1 feature2 feature3 ...

Cette dernière fusion est une "fusion pieuvre" car elle fusionne beaucoup de branches à la fois.

J'espère que cela vous aidera

3 votes

Pourquoi rebaser ?

13 votes

@UmairAshraf c'est un rebase interactif qui vous donne l'option de faire un squash dans votre branche.

4 votes

Le rebasement est une mauvaise idée. Ne pas rebaser les commits déjà publiés

39voto

user3838901 Points 11

Supposons que vous travailliez sur la fonctionnalité/tâche 1 avec plusieurs commits.

  1. Allez dans la branche de votre projet (projet/mon_projet)

     git checkout project/my_project
  2. Créer une nouvelle branche (feature/task1_bugfix)

     git checkout -b feature/task1_bugfix
  3. Fusionner avec le --squash option

     git merge --squash feature/task1
  4. Créer une seule livraison

     git commit -am "add single comments"
  5. Poussez votre branche

     git push --set-upstream origin feature/task1_bugfix

30voto

Vagelis Prokopiou Points 546

Fusionner newFeature dans la branche master avec un commit personnalisé :

git merge --squash newFeature && git commit -m 'Your custom commit message';

Si à la place, vous faites

git merge --squash newFeature && git commit

vous obtiendrez un message de livraison qui inclura toutes les newFeature les commits de branche, que vous pouvez personnaliser.

Je l'explique en détail ici : https://youtu.be/FQNAIacelT4

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X