Fusion: Hg / Git vs SVN

144

Je lis souvent que Hg (et Git et ...) sont meilleurs pour fusionner que SVN mais je n'ai jamais vu d'exemples pratiques où Hg / Git peut fusionner quelque chose où SVN échoue (ou où SVN a besoin d'une intervention manuelle). Pourriez-vous poster quelques listes pas à pas d'opérations de branchement / modification / validation /...- qui montrent où SVN échouerait alors que Hg / Git avance avec bonheur? Cas pratiques, pas très exceptionnels s'il vous plaît ...

Un peu de contexte: nous avons quelques dizaines de développeurs travaillant sur des projets utilisant SVN, avec chaque projet (ou groupe de projets similaires) dans son propre référentiel. Nous savons comment appliquer les branches de version et de fonctionnalités afin de ne pas rencontrer de problèmes très souvent (c'est-à-dire que nous y sommes allés, mais nous avons appris à surmonter les problèmes de Joel "un programmeur causant un traumatisme à toute l'équipe". ou "besoin de six développeurs pendant deux semaines pour réintégrer une succursale"). Nous avons des branches de publication qui sont très stables et utilisées uniquement pour appliquer des corrections de bogues. Nous avons des trunks qui devraient être suffisamment stables pour pouvoir créer une version en une semaine. Et nous avons des branches de fonctionnalités sur lesquelles des développeurs uniques ou des groupes de développeurs peuvent travailler. Oui, ils sont supprimés après la réintégration afin de ne pas encombrer le référentiel. ;)

J'essaie donc toujours de trouver les avantages de Hg / Git par rapport à SVN. J'adorerais avoir une expérience pratique, mais il n'y a pas encore de plus gros projets que nous pourrions déplacer vers Hg / Git, donc je suis obligé de jouer avec de petits projets artificiels qui ne contiennent que quelques fichiers composés. Et je recherche quelques cas où vous pouvez ressentir la puissance impressionnante de Hg / Git, car jusqu'à présent, j'ai souvent lu à leur sujet mais je n'ai pas réussi à les trouver moi-même.

stmax
la source
2
Je pense que vous devriez faire attention aux doublons exacts: stackoverflow.com/questions/43995/… stackoverflow.com/questions/459891/…
P Shved
11
J'avais déjà lu le premier, l'autre était nouveau. Mais ils ont déjà 1 à 2 ans et semblent concerner principalement des problèmes pré-svn-1.5 (où svn n'avait pas encore de suivi de fusion).
stmax
2
Juste un commentaire que vous pouvez également regrouper Bazaar avec git / hg comme un autre DVCS qui gérera correctement les problèmes ci-dessous. Et puisque vous avez mentionné essayer de trouver des avantages: un simple avantage logistique de git / hg / bzr est que les branches ne sont pas globales comme elles le sont avec svn. Vous n'avez pas besoin de voir 67 succursales, alors que seulement quelques-unes s'appliquent à vous. Tout le monde fait son travail dans des succursales «privées» et utilise ensuite l'excellente capacité de fusion pour fusionner sans se demander si la fusion fonctionnera dans 99% des cas.
wadesworld
5
@wade: voyez-vous les succursales «privées» comme un avantage dans un environnement d'entreprise? je suis inquiet pour les sauvegardes. J'ai souvent des succursales qui vivent 1 à 2 mois avant la réintégration ..
stmax
9
@stmax: une préoccupation valide. Cependant, ce que vous trouvez dans de nombreux environnements d'entreprise avec subversion, c'est que les gens tardent à s'enregistrer jusqu'à ce que leur code soit parfait, et vous avez la même exposition là-bas.
wadesworld

Réponses:

91

Je n'utilise pas Subversion moi-même, mais d'après les notes de publication de Subversion 1.5: Suivi des fusions (fondamental), il semble qu'il y ait les différences suivantes par rapport au fonctionnement du suivi des fusions dans les systèmes de contrôle de version DAG complets comme Git ou Mercurial.

  • La fusion d'un tronc à une branche est différente de la fusion d'une branche à l'autre: pour une raison quelconque, la fusion d'un tronc à une branche nécessite une --reintegrateoption pour svn merge.

    Dans les systèmes de contrôle de version distribués comme Git ou Mercurial, il n'y a pas de différence technique entre le tronc et la branche: toutes les branches sont créées égales (il peut cependant y avoir une différence sociale ). La fusion dans les deux sens se fait de la même manière.

  • Vous devez fournir une nouvelle option -g( --use-merge-history) svn loget svn blameprendre en compte le suivi des fusions.

    Dans Git et Mercurial, le suivi des fusions est automatiquement pris en compte lors de l'affichage de l'historique (log) et du blâme. Dans Git, vous pouvez demander à suivre le premier parent uniquement avec --first-parent(je suppose qu'une option similaire existe également pour Mercurial) pour "supprimer" les informations de suivi de fusion dans git log.

  • D'après ce que je comprends, la svn:mergeinfopropriété stocke des informations par chemin sur les conflits (Subversion est basée sur les ensembles de modifications), tandis que dans Git et Mercurial, il s'agit simplement d'objets de validation qui peuvent avoir plus d'un parent.

  • La sous- section "Problèmes connus" pour le suivi des fusions dans Subversion suggère que la fusion répétée / cyclique / réfléchissante pourrait ne pas fonctionner correctement. Cela signifie qu'avec les histoires suivantes, la deuxième fusion pourrait ne pas faire la bonne chose ('A' peut être un tronc ou une branche, et 'B' peut être une branche ou un tronc, respectivement):

    * --- * --- x --- * --- y --- * --- * --- * --- M2 <- A
             \ \ /
              - * ---- M1 --- * --- * --- / <- B
    

    Dans le cas où l'art ASCII ci-dessus serait cassé: la branche 'B' est créée (fourchue) à partir de la branche 'A' à la révision 'x', puis la branche 'A' ultérieure est fusionnée à la révision 'y' dans la branche 'B' comme fusionner «M1», et enfin la branche «B» est fusionnée dans la branche «A» en tant que fusion «M2».

    * --- * --- x --- * ----- M1 - * --- * --- M2 <- A
             \ / / 
              \ - * --- y --- * --- * --- / <- B
    

    Dans le cas où l'art ASCII ci-dessus est cassé: la branche 'B' est créée (fourchue) à partir de la branche 'A' à la révision 'x', elle est fusionnée dans la branche 'A' à 'y' en tant que 'M1', et plus tard fusionné à nouveau dans la branche «A» en tant que «M2».

  • Subversion peut ne pas prendre en charge le cas avancé de fusion entrecroisée .

    * --- b ----- B1 - M1 - * --- M3
         \ \ / /
          \ X /
           \ / \ /
            \ - B2 - M2 - *
    

    Git gère très bien cette situation en pratique en utilisant une stratégie de fusion "récursive". Je ne suis pas sûr de Mercurial.

  • Dans "Problèmes connus", il y a un avertissement que le suivi des fusions peut ne pas fonctionner avec les renommages de fichiers, par exemple lorsqu'un côté renomme le fichier (et peut-être le modifie) et que le deuxième côté modifie le fichier sans le renommer (sous l'ancien nom).

    Git et Mercurial gèrent tous les deux ce cas très bien dans la pratique: Git utilisant la détection de renommage , Mercurial utilisant le suivi de renommage .

HTH

Jakub Narębski
la source
en quelque sorte (erreur dans l'analyseur Markdown?) la partie après le <pre>...</pre>bloc n'est pas en retrait comme il se doit ...
Jakub Narębski
1
+1 pour les nombreux exemples détaillés. Je ne comprends pas encore pourquoi l'exemple du premier ascii-art pourrait poser des problèmes. cela ressemble à la manière standard de traiter les branches de fonction: supposons que A est le tronc, B est une branche de fonction. vous fusionnez chaque semaine de A à B et lorsque vous avez terminé avec la fonctionnalité, vous fusionnez tout de B à A, puis supprimez B. cela a toujours fonctionné pour moi. ai-je mal compris le diagramme?
stmax
1
Notez que je ne sais pas (je n'ai pas vérifié) que les exemples donnés ci-dessus posent vraiment des problèmes dans Subversion . Les changements de noms et les fusions entrecroisées sont un vrai problème dans SVN, je pense.
Jakub Narębski
2
Les fusions de réintégration sont une option spéciale pour vous aider dans le cas le plus courant lors de la fusion - il n'y a pas non plus de différence technique entre les branches et le tronc dans svn. J'ai tendance à ne jamais l'utiliser et à m'en tenir à l'option de fusion standard. Pourtant, le seul problème avec svn merge est qu'il traite un déplacement / renommer comme une suppression + ajout.
gbjbaanb le
--reintegrateest obsolète.
naught101
120

Moi aussi, j'ai cherché un cas où, disons, Subversion ne parvient pas à fusionner une branche et Mercurial (et Git, Bazaar, ...) fait ce qu'il faut.

Le livre SVN décrit comment les fichiers renommés sont fusionnés de manière incorrecte . Cela s'applique à Subversion 1.5 , 1.6 , 1.7 et 1.8 ! J'ai essayé de recréer la situation ci-dessous:

cd / tmp/ tmp
rm -rf svn-repo svn-checkout- rf svn - repo svn - paiement
svnadmin crée svn-repo- repo
svn checkout file: /// tmp / svn-repo svn-checkout: /// tmp / svn - repo svn - extraction
cd svn-checkout- caisse
branches de tronc mkdir
echo "Au revoir, Monde!" > trunk / bonjour.txt'Au revoir le monde!' > coffre / bonjour . SMS 
svn ajouter des branches de tronc
svn commit -m 'Importation initiale.'- m 'Importation initiale.'
svn copy '^ / trunk' '^ / branches / rename' -m 'Créer une branche.''^ / trunk' '^ / branches / rename' - m 'Créer une branche.'  
svn commutateur '^ / trunk'.'^ / coffre' . 
echo 'Bonjour, Monde!' > bonjour.txt'Bonjour le monde!' > bonjour . SMS 
svn commit -m 'Mise à jour sur le tronc.'- m 'Mise à jour sur le coffre.'
svn commutateur '^ / branches / renommer'.'^ / branches / renommer' . 
svn renommer hello.txt hello.en.txt. txt bonjour . en . SMS
svn commit -m 'Renommer sur la branche.'- m 'Renommer sur la branche.'
svn commutateur '^ / trunk'.'^ / coffre' . 
svn merge - réintégrer '^ / branches / renommer'- réintégrer '^ / branches / renommer'

Selon le livre, la fusion devrait se terminer proprement, mais avec des données erronées dans le fichier renommé car la mise à jour trunkest oubliée. Au lieu de cela, j'obtiens un conflit d'arbre (c'est avec Subversion 1.6.17, la dernière version de Debian au moment de l'écriture):

--- Fusion des différences entre les URL de référentiel dans «.»:
Un bonjour.en.txt
   C bonjour.txt
Résumé des conflits:
  Conflits d'arbres: 1

Il ne devrait pas y avoir de conflit du tout - la mise à jour doit être fusionnée avec le nouveau nom du fichier. Alors que Subversion échoue, Mercurial gère cela correctement:

rm -rf /tmp/hg-repo
hg init /tmp/hg-repo
cd /tmp/hg-repo
echo 'Goodbye, World!' > hello.txt
hg add hello.txt
hg commit -m 'Initial import.'
echo 'Hello, World!' > hello.txt
hg commit -m 'Update.'
hg update 0
hg rename hello.txt hello.en.txt
hg commit -m 'Rename.'
hg merge

Avant la fusion, le référentiel ressemble à ceci (de hg glog):

@ changeset: 2: 6502899164cc
| étiquette: astuce
| parent: 0: d08bcebadd9e
| utilisateur: Martin Geisler
| date: jeu avr.01 12:29:19 2010 +0200
| résumé: Renommer.
|
| o changeset: 1: 9d06fa155634
| / utilisateur: Martin Geisler 
| date: jeu avr.01 12:29:18 2010 +0200
| résumé: mise à jour.
|
o changeset: 0: d08bcebadd9e
   utilisateur: Martin Geisler 
   date: jeu avr.01 12:29:18 2010 +0200
   résumé: importation initiale.

Le résultat de la fusion est:

fusion de hello.en.txt et hello.txt avec hello.en.txt
0 fichier mis à jour, 1 fichier fusionné, 0 fichier supprimé, 0 fichier non résolu
(fusion de branche, n'oubliez pas de vous engager)

En d'autres termes: Mercurial a pris le changement de la révision 1 et l'a fusionné dans le nouveau nom de fichier de la révision 2 ( hello.en.txt). La gestion de ce cas est bien sûr essentielle afin de prendre en charge le refactoring et le refactoring est exactement le genre de chose que vous voudrez faire sur une branche.

Martin Geisler
la source
+1 pour un exemple détaillé, on peut taper sur le clavier et voir par soi-même ce qui se passe. En tant que noob Mercurial, je me demande si la version hg de cet exemple est la suivante de manière évidente, ligne par ligne?
DarenW
4
@DarenW: J'ai ajouté les commandes Mercurial correspondantes, j'espère que cela rend les choses plus claires!
Martin Geisler
17

Sans parler des avantages habituels (commits hors ligne, processus de publication , ...) voici un exemple de "fusion" que j'aime bien:

Le scénario principal que je continue de voir est une branche sur laquelle ... deux tâches indépendantes sont en fait développées
(cela a commencé à partir d'une fonctionnalité, mais cela a conduit au développement de cette autre fonctionnalité.
Ou cela a commencé à partir d'un patch, mais cela a conduit au développement d'une autre fonctionnalité).

Comment fusionner une seule des deux fonctionnalités de la branche principale?
Ou comment isolez-vous les deux fonctionnalités dans leurs propres branches?

Vous pouvez essayer de générer une sorte de correctif, le problème avec cela est que vous n'êtes plus sûr des dépendances fonctionnelles qui auraient pu exister entre:

  • les commits (ou révision pour SVN) utilisés dans vos patchs
  • l'autre commet ne fait pas partie du patch

Git (et Mercurial aussi je suppose) propose l'option rebase --onto pour rebaser (réinitialiser la racine de la branche) une partie d'une branche:

D' après le message de Jefromi

- x - x - x (v2) - x - x - x (v2.1)
           \
            x - x - x (v2-only) - x - x - x (wss)

vous pouvez démêler cette situation où vous avez des correctifs pour la v2 ainsi qu'une nouvelle fonctionnalité wss en:

- x - x - x (v2) - x - x - x (v2.1)
          |\
          |  x - x - x (v2-only)
           \
             x - x - x (wss)

, vous permettant de:

  • tester chaque branche isolément pour vérifier si tout compile / fonctionne comme prévu
  • ne fusionnez que ce que vous voulez principal.

L'autre fonctionnalité que j'aime (qui influence les fusions) est la possibilité d' écraser les commits (dans une branche pas encore poussée vers un autre repo) afin de présenter:

  • une histoire plus propre
  • commits qui sont plus cohérents (au lieu de commit1 pour fonction1, commit2 pour fonction2, commit3 à nouveau pour fonction1 ...)

Cela garantit des fusions beaucoup plus faciles, avec moins de conflits.

VonC
la source
svn n'a pas de commits hors ligne? rofl? comment peut-on envisager de l'utiliser, même à distance, s'il en est ainsi?
o0 '.
@Lohoris Lorsque SVN est sorti, il n'y avait pas de DVCS open source largement utilisés; à ce stade, je pense que c'est surtout par inertie que les gens l'utilisent encore.
Max Nanasy
@MaxNanasy une très mauvaise sorte d'inertie ... quand même, le choisir maintenant serait tout simplement stupide.
o0 '.
Les commits @Lohoris Online (plus précisément, centralisés) ne sont pas si importants dans une petite équipe où le référentiel peut simplement être sur un serveur local partagé. Les DVCS ont été principalement inventés pour de grandes équipes géographiquement réparties (git et mercurial étaient destinés à gérer le code du noyau Linux) et des projets open source (d'où la popularité de GitHub). L'inertie peut également être considérée comme une évaluation des risques par rapport aux avantages du changement d'un outil au cœur du flux de travail d'une équipe.
IMSoP
1
@Lohoris Je pense que vous avez mal compris mon point sur DB, pare - feu, etc: il y a peu de point de me pouvoir engager sur ma machine à la maison si je ne peux pas vraiment exécuter ce code en premier. Je pourrais travailler à l'aveugle, mais le fait que je ne puisse pas commettre des choses quelque part ne serait pas ce qui me décourageait.
IMSoP
8

Nous avons récemment migré de SVN vers GIT, et avons été confrontés à cette même incertitude. Il y avait beaucoup de preuves anecdotiques que GIT était meilleur, mais il était difficile de trouver des exemples.

Je peux vous dire cependant que GIT est BEAUCOUP MIEUX pour fusionner que SVN. C'est évidemment anecdotique, mais il y a un tableau à suivre.

Voici quelques-unes des choses que nous avons trouvées:

  • SVN avait l'habitude de générer beaucoup de conflits d'arbres dans des situations où il semblait que cela ne devrait pas. Nous ne sommes jamais allés au fond des choses, mais cela n'arrive pas dans GIT.
  • Bien que meilleur, GIT est beaucoup plus compliqué. Passez du temps à vous entraîner.
  • Nous étions habitués à Tortoise SVN, ce qui nous plaisait. Tortoise GIT n'est pas aussi bon et cela peut vous décourager. Cependant, j'utilise maintenant la ligne de commande GIT que je préfère de loin à Tortoise SVN ou à n'importe quelle interface graphique GIT.

Lors de l'évaluation de GIT, nous avons effectué les tests suivants. Celles-ci montrent GIT comme le gagnant en matière de fusion, mais pas autant. En pratique, la différence est beaucoup plus grande, mais je suppose que nous n'avons pas réussi à reproduire les situations que SVN gère mal.

Évaluation de la fusion GIT vs SVN

cedd
la source
5

D'autres en ont couvert les aspects les plus théoriques. Je peux peut-être donner une perspective plus pratique.

Je travaille actuellement pour une entreprise qui utilise SVN dans un modèle de développement "feature branch". C'est:

  • Aucun travail ne peut être effectué sur le coffre
  • Chaque développeur peut créer ses propres branches
  • Les succursales devraient durer pendant la durée de la tâche entreprise
  • Chaque tâche doit avoir sa propre branche
  • Les fusions vers le coffre doivent être autorisées (normalement via bugzilla)
  • Lorsque des niveaux de contrôle élevés sont nécessaires, les fusions peuvent être effectuées par un contrôleur d'accès

En général, cela fonctionne. SVN peut être utilisé pour un flux comme celui-ci, mais ce n'est pas parfait. Il y a certains aspects du SVN qui gênent et façonnent le comportement humain. Cela lui donne des aspects négatifs.

  • Nous avons eu pas mal de problèmes avec les gens qui partent de points inférieurs à ^/trunk. Ces portées fusionnent les enregistrements d'informations dans toute l'arborescence et finissent par interrompre le suivi de fusion. De faux conflits commencent à apparaître et la confusion règne.
  • Ramasser les changements du tronc dans une branche est relativement simple. svn mergefait ce que vous voulez. La fusion de vos modifications nécessite (on nous le dit) --reintegratela commande de fusion. Je n'ai jamais vraiment compris ce commutateur, mais cela signifie que la branche ne peut plus être fusionnée dans le tronc. Cela signifie que c'est une branche morte et que vous devez en créer une nouvelle pour continuer le travail. (Voir la note)
  • Toutes les opérations sur le serveur via des URL lors de la création et de la suppression de branches déroutent et effraient vraiment les gens. Alors ils l'évitent.
  • Il est facile de se tromper entre les branches, laissant une partie d'un arbre regardant la branche A, tout en laissant une autre partie regardant la branche B. Les gens préfèrent donc faire tout leur travail dans une branche.

Ce qui a tendance à arriver, c'est qu'un ingénieur crée une succursale le jour 1. Il commence son travail et l'oublie. Quelque temps plus tard, un patron arrive et lui demande s'il peut remettre son travail dans le coffre. L'ingénieur redoute ce jour car la réintégration signifie:

  • Fusionner sa branche de longue date dans le tronc et résoudre tous les conflits, et publier du code sans rapport qui aurait dû être dans une branche séparée, mais qui ne l'a pas été.
  • Supprimer sa branche
  • Créer une nouvelle branche
  • Basculer sa copie de travail vers la nouvelle succursale

... et parce que l'ingénieur fait ça aussi peu qu'il le peut, il ne se souvient pas de "l'incantation magique" pour faire chaque étape. De mauvais commutateurs et URL se produisent, et soudainement ils sont en désordre et ils vont chercher «l'expert».

Finalement, tout s'installe, et les gens apprennent à faire face aux lacunes, mais chaque nouveau démarreur traverse les mêmes problèmes. La réalité finale (par opposition à ce que j'ai exposé au début) est:

  • Aucun travail n'est effectué sur le coffre
  • Chaque développeur a une branche principale
  • Les succursales durent jusqu'à ce que le travail doive être libéré
  • Les corrections de bogues avec ticket ont tendance à avoir leur propre branche
  • Les fusions vers le coffre sont effectuées lorsqu'elles sont autorisées

...mais...

  • Parfois, le travail le rend au tronc alors qu'il ne le devrait pas, car il est dans la même branche que quelque chose d'autre.
  • Les gens évitent toute fusion (même les choses faciles), alors les gens travaillent souvent dans leurs propres petites bulles
  • De grandes fusions ont tendance à se produire et à provoquer un chaos limité.

Heureusement, l'équipe est assez petite pour faire face, mais elle ne pourrait pas évoluer. Le fait est que rien de tout cela n'est un problème avec CVCS, mais plus que parce que les fusions ne sont pas aussi importantes que dans DVCS, elles ne sont pas aussi astucieuses. Ce «frottement de fusion» provoque un comportement qui signifie qu'un modèle «Feature Branch» commence à se décomposer. Les bonnes fusions doivent être une caractéristique de tous les VCS, pas seulement de DVCS.


Selon cela, il y a maintenant un --record-onlycommutateur qui pourrait être utilisé pour résoudre le --reintegrateproblème, et apparemment la v1.8 choisit quand faire une réintégration automatiquement, et cela ne rend pas la branche morte par la suite

Paul S
la source
Si je comprends bien, l'option --reintegrate indique à svn que vous avez déjà résolu les modifications conflictuelles lors de la fusion sur la branche de fonctionnalité. En fait, plutôt que de le traiter comme un correctif, il écrase des fichiers entiers avec la version de la branche, après avoir déjà vérifié dans l'historique de fusion que toutes les révisions du tronc ont été fusionnées dans la branche.
IMSoP
@IMSoP: peut-être, cela a du sens. Cela ne m'explique pas pourquoi c'était nécessaire ni pourquoi cela a rendu impossible de nouvelles fusions à partir de cette branche. Cela n'a pas aidé que l'option était en grande partie non documentée non plus.
Paul S
Je ne l'ai jamais utilisé que via TortoiseSVN, où il était toujours clairement expliqué dans l'interface utilisateur de fusion. Je pense que SVN 1.8 choisit automatiquement la bonne stratégie et n'a pas besoin d'option distincte, mais je ne sais pas s'ils ont corrigé l'algorithme de fusion normal pour traiter correctement une branche qui a été réinitialisée de cette manière.
IMSoP
3

Avant la subversion 1.5 (si je ne me trompe pas), la subversion avait un inconvénient majeur en ce qu'elle ne se souvenait pas de l'historique des fusions.

Regardons le cas décrit par VonC:

- x - x - x (v2) - x - x - x (v2.1)
          |\
          |  x - A - x (v2-only)
           \
             x - B - x (wss)

Notez les révisions A et B. Supposons que vous ayez fusionné les modifications de la révision A sur la branche "wss" à la branche "v2 uniquement" à la révision B (pour une raison quelconque), mais que vous avez continué à utiliser les deux branches. Si vous tentiez de fusionner à nouveau les deux branches en utilisant mercurial, cela ne fusionnerait que les modifications après les révisions A et B. Avec la subversion, vous deviez tout fusionner, comme si vous n'aviez pas fait de fusion auparavant.

Voici un exemple tiré de ma propre expérience, où la fusion de B à A a pris plusieurs heures en raison du volume de code: cela aurait été une vraie douleur à refaire , ce qui aurait été le cas avec la subversion pré-1.5.

Une autre différence, probablement plus pertinente, dans le comportement de fusion de Hginit: Subversion Re-education :

Imaginez que vous et moi travaillions sur du code, et que nous branchions ce code, et que nous partions chacun dans nos espaces de travail séparés et apportions de nombreuses modifications à ce code séparément, de sorte qu'ils ont beaucoup divergé.

Quand 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 désordre impie. 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, alors que nous travaillions séparément dans Mercurial, Mercurial était occupé à conserver une série de modifications. Et donc, lorsque 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 de simplement regarder le produit final et d'essayer de deviner comment le mettre. ensemble.

En bref, la façon dont Mercurial analyse les différences est (était?) Supérieure à celle de la subversion.

Tomislav Nakic-Alfirevic
la source
5
j'ai lu hginit. dommage qu'il ne montre pas plus d'exemples pratiques où hg fait mieux que svn .. fondamentalement, il vous dit de "faire confiance à joel" que hg est juste mieux. les exemples simples qu'il a montrés pourraient probablement être faits avec svn aussi .. en fait c'est pourquoi j'ai ouvert cette question.
stmax
1
En se basant sur la manière dont cela est dit, la question naïve vient à l'esprit: et si l'algorithme de fusion de Mercurial était mis dans Subversion? Est-ce que svn serait aussi bon que hg? Non, car l'avantage de hg réside dans l'organisation de niveau supérieur, et non dans le texte mathématique de bas niveau de la fusion de lignes à partir de fichiers. C'est la nouvelle idée dont les utilisateurs svn ont besoin pour grok.
DarenW
@stmax: Je peux voir ce que tu veux dire. Cependant, l'opinion de Joel ou de quelqu'un d'autre n'a pas vraiment d'importance: une technologie est soit meilleure que l'autre (pour un ensemble de cas d'utilisation) ou non. @DarenW et @stmax: d'après ma propre expérience personnelle, Hg gagne haut la main en raison de son fonctionnement distribué (je ne suis pas connecté tout le temps), des performances (beaucoup d'opérations locales), des branchements extrêmement intuitifs surpuissants par un algorithme de fusion supérieur, hg rollback, sortie de journal basée sur des modèles, hg glog, dossier unique .hg ... Je pourrais juste continuer, encore et encore ... tout autre chose que peut-être git et bazaar ressemble à une camisole de force.
Tomislav Nakic-Alfirevic
Le commentaire hg cité à propos des "changesets" me semble plutôt inexact. SVN sait parfaitement quels changements il fusionne (un changeset est fondamentalement la différence entre deux instantanés, et vice versa, n'est-ce pas?), Et peut appliquer chacun d'eux à son tour s'il le souhaite; n'a certainement pas à «deviner» quoi que ce soit. Si cela crée "un gros désordre impie", alors c'est un problème d'implémentation, pas quelque chose de fondamental pour la conception. Le principal problème difficile à résoudre en plus de la conception actuelle de l'architecture est le déplacement / copie / changement de nom de fichier.
IMSoP