48 votes

Qu'est-ce qui rend la fusion facile dans le DVCS ?

J'ai lu à Joel sur les logiciels :

Avec le contrôle de version distribué, le partie distribuée n'est en fait pas la la partie la plus intéressante.

La partie intéressante est que ces systèmes pensent en termes de changements, et non en termes de versions.

et à HgInit :

Lorsque nous devons fusionner, Subversion essaie de regarder les deux révisions - mon code modifié, et votre code modifié et il essaie de deviner comment les écraser ensemble dans un grand et impie désordre. Il échoue généralement, produisant des pages et des pages de "conflits de fusion" qui ne sont pas vraiment des conflits, simplement des endroits où Subversion n'a pas réussi à comprendre ce que nous avons fait.

En revanche, pendant que nous travaillions séparément dans Mercurial, Mercurial était occupé à garder une série de changesets. Et donc, quand nous voulons fusionner notre code ensemble, Mercurial a en fait beaucoup plus d'informations : il sait ce que chacun de nous a changé et peut réappliquer ces changements, plutôt que simplement regarder le produit final et en essayant de deviner comment l'assembler ensemble.

En regardant le dossier de dépôt de SVN, j'ai l'impression que Subversion maintient chaque révision en tant que changeset . Et d'après ce que je sais, Hg utilise à la fois changeset y instantané alors que Git utilise uniquement instantané pour stocker les données.

Si mon hypothèse est correcte, alors il doit y avoir d'autres moyens de faciliter la fusion dans le DVCS. Quelles sont-elles ?

* Mise à jour :

  • Je suis plus intéressé par la perspective technique, mais les réponses d'un point de vue non technique sont acceptables.
  • Corrections :
    1. Git's conceptuel est purement basé sur des instantanés. Les instantanés peuvent être stockés comme des différences d'autres instantanés, mais les différences sont purement destinées à optimiser le stockage. - Rafa Dowgird 's commentaire
  • D'un point de vue non technique :
    1. C'est simplement culturel : un DVCS ne fonctionnerait pas du tout si la fusion était difficile, donc les développeurs de DVCS investissent beaucoup de temps et d'efforts pour rendre la fusion facile. En revanche, les utilisateurs de CVCS sont habitués à une fusion médiocre, ce qui n'incite pas les développeurs à la faire fonctionner. (Pourquoi faire quelque chose de bien quand vos utilisateurs vous paient aussi bien pour quelque chose de merdique ?)
      ...
      Pour résumer, l'intérêt d'un DVCS est de disposer de nombreux dépôts décentralisés et de fusionner constamment les modifications dans les deux sens. Sans une bonne fusion, un DVCS est tout simplement inutile. Un CVCS peut cependant survivre avec une fusion médiocre, surtout si le fournisseur peut conditionner ses utilisateurs à éviter les branchements. - Jörg W Mittag 's réponse
  • D'un point de vue technique :
    1. L'enregistrement d'un véritable DAG de l'historique est utile ! Je pense que la principale différence est que CVCS n'a pas toujours enregistré une fusion comme un changeset avec plusieurs parents, perdant ainsi certaines informations. - tonfa 's commentaire
    2. à cause de suivi des fusions et le fait plus fondamental que chaque révision connaît ses parents . ... Lorsque chaque révision (chaque commit), y compris les merge commits, connaît ses parents (pour les merge commits cela signifie avoir/se souvenir de plus d'un parent, c'est-à-dire le suivi des fusions), vous pouvez reconstruire le diagramme (DAG = Direct Acyclic Graph) de l'historique des révisions. Si vous connaissez le graphe des révisions, vous pouvez trouver l'ancêtre commun des commits que vous voulez fusionner. Et quand votre DVCS sait lui-même comment trouver un ancêtre commun vous n'avez pas besoin de le fournir comme argument, comme par exemple dans CVS.
      .
      Notez qu'il peut y avoir plus d'un ancêtre commun à deux (ou plusieurs) commits. Git utilise une stratégie de fusion dite "récursive", qui fusionne les bases de fusion (ancêtre commun), jusqu'à ce qu'il ne reste plus qu'un seul ancêtre commun virtuel/effectif (dans une certaine simplification), et peut faire une simple fusion à 3 voies. - Jakub Narbski 's réponse

