Tous les systèmes de contrôle de version doivent résoudre le même problème fondamental : comment le système permettra-t-il aux utilisateurs de partager l'information, mais les empêchera accidentellement de se marcher sur les pieds ? Il est trop facile pour les utilisateurs d'écraser accidentellement les changements de chacun sur le référentiel.
Considérons ce scénario : supposons que nous avons deux collaborateurs, Harry et Sally. Ils décident chacun d'éditer le même fichier du référentiel en même temps. Si Harry sauvegarde ses changements sur le référentiel d'abord, il est possible qu'ensuite (quelques moments plus tard) Sally puisse accidentellement les écraser avec sa propre nouvelle version du fichier. Tandis que la version d'Harry du fichier ne sera pas perdue pour toujours (parce que le système se rappelle chaque changement), les changements qu'Harry a fait ne seront pas dans la version plus récente du fichier de Sally, parce qu'elle n'a jamais vu les changements d'Harry pour commencer. Le travail d'Harry est effectivement encore perdu - ou du moins manquant de la dernière version du fichier - et probablement par accident. C'est certainement une situation que nous voulons éviter!
Many version control systems use a lock-modify-unlock model to address this problem, which is a very simple solution. In such a system, the repository allows only one person to change a file at a time. First Harry must lock the file before he can begin making changes to it. Locking a file is a lot like borrowing a book from the library; if Harry has locked a file, then Sally cannot make any changes to it. If she tries to lock the file, the repository will deny the request. All she can do is read the file, and wait for Harry to finish his changes and release his lock. After Harry unlocks the file, his turn is over, and now Sally can take her turn by locking and editing.
Le problème avec le modèle "verrouiller-modifier-déverrouiller" est qu'il est un peu restrictif et devient souvent un barrage pour les utilisateurs :
Le verrouillage peut causer des problèmes administratifs. Parfois Harry verrouillera un fichier et ensuite l'oubliera. En attendant, parce que Sally attend toujours pour éditer le fichier, ses mains sont liées. Et ensuite Harry va en vacances. Maintenant Sally doit appeler un administrateur pour relâcher le verrou d'Harry. La situation se finit en causant beaucoup de retard inutile et de temps gaspillé.
Le verrouillage peut causer une sérialisation inutile. Et si Harry édite le début d'un fichier texte et Sally veut simplement éditer la fin du même fichier ? Ces changements ne se chevauchent pas du tout. Ils pourraient facilement éditer le fichier simultanément et aucun grand mal n'arriverait, à supposer que les changements aient été correctement fusionnés ensemble. Ils n'ont aucun besoin de prendre leur tour dans cette situation.
Le verrouillage peut créer un faux sentiment de sécurité. Disons qu'Harry verrouille et édite le fichier A, tandis que Sally verrouille et édite le fichier B en même temps. Mais supposons qu'A et B dépendent l'un de l'autre et les changements faits à chacun sont sémantiquement incompatibles. Soudainement A et B ne marchent désormais plus ensemble. Le système de verrouillage était impuissant à empêcher le problème - encore il a fourni d'une façon ou d'une autre un sentiment de fausse sécurité. C'est facile pour Harry et Sally de s'imaginer qu'en verrouillant les fichiers, chacun commence une tâche sûre, isolée et les interdit ainsi de discuter de leurs changements incompatibles dès le début.
Subversion, CVS et les autres systèmes de contrôle de version utilisent un modèle copier-modifier-fusionner comme une alternative au verrouillage. Dans ce modèle, le client de chaque utilisateur lit le référentiel et crée une copie de travail personnelle du fichier ou du projet. Les utilisateurs travaillent alors en parallèle, modifiant leurs copies privées. Finalement, les copies privées sont fusionnées ensemble dans une version nouvelle, finale. Le système de contrôle de version aide souvent avec la fusion, mais en fin de compte un être humain est responsable pour qu'elle se produise correctement.
Here's an example. Say that Harry and Sally each create working copies of the same project, copied from the repository. They work concurrently, and make changes to the same file A within their copies. Sally saves her changes to the repository first. When Harry attempts to save his changes later, the repository informs him that his file A is out-of-date. In other words, that file A in the repository has somehow changed since he last copied it. So Harry asks his client to merge any new changes from the repository into his working copy of file A. Chances are that Sally's changes don't overlap with his own; so once he has both sets of changes integrated, he saves his working copy back to the repository.
Mais que se passe-t-il si les changements de Sally chevauchent les changements d'Harry ? Que se passe-t-il alors ? Cette situation est appelée un conflit et habituellement, ce n'est pas vraiment un problème. Quand Harry demande à son client de fusionner les derniers changements du référentiel vers sa copie de travail, sa copie du fichier A est marquée d'une façon ou d'une autre comme étant dans un état de conflit : il sera capable de voir les deux jeux de changements en conflit et choisira manuellement entre eux. Notez que le logiciel ne peut pas résoudre automatiquement les conflits ; seuls les êtres humains sont capables de comprendre et de faire les choix intelligents nécessaires. Une fois qu'Harry a manuellement résolu les changements se chevauchant (peut-être en discutant du conflit avec Sally !), il peut sans risque sauvegarder le fichier fusionné sur le référentiel.
Le modèle copier-modifier-fusionner peut sembler un peu chaotique, mais en pratique, il fonctionne de manière extrêmement fluide. Les utilisateurs peuvent travailler en parallèle, n'ayant jamais à s'attendre. Quand ils travaillent sur les mêmes fichiers, il s'avère que la plupart de leurs changements simultanés ne se chevauchent pas du tout ; les conflits sont peu fréquents. Et le temps que cela prend pour résoudre des conflits est moindre que le temps perdu par un système de verrouillage.
À la fin, tout cela se réduit à un facteur critique : la communication entre les utilisateurs. Quand les utilisateurs communiquent mal, les conflits tant syntaxiques que sémantiques augmentent. Aucun système ne peut forcer les utilisateurs à communiquer parfaitement et aucun système ne peut détecter les conflits sémantiques. Ainsi il n'y a aucune raison d'être apaisé par une fausse promesse qu'un système de verrouillage empêchera d'une façon ou d'une autre des conflits ; en pratique, le verrouillage semble inhiber la productivité plus qu'autre chose.
Il y a une situation commune où le modèle verrouiller-modifier-déverrouiller s'en sort mieux et c'est quand vous avez des fichiers qui ne sont pas fusionnables. Par exemple, si votre référentiel contient quelques images graphiques et deux personnes modifient une image en même temps, il n'y a aucun moyen de fusionner ces changements. Soit Harry, soit Sally perdra ses changements.
Subversion utilise la solution copier-modifier-fusionner par défaut et dans des nombreux cas c'est tout ce dont vous aurez jamais besoin. Cependant, à partir de la version 1.2, Subversion supporte aussi le verrouillage de fichier, si vous avez des fichiers non-fusionnables, ou si vous êtes simplement forcés à une politique de verrouillage par le management, Subversion fournira encore les fonctionnalités dont vous avez besoin.