The core mission of a version control system is to enable collaborative editing and sharing of data. But different systems use different strategies to achieve this.
La missione principale di un sistema di controllo di versione è abilitare la modifica collaborativa e la condivisione dei dati. In realtà sistemi differenti usano strategie differenti per ottenerlo.
All version control systems have to solve the same fundamental problem: how will the system allow users to share information, but prevent them from accidentally stepping on each other's feet? It's all too easy for users to accidentally overwrite each other's changes in the repository.
Tutti i sistemi per il controllo di versione devono risolvere lo stesso problema fondamentale: come farà il sistema a permettere agli utenti di condividere le informazioni, evitando al contempo che questi possano accidentalmente interferire fra loro? È troppo semplice infatti per gli utenti sovrascrivere accidentalmente le modifiche degli altri nel repository.
Consider the scenario shown in Figura 2.2, «Il problema da evitare». Suppose we have two co-workers, Harry and Sally. They each decide to edit the same repository file at the same time. If Harry saves his changes to the repository first, then it's possible that (a few moments later) Sally could accidentally overwrite them with her own new version of the file. While Harry's version of the file won't be lost forever (because the system remembers every change), any changes Harry made won't be present in Sally's newer version of the file, because she never saw Harry's changes to begin with. Harry's work is still effectively lost—or at least missing from the latest version of the file—and probably by accident. This is definitely a situation we want to avoid!
Si consideri lo scenario illustrato in Figura 2.2, «Il problema da evitare». Supponiamo di avere 2 collaboratori, che chiameremo Hally e Sally. Entrambi decidono di modificare lo stesso file del repository nello stesso momento. Se Harry salva le sue modifiche nel repository per primo, è possibile che (qualche istante dopo) Sally possa accidentalmente sovrascriverle con la propria versione aggiornata del file. Mentre la versione di Harry del file non verrà persa per sempre (perché il sistema ricorda ogni cambiamento), qualsiasi cambiamento apportato da Harry non sarà presente nella nuova versione del file di Sally, perché lei non ha mai ricevuto le modifiche di Harry da cui poter continuare. Il lavoro di Harry è effettivamente perso—o quantomeno mancante dall'ultima versione del file—e probabilmente accidentalmente. Questa è sicuramente la situazione che si vuole evitare.
Many version control systems use a lock-modify-unlock model to address the problem of many authors clobbering each other's work. In this model, the repository allows only one person to change a file at a time. This exclusivity policy is managed using locks. Harry must “lock” a file before he can begin making changes to it. If Harry has locked a file, then Sally cannot also lock it, and therefore cannot make any changes to that file. 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, Sally can take her turn by locking and editing the file. Figura 2.3, «La soluzione blocca-modifica-sblocca» demonstrates this simple solution.
Molti sistemi per il controllo di versione usano un modello blocca-modifica-sblocca per trattare il potenziale problema di più autori che compromettono il proprio lavoro. In questo modello, il repository permette solo ad una persona alla volta di modificare un file. Questa politica di esclusione è gestita attraverso dei blocchi (lock). Harry deve «bloccare» un file prima di apportare modifiche allo stesso. Se Harry ha bloccato il file, Sally non potrà a sua volta bloccarlo, e quindi non potrà apportare modifiche allo stesso. Tutto quello che può fare è leggere il file ed aspettare che Harry abbia finito le sue modifiche e rilasci il suo blocco. Dopo che Harry avrà sbloccato il file, Sally potrà prendere il suo turno bloccando e modificando il file. Figura 2.3, «La soluzione blocca-modifica-sblocca» dimostra questa semplice soluzione.
The problem with the lock-modify-unlock model is that it's a bit restrictive, and often becomes a roadblock for users:
Il problema con il modello blocca-modifica-sblocca è che risulta un po' restrittivo, e spesso diventa come un ostacolo per gli utenti:
Locking may cause administrative problems. Sometimes Harry will lock a file and then forget about it. Meanwhile, because Sally is still waiting to edit the file, her hands are tied. And then Harry goes on vacation. Now Sally has to get an administrator to release Harry's lock. The situation ends up causing a lot of unnecessary delay and wasted time.
Il blocco potrebbe creare problemi di natura amministrativa. A volte Harry si scorda di aver bloccato un file. Nel frattempo Sally, poiché sta aspettando di modificare il file, avrà le mani legate. Se in seguito Harry andrà in ferie, Sally si troverà costretta a contattare un amministratore per far rilasciare il blocco di Harry. La situazione si conclude con un notevole ritardo e tempo sprecato.
Locking may cause unnecessary serialization. What if Harry is editing the beginning of a text file, and Sally simply wants to edit the end of the same file? These changes don't overlap at all. They could easily edit the file simultaneously, and no great harm would come, assuming the changes were properly merged together. There's no need for them to take turns in this situation.
Il blocco potrebbe creare inutili serializzazioni. Cosa accade se Harry sta modificando l'inizio di un file di testo, mentre Sally vuole semplicemente modificare la parte finale dello stesso file? Questi cambiamenti non si sovrappongono in nessun modo. Loro potrebbero modificare il file simultaneamente, senza creare nessun danno, assumendo che i cambiamenti vengano propriamente fusi. Non c'è necessità per loro di prendere un turno in questa situazione.
Locking may create a false sense of security. Pretend that Harry locks and edits file A, while Sally simultaneously locks and edits file B. But suppose that A and B depend on one another, and the changes made to each are semantically incompatible. Suddenly A and B don't work together anymore. The locking system was powerless to prevent the problem—yet it somehow provided a false sense of security. It's easy for Harry and Sally to imagine that by locking files, each is beginning a safe, insulated task, and thus not bother discussing their incompatible changes early on.
Il blocco potrebbe creare un falso senso di sicurezza. Supponiamo che Harry blocchi e modifichi un file A, e simultaneamente Sally blocchi e modifichi un file B. Ma supponiamo che A e B dipendano l'uno dall'altro, e che le modifiche apportate ad entrambi siano semanticamente incompatibili. Improvvisamente A e B non funzionano più correttamente insieme. La soluzione del blocco non è stata in grado di prevenire il problema—pertanto si riceve in qualche modo un falso senso di sicurezza. È facile per Harry e Sally immaginare che bloccando i file, ognuno stia iniziando una operazione sicura ed isolata, e di conseguenza non si preoccupano di discutere i propri cambiamenti incompatibili in anticipo.
Subversion, CVS, and other version control systems use a copy-modify-merge model as an alternative to locking. In this model, each user's client contacts the project repository and creates a personal working copy—a local reflection of the repository's files and directories. Users then work in parallel, modifying their private copies. Finally, the private copies are merged together into a new, final version. The version control system often assists with the merging, but ultimately a human being is responsible for making it happen correctly.
Subversion, CVS, ed altri sistemi per il controllo di versione usano il modello copia-modifica-fondi come alternativa al blocco. In questo modello, il client di ogni utente comunica con il repository e crea la propria copia di lavoro—una riproduzione dei file e delle directory del repository. Gli utenti possono poi lavorare in parallelo, modificando le proprie copie private. Infine, le copie private vengono fuse in una nuova versione finale. Spesso il sistema per il controllo di versione assiste nella fase di integrazione, ma alla fine è un essere umano il responsabile di fare in modo che questa si compia correttamente.
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. Figura 2.4, «La soluzione copia-modifica-fondi» and Figura 2.5, «La soluzione copia-modifica-fondi (continua)» show this process.
Ecco un esempio. Supponiamo che Harry e Sally creino una copia locale dello stesso progetto, copiata dallo stesso repository. Loro lavorano concorrentemente, ed apportano modifiche allo stesso file A all'interno delle loro copie. Sally salva le proprie modifiche per prima sul repository. Quando Harry prova successivamente a salvare i propri cambiamenti, il repository lo informa che il suo file A è obsoleto. In altre parole, questo file A è cambiato nel repository rispetto all'ultima volta che lui lo ha copiato. Quindi Harry chiede al repository di fondere ogni nuovo cambiamento dal repository alla sua copia locale del file A. Con buona probabilità i cambiamenti di Sally non si sovrappongono con i suoi; quindi una volta che ha integrato entrambi gli insiemi di cambiamenti, salva la sua copia di lavoro nel repository. Figura 2.4, «La soluzione copia-modifica-fondi» e Figura 2.5, «La soluzione copia-modifica-fondi (continua)» mostrano questo processo.
But what if Sally's changes do overlap with Harry's changes? What then? This situation is called a conflict, and it's usually not much of a problem. When Harry asks his client to merge the latest repository changes into his working copy, his copy of file A is somehow flagged as being in a state of conflict: he'll be able to see both sets of conflicting changes, and manually choose between them. Note that software can't automatically resolve conflicts; only humans are capable of understanding and making the necessary intelligent choices. Once Harry has manually resolved the overlapping changes—perhaps after a discussion with Sally—he can safely save the merged file back to the repository.
Cosa accade se le modifiche di Sally di fatto si sovrappongono a quelle di Harry? Che comporta? Questa situazione è chiamataconflitto, ed in generale non è un grande problema. Quando Harry chiede al proprio client di fondere le ultime modifiche del repository nella sua copia di lavoro, la propria copia del file A è in qualche modo etichettata come in uno stato di conflitto: lui sarà in grado di vedere entrambi gli insiemi di cambiamenti e scegliere manualmente tra questi. Da notare che il software non può risolvere il conflitto automaticamente; solo gli uomini sono capaci di capire e fare le necessarie scelte intelligenti. Una volta che Harry ha risolto manualmente i cambiamenti sovrapposti— probabilmente dopo una discussione con Sally— può salvare in maniera sicura il file integrato nel repository.
The copy-modify-merge model may sound a bit chaotic, but in practice, it runs extremely smoothly. Users can work in parallel, never waiting for one another. When they work on the same files, it turns out that most of their concurrent changes don't overlap at all; conflicts are infrequent. And the amount of time it takes to resolve conflicts is far less than the time lost by a locking system.
Il modello copia-modifica-fondi può sembrare un po' caotico, ma nella pratica funziona senza difficoltà. L'utente può lavorare in parallelo, senza mai dover aspettare gli altri. Quando gli utenti lavorano sullo stesso file, accade frequentemente che la maggior parte delle modifiche concorrenti non si sovrappongano; i conflitti sono infatti rari. La quantità di tempo necessario per risolvere i conflitti è decisamente inferiore a quella persa nell'uso di un sistema di blocchi.
In the end, it all comes down to one critical factor: user communication. When users communicate poorly, both syntactic and semantic conflicts increase. No system can force users to communicate perfectly, and no system can detect semantic conflicts. So there's no point in being lulled into a false promise that a locking system will somehow prevent conflicts; in practice, locking seems to inhibit productivity more than anything else.
Alla fine, tutto si riconduce ad un fattore critico: la comunicazione degli utenti. Quando la comunicazione è povera, sia i conflitti sintattici che semantici aumentano. Nessun sistema può forzare l'utente a comunicare perfettamente, e nessun sistema può scovare conflitti semantici. Non c'è quindi nessuna ragione per rimanere illusi dalla falsa promessa che il sistema a blocchi prevenga in qualche modo i conflitti; nella pratica, il blocco sembra più che altro limitare la produttività.