Vérifiez également Comment et/ou pourquoi la fusion dans Git est-elle meilleure que dans SVN ?

32voto

Jörg W Mittag Points 153275

Il n'y a rien de particulier dans les DVCS qui facilite la fusion. C'est simplement culturel : un DVCS ne fonctionne pas du tout si la fusion était difficile, alors les développeurs de DVCS investissent beaucoup de temps et d'efforts pour rendre la fusion facile. Les utilisateurs de CVCS, en revanche, sont habitués à une fusion médiocre, ce qui n'incite pas les développeurs à la faire fonctionner. (Pourquoi faire quelque chose de bien quand vos utilisateurs vous paient aussi bien pour quelque chose de merdique ?)

Linus Torvalds a dit dans l'une de ses conférences sur Git que lorsqu'il utilisait CVS chez Transmeta, ils ont mis de côté une semaine entière pendant un cycle de développement pour la fusion. Et tout le monde a accepté cela comme l'état normal des choses. Aujourd'hui, pendant une fenêtre de fusion, Linus fait des centaines de fusions en quelques heures.

Les CVCS pourraient avoir d'aussi bonnes capacités de fusion que les DVCS, si les utilisateurs de CVCS allaient simplement voir leurs fournisseurs et leur disaient que cette merde est inacceptable. Mais ils sont pris dans le paradoxe de Blub : ils ont simplement je ne sais pas que c'est inacceptable, parce qu'ils n'ont jamais vu un système de fusion qui fonctionne. Ils ne savent pas qu'il existe quelque chose de mieux.

Et quand ils faire essayent un DVCS, ils attribuent comme par magie toutes les qualités à la partie "D".

Théoriquement, en raison de sa nature centralisée, un CVCS devrait avoir meilleur des capacités de fusion, parce qu'ils ont une vue globale de la tout le site contrairement à DVCS où chaque dépôt ne possède qu'un petit fragment.

Pour récapituler : le point final d'un DVCS est d'avoir de nombreux dépôts décentralisés et de fusionner constamment les changements dans les deux sens. Sans une bonne fusion, un DVCS est tout simplement inutile. Un CVCS peut cependant survivre avec une fusion médiocre, surtout si le fournisseur peut conditionner ses utilisateurs à éviter les branchements.

Donc, comme pour tout ce qui concerne le génie logiciel, c'est une question d'effort.

23voto

Jakub Narębski Points 87537

