web-dev-qa-db-fra.com

Y a-t-il une différence entre les fonts dans SVN par rapport à Git ou Mercurial?

De ma compréhension, SVN est 'facile à brancher. Difficile à fusionner '. Pourquoi donc? Y a-t-il une différence comment ils fusionnent?

12
user2528

S'il vous plaît voir My Stack Overflow Réponse Pour une situation très concrète où Mercurial (et Git) se fusionne sans problèmes et où Subversion vous présente avec un faux conflit. La situation est une simple refactoring faite sur une succursale où vous renommez certains fichiers.

En ce qui concerne les TDAMMERS Répondre, il y a un certain nombre de malentendus là-bas:

  • Subversion, mercuriale et git tous les instantanés du projet sur le référentiel. Les appeler Versions, révisions, ou les modifications ne fait aucune différence. Ce sont tous des instantanés logiquement atomiques d'un ensemble de fichiers.

  • La taille de vos commits ne fait aucune différence quand il s'agit de la fusionner. Les trois systèmes fusionnent avec l'algorithme de fusion à trois voies standard et les intrants à cet algorithme sont

    • la plus grande version ancestrale commune
    • version sur une branche
    • version sur une autre branche

    Il Peu importe Comment les deux versions de la branche ont été créées. Vous pouvez avoir utilisé 1000 petits commits depuis la version ancestrale ou vous pouvez avoir utilisé 1 commit. Tout ce qui compte est la version finale des fichiers. (Oui, c'est surprenant! Oui, beaucoup de guides DVCS l'obtiennent horriblement.)

Il soulève également de bons points sur les différences:

  • Subversion a du "vaudou" où vous pouvez fusionner de /trunk Dans, disons, /branches/foo. Mercurial et Git n'utilise pas ce modèle - les branches sont plutôt modélisées directement dans l'historique. L'historique devient donc un Graphique acyclique dirigé au lieu d'être linéaire. C'est un modèle beaucoup plus simple que celui utilisé par Subversion et cela coupe un certain nombre de cas d'angle.

  • Vous pouvez facilement retarder une fusion ou même laisser quelqu'un d'autre le gérer. Si hg merge Vous donne une tonne de conflits, vous pouvez demander à votre collègue de hg pull De vous, puis il a exactement le même état. Donc, il peut hg merge Et peut-être qu'il est mieux à résoudre les conflits que vous.

    Ceci est très difficile avec la subversion où vous devez mettre à jour avant ​​vous pouvez commettre. Vous ne pouvez pas simplement ignorer les modifications sur le serveur et continuer à vous engager sur votre propre branche anonyme. En général, Subversion vous oblige à jouer avec A Copie de travail sale lorsque vous svn update. C'est un peu risqué car vous n'avez pas stocké vos changements nulle part en sécurité. Git et Mercurial vous permettent de commettre d'abord, puis de mettre à jour et de fusionner si nécessaire.

La vraie raison GIT et Mercurial sont meilleures à la fusion que la subversion est une question de mise en œuvre. Il y a des conflits de renommée que Subversion ne peut tout simplement pas gérer la pensée, il est clair que la réponse correcte est. Mercurial et Git gère ceux qui sont facilement. Mais il n'y a aucune raison pour que Subversion ne puisse pas gérer ceux qui sont centralisés n'est certainement pas la raison.

21
Martin Geisler

Le problème de base réside dans la manière dont ces systèmes représentent une structure de répertoire versé.

Le concept de base de Subversion autour duquel tout le système tourne est celui d'une version (ou, dans SVN Lingo, "révision"): un instantané d'un fichier à un certain point. Tant que l'histoire est parfaitement linéaire, tout va bien, mais si vous devez fusionner des changements de deux lignes de développement indépendants, SVN doit comparer les versions actuelles des deux, puis effectuer une comparaison à trois voies entre la dernière version partagée. et les deux versions de tête. Les lignes qui semblent changées dans l'une des têtes, mais pas l'autre, peuvent facilement être résolues; Les lignes qui dévient exactement la même manière dans les deux têtes sont plus difficiles, mais généralement faisables; Les lignes qui dévient de différentes manières sont ce qui fait dire SVN "Je ne peux pas comprendre cela, humain, s'il vous plaît résoudre cela pour moi."

