Git rebase perd son histoire, alors pourquoi rebaser?

Je me suis penchée sur Git au cours des deux derniers jours. La plupart des arguments en faveur d’un rebasage disent qu’il nettoie l’histoire et la rend plus linéaire. Si vous faites des fusions simples (par exemple), vous obtenez une histoire qui montre quand l’histoire a divergé et quand elle a été ramenée. Autant que je sache, le rebasage supprime toute cette histoire. La question est la suivante: pourquoi ne voudriez-vous pas que l’historique des pensions reflète toutes les manières dont le code a été développé, y compris où et comment il a divergé?

Autant que je sache, le rebasage supprime toute cette histoire.

Ce n’est pas correct La reformulation, comme son nom l’indique, modifie la base des commits. Généralement, aucun commit n’est perdu dans ce processus (sauf que vous ne recevez pas de validation de fusion). Bien que votre argument concernant la conservation de tout ce qui concerne le processus de développement dans l’histoire soit correct, cela conduit souvent à des histoires confuses.

Surtout quand on travaille avec d’autres qui travaillent chacun sur leurs propres twigs tout en exigeant que certaines modifications soient apscopes par d’autres (par exemple, A demande à B d’implémenter quelque chose pour que A puisse utiliser cette fonctionnalité dans son propre développement), Par exemple, comme ceci:

  #--#--#--#--*-----*-----------------*---#---\ Branch B / / / / \ ---#-----#-----#-----#-----#-----#-----#-----#-----* Branch A 

Dans cet exemple, nous avons une twig qui fonctionne séparément pour le temps mais qui extrait constamment les modifications de la twig d’origine (# sont les commits d’origine, * sont les fusions).

Maintenant, si nous faisons un rebase sur la twig B avant de fusionner, nous pourrions obtenir ce qui suit:

  #--#--#--#--#---\ Branch B / \ ---#---#---#---#---#---#---#---#---------------* Branch A 

Cela représente les mêmes changements réels, mais B a été rebasé sur un ancien commit sur A, donc toutes les fusions effectuées sur B qui ont été effectuées auparavant ne sont plus nécessaires (car ces modifications sont déjà présentes dans cet ancien commit). Et tous les commits qui manquent maintenant sont les fusions, qui ne contiennent généralement aucune information sur le processus de développement. (Notez que dans cet exemple, vous pouvez également réinitialiser ultérieurement ce dernier engagement pour obtenir une ligne droite, supprimant ainsi tout conseil à la deuxième twig)

Imaginez que vous travaillez sur un projet secret de la domination du monde. Il y a trois cerveaux sur cette conspiration:

  • Le génie
  • Le général
  • Le pirate informatique

Et ils acceptent tous de venir à leur base secrète en une semaine chacun avec un plan détaillé.

Le pirate informatique, en tant que programmeur pragmatique, a suggéré d’utiliser Git pour stocker tous les fichiers des plans. Chacune fournira le repository initial du projet et fusionnera le tout en une semaine.

Ils sont tous d’accord et dans les jours suivants l’histoire se déroule comme suit:

Le génie

Il a fait un total de 70 commits, 10 par jour.

Le général

Il espionne le repo de leurs camarades et fait une stratégie pour les battre. Il a fait 3 commits, tout le dernier jour.

Le pirate informatique

Ce programmeur pragmatique utilisait des twigs. Il a fait 4 plans différents, chacun sur une twig. Chaque twig a été rebaptisée pour ne constituer qu’un seul engagement.

Sept jours ont passé et le groupe se réunit à nouveau pour fusionner tous les plans en un seul chef-d’œuvre. Tous étaient impatients de commencer, alors ils ont tous essayé de fusionner tous les éléments.

Voici l’histoire:

Le génie

Il a fusionné tous les changements du repo du général et celui du pirate informatique. Et puis, étant un amateur de logique, il jeta un coup d’œil au journal. Il s’attendait à voir une évolution logique d’une idée, où les choses étaient construites sur les idées précédentes.

Mais ce que les journaux montraient, c’était une myriade d’engagements d’idées différentes, tous mélangés dans la chronologie. Un lecteur ne pouvait pas vraiment comprendre l’évolution, le raisonnement des commits en lisant simplement la chronologie des commits.

Donc, il a fini avec un désordre, que même un génie ne pouvait pas comprendre.

Le général

La pensée générale: Diviser et conquérir!

Et ainsi, il a fusionné le repo du Génie sur son repo. Il a regardé le journal et a vu un tas de commits de l’idée de génie, qui ont suivi une progression compréhensible, jusqu’au dernier jour. Le dernier jour, les idées du général et du génie ont été mélangées.

Il espionnait The Computer Hacker et connaissait la solution Rebase. Il a donc refait sa propre idée et a recommencé la fusion.

Maintenant, le journal affiche une progression logique chaque jour.

Le pirate informatique

Ce programmeur pragmatique a créé une twig d’intégration pour l’idée Genius, une autre pour l’idée générale et une autre pour ses propres idées. Il a fait un rebase à chaque twig. Et puis il a fusionné tout en maître.

Et tous ses coéquipiers ont vu que son journal était génial. C’était simple C’était compréhensible à première vue.

Si une idée introduisait un problème, il était clair dans quel cas elle était introduite, car il n’y en avait qu’une.

Ils ont fini par conquérir le monde entier et ils ont disparu de l’utilisation de Subversion.

Et tous étaient heureux.

Vous faites un rebase principalement pour retravailler vos commits locaux (celui que vous n’avez pas encore poussé) au-dessus d’une twig distante (vous récupérez simplement), afin de résoudre tout conflit localement (c’est-à-dire avant de les renvoyer au référentiel amont) ).
Voir ” workflow git et questions de rebase vs fusion ” et, assez détaillé: ” git rebase vs git merge “.

Mais rebase ne se limite pas à ce scénario, et combiné avec «–interactive», il permet de réorganiser et de nettoyer localement votre historique. Voir aussi ” Découper les checkins GIT / l’historique GIT “.

pourquoi ne voudriez-vous pas que l’historique des pensions reflète toutes les façons dont le code a été élaboré, y compris où et comment il a divergé?

  • Dans un VCS centralisé, il est important de ne jamais perdre l’histoire, et cela devrait en effet refléter “toutes les manières dont le code a évolué”.
  • Dans un VCS dissortingbué, où vous pouvez faire toutes sortes d’expériences locales avant de publier certaines de vos twigs en amont, il est moins logique de tout garder dans l’historique: tout le monde n’a pas besoin de cloner et de voir toutes vos twigs, tests, alternatives, etc.

Si vous faites une erreur sur un repository public et que personne ne l’a encore fait, vous pouvez sauver la face et la confusion:

 git reset --hard [SHAnumber] git rebase -f master git push -f origin HEAD:master 

Pour vider la corbeille:

 git gc