Tous les systèmes de contrôle de version doivent résoudre le même problème fondamental : comment le système va-t-il permettre aux utilisateurs de partager l'information, mais les empêcher de se marcher accidentellement sur les pieds ? Il n'est que trop facile pour les utilisateurs d'écraser accidentellement les modifications des autres sur le dépôt.
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 dépôt en même temps. Si Harry sauvegarde ses changements sur le dépôt en premier, il est possible qu'ensuite (quelques moments plus tard) Sally puisse accidentellement les écraser avec sa propre nouvelle version du fichier. Même si la version d'Harry du fichier ne sera pas perdue pour toujours (parce que le système se rappelle de 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 en premier lieu. Le travail d'Harry est quand même de facto perdu — ou du moins absent de la dernière version du fichier — et probablement par accident. C'est clairement une situation que nous voulons éviter !
Beaucoup de systèmes de contrôle de version utilisent le modèle verrouiller-modifier-déverrouiller pour aborder ce problème, qui est une solution très simple. Dans un tel système, le dépôt ne permet qu'à une seule personne à la foid de modifier un fichier. Tout d'abord, Harry doit verrouiller le fichier avant qu'il ne puisse commencer à y faire des changements. Le verrouillage d'un fichier s'apparente à l'emprunt d'un livre dans une bibliothèque ; si Harry a verrouillé un fichier, alors Sally ne peut pas le modifier. Si elle essaye de verrouiller le fichier, le dépôt refusera la requête. Tout qu'elle peut faire est lire le fichier et attendre qu'Harry finisse ses changements et relâche le verrou. Dès qu'Harry déverrouille le fichier, son tour est fini, et Sally peut alors à son tour le verrouiller et y apporter ses modifications.
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, elle est bloquée. Et ensuite Harry part en vacances. Maintenant Sally doit appeler un administrateur pour relâcher le verrou d'Harry. La situation finit par causer beaucoup de retard inutile et de temps perdu.
Le verrouillage peut causer une sérialisation inutile. Que se passe-t-il si Harry édite le début d'un fichier texte, et que 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 rien de bien grave n'arriverait, à supposer que les changements aient été correctement fusionnés ensemble. Ils n'ont aucun besoin d'attendre chacun 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 que les changements faits à chacun soient sémantiquement incompatibles. Soudain, A et B ne fonctionnent plus ensemble. Le système de verrouillage n'a pas pu empêcher le problème - pourtant il a fourni d'une certaine façon 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 et isolée, et ainsi cela ne les incite pas à discuter dès le début de leurs modifications incompatibles.
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 dépôt 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.
Voici un exemple. Disons qu'Harry et Sally ont chacun une copie de travail du même projet, extrait du dépôt. Ils travaillent en même temps et modifient localement le même fichier A
. Sally sauvegarde ses changements dans le dépôt d'abord. Quand Harry essaie de sauvegarder ses changements, le dépôt l'informe que son fichier A est périmé. Autrement dit, dans le dépôt, ce fichier A a été modifié depuis qu'il a été extrait. Donc Harry demande à son client de fusionner les nouveaux changements du fichier A du dépôt avec sa copie de travail. Il y a des chances que les changements de Sally ne se chevauchent pas avec les siens ; ainsi une fois qu'il a les deux changements intégrés, il sauvegarde sa copie de travail sur le dépôt.
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 dépôt 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 dépôt.
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 dépôt 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.