web-dev-qa-db-fra.com

Dans git, quelle est la différence entre merge --squash et rebase?

Je suis nouveau sur Git et j'essaie de comprendre la différence entre un squash et un rebasement. Si je comprends bien, vous effectuez un squash lorsque vous effectuez un rebasement.

320
GiH

git merge --squash et git rebase --interactive peuvent tous deux générer un commit "écrasé".
Mais ils servent des objectifs différents.

produira un commit écrasé sur la branche de destination, sans marquer de relation de fusion.
(Remarque: il ne produit pas de commit immédiatement: vous avez besoin d'un git commit -m "squash branch" supplémentaire)
Ceci est utile si vous voulez jeter complètement la branche source à partir de (schéma extrait de SO question ):

 git checkout stable

      X                   stable
     /                   
a---b---c---d---e---f---g tmp

à:

git merge --squash tmp
git commit -m "squash tmp"

      X-------------------G stable
     /                   
a---b---c---d---e---f---g tmp

puis en supprimant la branche tmp.

Remarque: git merge A UNE OPTION --commit , mais depuis Git 2.22.1 (Q3 2019), vous ne pouvez pas l'utiliser avec git merge --squash.

Voir commit 1d14d0c (24 mai 2019) par Vishal Verma (reloadbrain) .
(Fusionnée par Junio ​​C Hamano - gitster - dans commit 33f279 , 25 juillet 2019)

merge: refuse --commit avec --squash

Auparavant, lorsque --squash était fourni, 'option_commit' était supprimé en silence. Cela aurait pu surprendre un utilisateur qui a tenté de remplacer le comportement de non-validation de squash en utilisant explicitement --commit.

git/gitbuiltin/merge.c#cmd_merge() inclut désormais:

if (option_commit > 0)
    die(_("You cannot combine --squash with --commit."));

rejoue tout ou partie de vos commits sur une nouvelle base, vous permettant ainsi d’écraser (ou plus récemment de "réparer", voyez ceci SO question ), en allant directement à:

git checkout tmp
git rebase -i stable

      stable
      X-------------------G tmp
     /                     
a---b

Si vous choisissez d'écraser tous les commits de tmp (mais, contrairement à merge --squash, vous pouvez choisir de rejouer certains éléments et d'en écraser d'autres).

Les différences sont donc les suivantes:

  • merge ne touche pas votre branche source (tmp ici) et crée un commit à l'endroit souhaité.
  • rebase vous permet de continuer sur la même branche source (toujours tmp) avec:
    • une nouvelle base
    • une histoire plus propre
328
VonC

Fusionner les commits: conserve tous les commits de votre branche et les entrelace avec des commits sur la branche de base.enter image description here

Merge Squash: conserve les modifications mais omet les commits individuels de l’historique enter image description here

Rebase: Cela déplace la totalité de la branche de fonctionnalités pour qu'elle commence sur le sommet de la branche principale, incorporant de fait tous les nouveaux commits dans master.

enter image description here

Plus sur ici

130
Md Ayub Ali Sarker

Fusionner squash fusionne une arborescence (une séquence de commits) en un seul commet. Autrement dit, il écrase toutes les modifications apportées à n dans une seule livraison.

Rebaser, c'est re-baser, c'est-à-dire choisir une nouvelle base (commit parent) pour un arbre. Peut-être que le terme Mercurial est plus clair: on l’appelle transplantation, c’est juste: choisir un nouveau motif (parent commit, root) pour un arbre.

Lorsque vous effectuez une rebase interactive, vous avez le choix entre squash, pick, edit ou ignorer les commits que vous allez rebaser.

J'espère que c'était clair!

74
Mauricio Scheffer