Duplicata possible:
je suis un geek de Subversion, pourquoi devrais-je considérer ou non Mercurial ou Git ou tout autre DVCS?
De temps en temps, vous entendez quelqu'un dire que le contrôle de version distribué (Git, HG) est intrinsèquement meilleur que le contrôle de version centralisé (comme SVN) car la fusion est difficile et douloureuse dans SVN. Le fait est que je n'ai jamais eu de problème avec la fusion dans SVN, et puisque vous n'entendez que cette affirmation faite par les défenseurs de DVCS, et non par les utilisateurs réels de SVN, cela a tendance à me rappeler ces publicités odieuses à la télévision où elles essayez de vous vendre quelque chose dont vous n'avez pas besoin en faisant croire aux acteurs maladroits que la chose que vous avez déjà et qui fonctionne très bien est incroyablement difficile à utiliser.
Et le cas d'utilisation qui est invoqué invariablement est la fusion d'une succursale, ce qui me rappelle encore ces publicités de produits de paille; si vous savez ce que vous faites, vous ne devriez pas (et ne devriez jamais devoir) refusionner une branche en premier lieu. (Bien sûr, c'est difficile à faire quand vous faites quelque chose de fondamentalement mauvais et idiot!)
Donc, en excluant le cas d'utilisation ridicule de l'homme de paille, qu'y a-t-il dans la fusion SVN qui est intrinsèquement plus difficile que la fusion dans un système DVCS?
Réponses:
C'est parce que svn n'avait pas les structures de données appropriées pour déterminer avec précision le dernier ancêtre commun des deux branches. Ce n'est pas un gros problème pour une branche qui n'est fusionnée qu'une seule fois, mais peut provoquer de nombreux conflits de fusion erronés dans des situations où plusieurs branches sont fusionnées plusieurs fois.
Je ne suis pas très proche de svn, mais je crois comprendre que ces problèmes techniques particuliers ont été corrigés dans les versions récentes. Cependant, il n'a pas été corrigé assez tôt pour dissiper le mythe, et les personnes qui ont essayé le DVCS pour les fusions sont restées avec lui pour d'autres raisons.
la source
Et c'est là que réside la source de votre confusion et de tout le problème en général.
Vous dites que la fusion de succursales est "fondamentalement mauvaise et idiote". Eh bien, c'est exactement le problème: vous pensez aux branches comme des choses qui ne devraient pas être fusionnées. Pourquoi? Parce que vous êtes un utilisateur SVN qui sait que la fusion des branches est difficile . Par conséquent, vous ne le faites jamais et vous encouragez les autres à ne pas le faire. Vous avez été formé pour éviter la fusion; vous avez développé des techniques que vous utilisez pour éviter la fusion.
Je suis un utilisateur Mercurial. Même sur mes propres projets, dont je suis le seul développeur, je fusionne tout le temps les succursales . J'ai une branche de publication, dans laquelle j'ai mis un correctif. Eh bien, je fusionne cela dans la ligne principale pour que le correctif y soit.
Si j'utilisais SVN, j'adopterais une structure complètement différente de la base de code. Pourquoi? Parce que SVN rend les fusions difficiles, et donc vous développez des idiomes et des techniques pour éviter de faire des fusions complexes.
Les DVCS facilitent les fusions complexes car elles sont l' état par défaut . Tout est une branche, plus ou moins, dans un DVCS. Ainsi, la structure entière d'entre eux est construite à partir de zéro pour faciliter la fusion. Cela vous permet de développer un flux de travail qui utilise la fusion au quotidien, plutôt que le flux de travail SVN où vous n'utilisez jamais la fusion.
Le simple fait est le suivant: vous devez aborder un DVCS d'une manière différente de SVN. Vous devez utiliser les idiomes appropriés pour ces types très différents de systèmes de contrôle de version. Dans SVN, vous adoptez des idiomes qui n'impliquent pas de fusion car les fusions sont difficiles. Dans DVCS, vous adoptez des idiomes qui utilisent fréquemment des fusions car ils ne sont pas un gros problème.
Le bon outil pour le bon travail.
Le truc, c'est que le flux de travail axé sur la fusion est beaucoup plus agréable et plus facile à utiliser que le flux de travail de style SVN où vous ne fusionnez pas les choses. Il est plus facile de voir quand quelque chose de la branche release a été introduit dans la branche dev. Il est plus facile de voir les différentes interactions entre les branches. Il est facile de créer des branches de test pour des choses, puis de les couper si le test ne fonctionne pas. Etc.
Vraiment, Joel explique cela beaucoup mieux que moi . Vous devriez en avoir une bonne lecture.
la source
Il n'y a rien de trop difficile à fusionner SVN ... plus ... si vous suivez la bonne philosophie
Ce que je vois dans la plupart des autres réponses semble provenir de personnes qui n'ont pas utilisé SVN depuis un certain temps. Comme quelqu'un le mentionne avec précision: "il n'a pas été corrigé assez tôt pour dissiper le mythe".
D'après mon expérience actuelle de l'utilisation de SVN 1.6 à 1.8 sur un projet hérité dont j'ai hérité récemment, SVN a fait un long chemin pour rendre la fusion beaucoup plus facile. Ce n'est pas infaillible, cependant, et je pense que les utilisateurs ne s'écartent pas facilement de l'utilisation prévue.
Alors que je connaissais assez bien SVN et que j'avais également essayé Mercurial pour des projets personnels entre-temps, je n'avais jamais fait beaucoup de branchements dans SVN avant ce projet. Il y a eu pas mal d'essais et d'erreurs et j'ai eu beaucoup de conflits de fusion inattendus quand j'ai commencé.
En fin de compte, cependant, je me suis rendu compte que chaque fois que j'en obtenais un (ou un autre problème), c'était parce que je n'avais pas fait les choses correctement (alias "la manière SVN" - sans doute, la bonne façon de contrôler la version). Je pense que c'est là que réside la difficulté: vous ne pouvez pas faire ce que vous voulez de manière non organisée et vous attendre à ce que SVN fonctionne parfaitement, en particulier avec les fusions. Les fusions nécessitent une discipline rigoureuse de la part des utilisateurs avant de montrer leur véritable pouvoir.
Voici des choses que j'ai remarquées comme de fortes recommandations, sinon des exigences, pour une utilisation propre des fusions:
Si vous ne suivez pas ce qui précède, vous risquez probablement de rencontrer des conflits. Ils sont toujours solubles, mais pas très amusants à passer du temps.
Oh, encore une chose à propos de la fusion où, de tout ce que j'ai lu et essayé, SVN est vraiment nul: fichiers / dossiers supprimés / déplacés / renommés. Apparemment , SVN ne peut toujours pas traiter un fichier renommé, supprimé ou déplacé dans une branche, et sa version d'origine modifiée dans une autre branche ... puis les fusionner. Il ne saura simplement pas où le fichier est allé dans un sens et "oubliera" les changements dans l'autre sens. Une modification est évidemment insoluble (vous supprimez ou modifiez le fichier, vous ne pouvez pas faire les deux), mais l'application des modifications aux fichiers déplacés / renommés devrait fonctionner et ce n'est pas le cas. Espérons que cela sera bientôt corrigé.
Donc, dans l'ensemble, la fusion de SVN est-elle facile? Je suppose que non. Pas de manière insouciante, c'est sûr. C'est mauvais ? Je ne pense pas. Il ne crache en arrière dans votre visage que lorsque vous l'utilisez mal et que vous ne pensez pas assez à ce que vous faites.
Sur cette base, je peux voir pourquoi les gens pourraient préférer Mercurial (par exemple) car il est un peu plus indulgent à propos de ces choses de mon expérience et a tout automatisé dès le départ (au moins à partir des premières versions avec lesquelles j'ai commencé). SVN a rattrapé un peu de retard, cependant, ce n'est plus digne d'être autant critiqué.
la source
Les modèles de données internes sont fondamentalement différents.
Fondamentalement, dans SVN, lorsque vous regardez l'historique d'une branche, vous ne voyez que ce qui s'est passé dans cette branche. Ainsi, lorsque vous fusionnez de branche
B
en brancheA
, l'historique de brancheA
contiendra une grande validation contenant toutes les modifications apportées explicitementB
depuis qu'elle a été branchée.Dans les premières versions de SVN, si vous deviez fusionner une branche
B
en brancheA
une fois de plus, vous deviez spécifier manuellement la plage de révision de la branche queB
vous vouliez fusionner afin d'éviter de fusionner deux fois les mêmes révisions. Le développeur intelligent utiliserait bien sûr un message de validation comme «Fusionné dans B: 1234».SVN 1.5 "corrige" cela. Mais cela n'a pas changé la façon dont les fusions sont appliquées fondamentalement. Il a simplement ajouté des métadonnées supplémentaires à la branche
A
, permettant à SVN de savoir que la révision 1234 avait été fusionnée, permettant à SVN de choisir automatiquement la plage de révision correcte.Mais cette solution est essentiellement une solution de contournement pour un modèle de données qui, fondamentalement, ne prend pas en charge le suivi de ce qui a été fusionné.
La fusion de deux branches est un exemple relativement simple. Mais imaginer ce scénario plus complexe
A
partir detrunk
et faites quelques commits iciB
partir deA
et faites quelques commits icitrunk
etA
B
danstrunk
A
dansB
A
danstrunk
B
danstrunk
(cela ne devrait pas faire quoi que ce soit)Le gérer correctement à l'aide du modèle de métadonnées devient extrêmement complexe (je ne sais pas si SVN gère effectivement ce scénario correctement, et je ne me sens pas enclin à le tester).
La gestion de ce scénario dans git est extrêmement simple.
Dans git, chaque fois que vous validez, l'objet interne représentant cette validation contient une référence à la tête précédente. Lorsque vous fusionnez dans une branche, la validation contient des références à la tête précédente de toutes les branches fusionnées (vous pouvez fusionner plusieurs branches à la fois dans git)
Par conséquent, lorsque vous examinez l'historique d'un seul commit dans git, vous pouvez voir tout l'historique, vous pouvez voir quand il a été ramifié, quand il a été fusionné, et vous pouvez voir l'historique des deux branches entre la branche et la fusion.
Ainsi, lors de la fusion dans une branche qui a été partiellement fusionnée, il est extrêmement simple de déterminer ce qui a déjà été fusionné et ce qui ne l'a pas déjà été.
Je n'ai aucune expérience avec Mercurial, mais je soupçonne que son fonctionnement interne est similaire à Git.
Donc, fondamentalement, pour SVN, c'était un objectif de conception de rendre la branche bon marché. Mais dans git, c'était un objectif de conception de rendre la fusion bon marché.
Enfin, la dernière fois que j'ai utilisé SVN, il n'a pas pu gérer les fusions, où un fichier a été renommé dans une branche et modifié dans une autre.
la source
J'ai fait un peu de fusion de SVN - y compris des branches de développement et de publication de longue durée. Dans l'ensemble, j'ai survécu. La fusion est toujours délicate, mais avec DCVS, l'inconvénient n'est pas horriblement mauvais - tout est local, alors mettez à jour une bonne révision connue et continuez. Alors qu'avec SVN, beaucoup de choses se passaient du côté serveur, donc la récupération était moche - généralement cela impliquait d'effacer la copie locale puis de vérifier une nouvelle branche propre pour l'essayer à nouveau. Ce n'était pas mal dans mon cas - une connexion gigabit à la boîte SVN aide. Mais nous avons eu certains entrepreneurs qui ont eu beaucoup de problèmes avec cela car ils étaient sur des connexions lentes, donc tout a pris une éternité, y compris les fusions.
la source
Ici se trouve l'une des très belles choses sur git. Ce n'est pas hérité du DVCS, c'est juste quelque chose d'excitant. Vous pouvez fusionner des révisions spécifiques de n'importe quelle branche dans une autre branche. Il prend simplement le diff et l'applique à l'autre branche, mais fait le suivi et est beaucoup plus automatique.
Donc, si vous avez la branche 2.0 et la branche 3.0 et découvrez un bogue dans 2.0, vous pouvez le corriger dans 2.0 et prendre l'ensemble des révisions qui le résolvent et fusionner uniquement ces révisions dans la branche 3.0. Je ne pense pas que SVN ait d'autre moyen que de prendre manuellement les différences pour chaque révision et de les appliquer
Bien sûr, l'algorithme de fusion automatique semble également fonctionner beaucoup plus facilement et git a été construit à partir du sol sur le modèle "créer une branche pour toutes choses", donc la ramification est vraiment très simple et facile. Il semble naturel de se ramifier souvent avec la légèreté de ses branches
la source