Par contraste, piste git et mercuriale modifications plutôt que versions. L'ensemble du référentiel est un arbre de modifications, chacun en fonction d'un parent, où une modification des parents peut avoir un nombre quelconque d'enfants et la racine d'arbre représente un répertoire vide. En d'autres termes, GIT/HG dit "D'abord, je n'avais rien, alors ce patch a été appliqué, puis ce patch, etc.". Lorsque vous devez fusionner deux lignes de développement, GIT/HG sait non seulement à quoi ressemble chaque tête et quelle est la dernière version commune, elle sait également comment la transition s'est produite, permettant une fusion beaucoup plus intelligente.

Une autre chose qui facilite la fusion dans un DVCS est une conséquence indirecte de la séparation des concepts de commet et Push , et de permettre toutes sortes de fusion croisées entre deux clones du même référentiel à tout moment. Avec SVN, les gens ont tendance à commettre de gros changements avec des changements souvent non liés, car une commission est également une mise à jour sur le référentiel central qui affecte tous les autres membres de l'équipe; Si vous commettez une version cassée, tout le monde va être en colère contre vous. Étant donné que la plupart des configurations impliquent un serveur SVN en réseau, l'engagement implique également de pomper les données sur le réseau, ce qui signifie que l'engagement introduit un délai considérable au workflow (en particulier lorsque votre copie de travail est obsolète et que vous devez tirer d'abord). Avec Git et Mercurial, le commit se produit localement, et les deux sont très efficaces pour la manipulation des systèmes de fichiers locaux, il finit généralement instantanément. En conséquence, les gens (une fois qu'ils s'y sont habitués à cela) commettent de petits changements incrémentiels, puis quand cela fonctionne, poussez une douzaine d'une dizaine comme parti. Ensuite, lorsque le temps de fusion vient, le SCM a des informations beaucoup plus détaillées à suivre et peut faire un meilleur travail de résolution des conflits en toute sécurité et automatiquement.

Et puis il y a de beaux détails qui rendent les choses encore plus faciles:

  • Vous pouvez avoir plusieurs têtes et toujours commettre l'un ou l'autre; Contrairement à Subversion, vous n'avez pas besoin de combiner tirer, mettre à jour et fusionner avant de vous engager - les multiples têtes restent de cette façon jusqu'à ce que vous choisissiez de fusionner
  • Les répertoires ne sont pas traités spécialement; Au lieu de cela, le chemin est juste considéré comme un grand nom de fichier, et tous vos annuaires doivent être à la même révision à tout moment. Cela signifie que vous ne pouvez pas faire le Subversion Voodoo où les sous-dossiers d'un projet sont à différentes révisions, mais cela signifie également que la copie de travail est moins susceptible de devenir un énorme désordre brisé non gêné, et plus de manière intéressante, un geste n'est pas représenté comme une suppression. -et-ajoutez (ce qui serait entièrement en svn s'il n'était pas pour les métadonnées de modernisation), mais simplement comme renommée; Si vous déplacez un fichier, toute l'historique est préservé; La fusion peut même appliquer des modifications apportées au fichier déplacé apporté à une version non déplacée du même fichier après le déplacement, dans une autre branche
  • La plupart du temps, vous n'avez même pas besoin BESOIN à la branche: au lieu de cela, vous venez de cloner tout le référentiel. Le clonage est bon marché, surtout si cela est fait sur le même système de fichiers, et si vous décidez que vous souhaitez vous débarrasser du clone, vous supprimez simplement le répertoire qu'il vit et c'est ça. Vous n'avez même pas besoin d'utiliser HG ou Git pour cela.
  • Il y a peu (le cas échéant) des restrictions sur ce que vous pouvez fusionner. Vous pouvez avoir six clones du même référentiel et fusionnez (ou plutôt, poussez ou tirez; une fusion explicite n'est souvent pas requise) de A à B, puis C à B, puis B à D, puis c à D, puis c à d à un, D à E, à tout moment et aussi souvent que vous le souhaitez.
  • Vous pouvez tester une fusion en clonant l'un des référentiels que vous souhaitez fusionner, puis retirez-le de l'autre. Si cela fait ce que vous voulez, vous pouvez repousser la cible réelle, si ce n'est le cas, vous jetez le clone et recommencez à nouveau.
6
tdammers