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 branche A
, l'historique de branche A
contiendra une grande validation contenant toutes les modifications apportées explicitement B
depuis qu'elle a été branchée.
Dans les premières versions de SVN, si vous deviez fusionner une branche B
en branche A
une fois de plus, vous deviez spécifier manuellement la plage de révision de la branche que B
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
- Créez une branche à
A
partir de trunk
et faites quelques commits ici
- Créez une branche à
B
partir de A
et faites quelques commits ici
- Faites quelques commits
trunk
etA
- Fusionner
B
danstrunk
- Fusionner
A
dansB
- Fusionner
A
danstrunk
- Fusionner
B
dans trunk
(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.