Dans Git et d'autres DVCS, les fusions sont faciles, non pas à cause d'une quelconque série de jeux de modifications (à moins que vous n'utilisiez Darcs, avec sa théorie des correctifs, ou un DVCS inspiré de Darcs ; ils sont cependant minoritaires) dont parle Joel, mais en raison de suivi des fusions et le fait plus fondamental que chaque révision connaît ses parents . Pour cela, vous avez besoin (je pense) de commits sur l'arbre entier / le référentiel complet... ce qui malheureusement limite la possibilité de faire des checkouts partiels, et de faire un commit sur seulement un sous-ensemble de fichiers.

Lorsque chaque révision (chaque commit), y compris les merge commits, connaît ses parents (pour les merge commits, cela signifie avoir/se souvenir de plus d'un parent, c'est à dire suivi des fusions ), vous pouvez reconstruire le diagramme (DAG = Direct Acyclic Graph) de l'historique des révisions. Si vous connaissez le graphe des révisions, vous pouvez trouver l'ancêtre commun des commits que vous voulez fusionner. Et quand votre DVCS sait lui-même comment trouver un ancêtre commun vous n'avez pas besoin de le fournir comme argument, comme par exemple dans CVS.

Notez qu'il peut y avoir plus d'un ancêtre commun à deux (ou plusieurs) commits. Git utilise une stratégie de fusion dite "récursive", qui fusionne les bases de fusion (ancêtre commun), jusqu'à ce qu'il ne reste plus qu'un seul ancêtre commun virtuel / effectif (dans une certaine simplification), et peut faire une simple fusion à trois.

Utilisation de Git détection de renommage a été créé pour pouvoir traiter les fusions impliquant des renommages de fichiers. (Ceci supporte Jörg W Mittag l'argument selon lequel les DVCS ont une meilleure prise en charge des fusions parce qu'ils devaient l'avoir, car les fusions sont beaucoup plus fréquentes que dans CVCS, dont la fusion est cachée dans la commande 'update', dans le flux de travail 'update-then-commit', etc. Comprendre le contrôle de version (WIP) par Eric S. Raymond).

10voto

Laurens Holst Points 6779

Une partie de la raison est bien sûr l'argument technique selon lequel les DVCS stockent plus d'informations que le SVN (DAG, copies), et ont également un modèle interne plus simple, ce qui explique pourquoi il est capable d'effectuer des fusions plus précises, comme mentionné dans les autres réponses.

Cependant, une différence encore plus importante est que, parce que vous disposez d'un dépôt local, vous pouvez faire de fréquentes petites modifications, ainsi que retirer et fusionner fréquemment les modifications entrantes. Cela est dû davantage au "facteur humain", aux différences dans la façon dont un être humain travaille avec un VCS centralisé par rapport à un DVCS.

Avec SVN, si vous mettez à jour et qu'il y a des conflits, SVN va fusionner ce qu'il peut et insérer des marqueurs dans votre code là où il ne peut pas. Le gros problème avec ceci est que votre code ne sera plus dans un état exploitable jusqu'à ce que vous résolviez tous les conflits.

Cela vous distrait du travail que vous essayez de réaliser, c'est pourquoi les utilisateurs de SVN ne fusionnent généralement pas pendant qu'ils travaillent sur une tâche. Combinez cela avec le fait que les utilisateurs de SVN ont aussi tendance à laisser les changements s'accumuler dans un seul gros commit par peur de casser les copies de travail d'autres personnes, et il y aura de grandes périodes de temps entre la branche et la fusion.

Avec Mercurial, vous pouvez fusionner avec les changements entrants beaucoup plus fréquemment entre vos petits commits incrémentaux. Cela se traduira par définition par moins de conflits de fusion, car vous travaillerez sur une base de code plus à jour.

Et si il s'avère qu'il y a un conflit, vous pouvez décider de reporter la fusion et de l'effectuer à votre guise. Cela rend notamment la fusion beaucoup moins ennuyeuse.

7voto

Jason Orendorff Points 15869

Whoa, l'attaque des essais de 5 paragraphes !

En bref, rien ne rend la chose facile. C'est difficile, et mon expérience montre que des erreurs se produisent. Mais :

  • DVCS vous oblige à vous occuper de la fusion, ce qui implique de prendre quelques minutes pour vous familiariser avec les outils qui existent pour vous aider. Rien que ça, ça aide.

  • DVCS vous encourage à fusionner fréquemment, ce qui aide aussi.

L'extrait de hginit que vous avez cité, prétendant que Subversion est incapable de faire des fusions à trois voies et que Mercurial fusionne en regardant tous les changesets dans les deux branches, est simplement faux sur les deux points.

2voto

Andreas Krey Points 1109

Un point est que la fusion svn est subtilement cassée ; voir http://blogs.open.collab.net/svn/2008/07/subversion-merg.html Je soupçonne que c'est en conjonction avec le fait que svn enregistre mergeinfo même sur les merges cherry-picking. Ajoutez quelques bogues simples dans la gestion des cas limites, et svn, en tant qu'enfant-vedette actuel des CVCS, les fait paraître mauvais par opposition à tous les DVCS qui ne font que bien faire les choses.

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