La fonction de base d'un système de contrôle de version est d'autoriser l'édition collaborative et le partage de données. Mais les différents systèmes utilisent des stratégies différentes pour y parvenir.
Tous les systèmes de contrôle de version ont à résoudre les mêmes problèmes fondamentaux : Comment faire pour que le système autorise les utilisateurs à partager de l'information, mais empêcher qu'ils n'empiètent accidentellement sur les autres utilisateurs ? Il est tellement facile pour un utilisateur de réécrire accidentellement sur un fichier qu'un autre utilisateur a modifié dans le dépôt.
Considérons le scénario illustré dans la Figure 2.2, “Le problème à supprimer”. Nous supposons que nous avons deux collaborateurs, Harry et Sally. Ils décident de modifier le même fichier du même dépôt au même moment. Si Harry sauve ses changements dans le dépôt le premier, alors il est possible que (un peu plus tard), Sally réécrive accidentellement le fichier avec ses propres modifications, et sa propre version. Bien que les modifications de Harry ne soient pas perdues à jamais (parce que le système se souvient de tous les changements), celles-ci ne sont pas dans la version du fichier de Sally, qui est la plus récente, parce qu'elle n'a jamais eu les changements effectués par Harry. Le travail de Harry est donc effectivement perdu, ou au moins manquant, dans la nouvelle version du fichier, et probablement par accident (ce n'était pas la volonté de Sally). Ceci est une situation que nous voulons à tout prix éviter.
Un nombre important de systèmes de contrôle de version utilisent le modèle Verrouiller-Modifier-Libérer pour répondre à ce problème. Dans ce système, le dépôt autorise seulement une personne à la fois à travailler sur un fichier donné. Lors du début de son travail, Harry doit “verrouiller” le fichier avant de pouvoir faire des modifications sur ce dernier. Verrouiller un fichier est comme prendre un livre dans une bibliothèque ; si Harry a verrouillé le fichier, alors Sally ne pourra pas effectuer de changement sur celui-ci. Si elle essaie de verrouiller à son tour le fichier, le dépôt le lui interdira. Tout ce qu'elle sera autorisée à faire sera la lecture du fichier, elle sera obligée d'attendre que Harry finisse ses changements et libère son verrou. Après que ce dernier a libéré le fichier, son tour est fini, et Sally peut désormais verrouiller le fichier et travailler dessus. La Figure 2.3, “Le modèle Verrouiller-Modifier-Libérer” est un exemple de cette solution simple.
Le problème avec le système de Verrouiller-Modifier-Libérer est qu'il est un peu restrictif, et peut devenir un problème pour les utilisateurs et la productivité :
Verrouiller peut provoquer des problèmes administratifs. Parfois, Harry va verrouiller un fichier, et ensuite l'oublier. Ainsi, Sally doit attendre pour l'éditer, et va prendre du retard. Imaginons que Harry parte en vacances. Maintenant, Sally doit demander à un administrateur de libérer le verrou de Harry. Cette situation est la cause de beaucoup de retard et de temps perdu.
Verrouiller interdit le travail en parallèle. Que faire si Harry veut modifier le début du fichier, et Sally veut simplement éditer la fin du même fichier ? Aucun changement ne se chevauche. Ils pourraient facilement éditer le fichier simultanément, sans que cela ne pose problème, et ensuite fusionner les deux modifications. Il n'y a aucune solution à ce cas, et ils doivent alors attendre leur tour.
Verrouiller peut créer un faux sentiment de sécurité. Imaginons que Harry verrouille et édite le fichier A, pendant que Sally verrouille et modifie le fichier B. Maintenant, supposons que le fichier A et B dépendent l'un de l'autre et que les changements effectués sur chacun soient incompatibles. Dans ce cas, A et B ne fonctionneront plus ensemble. Le système de réservation est impuissant face aux différents problèmes de sens qui peuvent survenir, et provoque donc un faux sentiment de sécurité. Il est facile pour Harry et Sally de penser que, parce qu'ils ont verrouillé leurs fichiers, tout s'est fait de manière sécurisée et propre, et n'ont ainsi pas pensé à se consulter avant d'effectuer les changements qui brisent la compatibilité.
Subversion, CVS, et d'autres outils de contrôle de version utilisent un modèle de Copier-Modifier-Fusionner comme alternative à la réservation. Dans ce modèle, les clients des utilisateurs contactent le dépôt du projet, et créent une copie de travail personnelle, qui est une réplication locale de la structure et des fichiers du dépôt. Les utilisateurs peuvent ainsi travailler en parallèle, en modifiant directement et uniquement leur copie privée. Ensuite, les copies privées sont fusionnées ensemble en une nouvelle version finale. Le système de contrôle de version permet ensuite d'assister les utilisateurs dans la fusion des documents, mais le contrôle final est laissé à l'humain, qui est alors responsable des modifications et de leur intégrité. Il doit donc vérifier que tout se passe correctement.
Voici un exemple. Harry et Sally créent chacun leur copie de travail du même projet, récupérée depuis le dépôt. Ils travaillent en parallèle, et effectuent des modifications sur les mêmes fichiers. Sally sauvegarde ses changements dans le dépôt la première (fusion). Lorsque Harry tentera de sauvegarder ses propres changements, le dépôt l'informera que le fichier A n'est pas à jour (out-of-date). En d'autre termes, le fichier A situé dans le dépôt a été modifié depuis sa dernière copie par Harry. Alors Harry demande au client de fusionner dans sa copie de travail tous les changements du fichier situé dans le dépôt avec son propre fichier nouvellement édité. Il y a des chances pour que les modifications ne se recouvrent pas, alors une fois la fusion effectuée, il peut sauvegarder la nouvelle version fusionnée de sa copie de travail dans le dépôt. Les Figure 2.4, “La solution du Copier-Modifier-Fusionner” et Figure 2.5, “La solution du Copier-Modifier-Fusionner (suite)” montrent le processus de ce modèle.
Mais que se passe-t-il si les changements chevauchent les changements de Harry ? Alors ? Cette situation est nommée conflit, et ce n'est généralement pas un problème. Lorsque Harry demande à son client de fusionner son répertoire de travail avec les dernières modifications du dépôt, son fichier est étiqueté comme étant en un état de conflit : il lui sera alors possible de voir où se situe le conflit et les changements concernés. Il pourra ainsi choisir manuellement la solution la plus adaptée. Il faut bien garder à l'esprit qu'un logiciel ne peut pas résoudre un conflit automatiquement ; seul un humain est capable de comprendre le sens, et faire le bon choix en toute intelligence. Une fois que Harry a résolu le problème de chevauchement des modifications, sans doute après une discussion avec Sally, il peut de manière sécurisée sauvegarder le fichier fusionné dans le dépôt.
Le modèle Copier-Modifier-Fusionner peut sembler un brin chaotique, mais en pratique, cela fonctionne extrêmement bien. Les utilisateurs peuvent travailler en parallèle, sans jamais attendre après quelqu'un d'autre. Lorsqu'ils travaillent sur les mêmes fichiers, la plupart du temps, les modifications concernent rarement les mêmes endroits, et entrent rarement en conflit. Et encore, le travail pour résoudre les conflits est nettement moins contraignant et problématique que la perte du travail ou l'attente causée par un système de verrou
Enfin, il reste un facteur critique dans ce système, la communication entre les utilisateurs. Lorsque les utilisateurs communiquent peu, des erreurs syntactiques aussi bien que sémantiques peuvent survenir de manière importante. Aucun système ne peut forcer les utilisateurs à bien communiquer entre eux, et aucun système ne peut détecter des erreurs de sémantique. Il n'y a aucun moyen de contrôle de conflit dans un même fichier comme peu le faire un système de verrous, mais il apparaît que les verrous limitent plus la productivité qu'autre chose.