It's time to move from the abstract to the concrete. In this section, we'll show real examples of Subversion being used.
È il momento di passare dall'astratto al concreto. In questa sezione, saranno mostrati esempi di uso reale di Subversion.
You've already read about working copies; now we'll demonstrate how the Subversion client creates and uses them.
Si è già letto a proposito delle copie di lavoro; adesso verrà mostrato come queste vengano create ed utilizzate dal client Subversion.
A Subversion working copy is an ordinary directory tree on your local system, containing a collection of files. You can edit these files however you wish, and if they're source code files, you can compile your program from them in the usual way. Your working copy is your own private work area: Subversion will never incorporate other people's changes, nor make your own changes available to others, until you explicitly tell it to do so. You can even have multiple working copies of the same project.
Una copia di lavoro di Subversion è un normale albero di directory sul proprio sistema locale, contenente un certo insieme di file. È possibile modificare questi file come si preferisce, e, se si tratta di file di codice sorgente, si può compilare il proprio programma esattamente nella maniera usuale. La copia di lavoro è la propria area personale di lavoro: Subversion non incorporerà mai le modifiche introdotte da altri, né renderà le proprie modifiche disponibili ad altri, fino a quando non verrà esplicitamente chiesto di farlo. È possibile perfino avere più di una copia di lavoro dello stesso progetto.
After you've made some changes to the files in your working copy and verified that they work properly, Subversion provides you with commands to “publish” your changes to the other people working with you on your project (by writing to the repository). If other people publish their own changes, Subversion provides you with commands to merge those changes into your working directory (by reading from the repository).
Dopo aver apportato le modifiche desiderate ai file nella propria copia di lavoro ed aver verificato che funzionino correttamente, Subversion mette a disposizione dei comandi per «pubblicare» le proprie modifiche verso le altre persone che lavorano sullo stesso progetto (scrivendo nel repository). Quando altre persone pubblicano le loro modifiche, Subversion permette di importarle nella propria directory di lavoro (leggendole dal repository).
A working copy also contains some extra files, created and
maintained by Subversion, to help it carry out these commands.
In particular, each directory in your working copy contains a
subdirectory named .svn
, also known as
the working copy administrative
directory. The files in each administrative
directory help Subversion recognize which files contain
unpublished changes, and which files are out-of-date with
respect to others' work.
Una copia di lavoro contiene anche dei file aggiuntivi, creati ed
aggiornati da Subversion, come supporto all'esecuzione dei comandi
di cui sopra. In particolare, ogni directory nella propria copia di
lavoro contiene una sottodirectory chiamata .svn
,
altrimenti nota come directory amministrativa
della copia di lavoro. I file presenti in ciascuna delle directory
amministrative aiutano Subversion a tenere traccia di quali file
contengono modifiche non pubblicate e quali file non sono aggiornati
rispetto al lavoro svolto da altri.
A typical Subversion repository often holds the files (or source code) for several projects; usually, each project is a subdirectory in the repository's filesystem tree. In this arrangement, a user's working copy will usually correspond to a particular subtree of the repository.
Un tipico repository di Subversion spesso contiene i file (o codice sorgente) di diversi progetti; di solito, ogni progetto è contenuto in una sottodirectory nell'albero del filesystem del repository. Seguendo questa disposizione, la copia di lavoro di un utente corrisponderà ad uno specifico sottoalbero del repository.
For example, suppose you have a repository that contains
two software projects, paint
and
calc
. Each project lives in its own
top-level subdirectory, as shown in Figura 2.6, «Il filesystem del repository».
Ad esempio, supponiamo di avere un repository che contenga due
progetti software, paint
e calc
.
Ciascun progetto vive nella sua personale sottodirectory al livello
più alto dell'albero del filesystem, come mostrato in Figura 2.6, «Il filesystem del repository».
To get a working copy, you must check
out some subtree of the repository. (The term
“check out” may sound like it has something to do
with locking or reserving resources, but it doesn't; it simply
creates a private copy of the project for you.) For example,
if you check out /calc
, you will get a
working copy like this:
Per ottenere una copia di lavoro, si deve anzitutto eseguire il
check out di un qualche sottoalbero del
repository. (Il termine «check out» potrebbe erroneamente
far pensare ad una azione di blocco o riserva delle risorse ma, in
realtà, crea semplicemente all'utente una copia di lavoro del progetto.)
Per esempio, se si effettua il check out di /calc
,
si otterrà una copia di lavoro con questa struttura:
$ svn checkout http://svn.example.com/repos/calc A calc/Makefile A calc/integer.c A calc/button.c Checked out revision 56. $ ls -A calc Makefile integer.c button.c .svn/
The list of letter A's indicates that Subversion is adding
a number of items to your working copy. You now have a
personal copy of the repository's /calc
directory, with one additional
entry—.svn
—which holds the
extra information needed by Subversion, as mentioned
earlier.
La lista di A indica che Subversion stia aggiungendo un certo
numero di elementi alla propria copia locale. Adesso quindi si ha una
copia personale della directory/calc
del
repository, con un elemento aggiuntivo
—.svn
—che contiene tutte quelle
extra informazioni menzionate in precedenza.
Suppose you make changes to button.c
.
Since the .svn
directory remembers the
file's modification date and original contents, Subversion can
tell that you've changed the file. However, Subversion does
not make your changes public until you explicitly tell it to.
The act of publishing your changes is more commonly known as
committing (or checking
in) changes to the repository.
Supponiamo di aver apportato modiche a button.c
.
Dato che la directory .svn
ricorda le date delle
modifiche ai file ed i contenuti originali, Subversion può notificare
che i file siano stati cambiati. Ad ogni modo, Subversion non rende
pubblici i propri cambiamenti fino a quando non verrà esplicitamente
richiesto. L'atto di pubblicazione dei propri cambiamenti è comunemente
conosciuta comecommit (o check
in) delle modifiche al repository.
To publish your changes to others, you can use Subversion's commit command:
Per pubblicare le proprie modifiche agli altri è possibile usare il comando di Subversion commit:
$ svn commit button.c Sending button.c Transmitting file data . Committed revision 57.
Now your changes to button.c
have
been committed to the repository; if another user checks out a
working copy of /calc
, they will see
your changes in the latest version of the file.
Adesso le modifiche a button.c
sono state
sottomesse al repository; se un altro utente effettua il check out di
una copia di lavoro di /calc
, vedrà i propri
cambiamenti nell'ultima versione del file.
Suppose you have a collaborator, Sally, who checked out a
working copy of /calc
at the same time
you did. When you commit your change to
button.c
, Sally's working copy is left
unchanged; Subversion only modifies working copies at the
user's request.
Supponiamo di avere un altro collaboratore, Sally, che ha effettuato
il check out della copia di lavoro di /calc
nello
stesso momento in cui è stata effettuata la nostra. Quando verranno
sottomesse le modifiche al filebutton.c
, la copia
di lavoro di Sally rimarrà inalterata; Subversion infatti modifica le
copie solamente alla richiesta dell'utente.
To bring her project up to date, Sally can ask Subversion to update her working copy, by using the Subversion update command. This will incorporate your changes into her working copy, as well as any others that have been committed since she checked it out.
Per attualizzare il proprio progetto, Sally può chiedere a Subversion di aggiornare la sua copia di lavoro, usando il comando di Subversion update. Questo incorporerà le nostre modifiche nella sua copia di lavoro, così come ogni altro cambiamento che è stato sottomesso da quando lei ha effettuato il check out.
$ pwd /home/sally/calc $ ls -A .svn/ Makefile integer.c button.c $ svn update U button.c Updated to revision 57.
The output from the svn update command
indicates that Subversion updated the contents of
button.c
. Note that Sally didn't need to
specify which files to update; Subversion uses the information
in the .svn
directory, and further
information in the repository, to decide which files need to
be brought up to date.
I risultati del comando svn update indicano che
Subversion ha aggiornato i contenuti di button.c
.
Si noti che Sally non ha dovuto specificare quali file aggiornare;
Subversion usa le informazioni nella directory .svn
,
ed informazioni aggiuntive nel repository, per decidere quali file hanno
bisogno di essere attualizzati.
An svn commit operation can publish changes to any number of files and directories as a single atomic transaction. In your working copy, you can change files' contents, create, delete, rename and copy files and directories, and then commit the complete set of changes as a unit.
Un comando svn commit può pubblicare i cambiamenti.
In the repository, each commit is treated as an atomic transaction: either all the commit's changes take place, or none of them take place. Subversion tries to retain this atomicity in the face of program crashes, system crashes, network problems, and other users' actions.
Nel repository, ogni commit viene trattata come una transazione atomica: vengono effettuate o tutte o nessuna delle modifiche. Subversion cerca di mantenere questa atomicità come precauzione verso i crash dei programmi, i crash dei sistemi, i problemi di rete ed altre azioni dell'utente.
Each time the repository accepts a commit, this creates a new state of the filesystem tree, called a revision. Each revision is assigned a unique natural number, one greater than the number of the previous revision. The initial revision of a freshly created repository is numbered zero, and consists of nothing but an empty root directory.
Ogni volta che il repository accetta una commit, questo crea un nuovo stato nell'albero del filesystem, che viene chiamato revisione. Ogni revisione è assegnata ad un unico numero naturale, di una unità maggiore rispetto alla revisione precedente. La revisione iniziale di un repository appena creato è numerata come zero, e consiste in nient'altro che una directory radice vuota.
Figura 2.7, «Il repository» illustrates a nice way to visualize the repository. Imagine an array of revision numbers, starting at 0, stretching from left to right. Each revision number has a filesystem tree hanging below it, and each tree is a “snapshot” of the way the repository looked after a commit.
Figura 2.7, «Il repository» illustra una tipo intuitivo di visualizzazione del repository. Si immagini un array di numeri di revisioni, che inizia da 0 ed incrementa da destra a sinistra. Ogni numero di revisione ha un albero di filesystem appeso al di sotto, e ogni albero è una «istantanea» di come appariva il repository dopo la commit.
It's important to note that working copies do not always correspond to any single revision in the repository; they may contain files from several different revisions. For example, suppose you check out a working copy from a repository whose most recent revision is 4:
È importante notare che le copie di lavoro non sempre corrispondano ad una singola revisione del repository; potrebbero contenere file di varie revisioni differenti. Ad esempio, supponiamo di effettuare check out di una copia di lavoro da un repository la cui revisione più recente è 4:
calc/Makefile:4 integer.c:4 button.c:4
At the moment, this working directory corresponds exactly
to revision 4 in the repository. However, suppose you make a
change to button.c
, and commit that
change. Assuming no other commits have taken place, your
commit will create revision 5 of the repository, and your
working copy will now look like this:
Al momento, questa directory di lavoro corrisponde esattamente alla
revisione 4 del repository. Tuttavia, supponiamo di aver modificato
button.c
, ed aver sottomesso questo cambiamento.
Assumendo che nessun'altra commit abbia avuto luogo, la propria commit
creerà la revisione 5 del repository, e la propria copia di lavoro
apparirà come segue:
calc/Makefile:4 integer.c:4 button.c:5
Suppose that, at this point, Sally commits a change to
integer.c
, creating revision 6. If you
use svn update to bring your working copy
up to date, then it will look like this:
Supponiamo che, a questo punto, Sally effettui la commit di una
modifica a integer.c
, creando la revisione 6. Se si
usa svn update per attualizzare la propria copia
di lavoro, questa apparirà come segue:
calc/Makefile:6 integer.c:6 button.c:6
Sally's change to integer.c
will
appear in your working copy, and your change will still be
present in button.c
. In this example,
the text of Makefile
is identical in
revisions 4, 5, and 6, but Subversion will mark your working
copy of Makefile
with revision 6 to
indicate that it is still current. So, after you do a clean
update at the top of your working copy, it will generally
correspond to exactly one revision in the repository.
La modifica di Sally a integer.c
apparirà
nella propria copia di lavoro, ed i propri cambiamenti saranno ancora
presenti in button.c
. In questo esempio il testo di
Makefile
è identico nelle revisioni 4, 5 e 6, ma
Subversion marcherà la propria copia di lavoro di
Makefile
con la revisione 6 per indicare che è la
corrente. Quindi, dopo aver fatto un aggiornamento al livello più
alto della propria copia di lavoro, questa corrisponderà esattamente ad
una revisione del repository.
For each file in a working directory, Subversion records
two essential pieces of information in the
.svn/
administrative area:
Per ogni file nella directory di lavoro, Subversion registra due
porzioni di informazione essenziali nell'area di amministrazione
.svn/
:
what revision your working file is based on (this is called the file's working revision), and
il numero di revisione su cui è basata la copia di lavoro (detta revisione di lavoro del file), e
a timestamp recording when the local copy was last updated by the repository.
una marca temporale relativa a quando la copia locale è stata aggiornata con il repository
Given this information, by talking to the repository, Subversion can tell which of the following four states a working file is in:
Date queste informazioni, comunicando con il repository, Subversion può decidere in quale dei seguenti quattro stati si trovi un file nella copia di lavoro:
The file is unchanged in the working directory, and no changes to that file have been committed to the repository since its working revision. An svn commit of the file will do nothing, and an svn update of the file will do nothing.
Il file non è stato modificato nella directory di lavoro e nessuna modifica alla sua revisione di lavoro è stata sottomessa al repository. Un comando svn commit del file non farà nulla, e un comando svn update del file non farà nulla.
The file has been changed in the working directory, and no changes to that file have been committed to the repository since its base revision. There are local changes that have not been committed to the repository, thus an svn commit of the file will succeed in publishing your changes, and an svn update of the file will do nothing.
Il file è stato modificato nella directory di lavoro e nessuna modifica alla sua revisione di lavoro è stata sottomessa al repository. Ci sono delle modifiche locali che devono essere salvate sul repository, quindi un svn commit del file pubblicherà con successo le modifiche, ed un svn update del file non farà nulla.
The file has not been changed in the working directory, but it has been changed in the repository. The file should eventually be updated, to make it current with the public revision. An svn commit of the file will do nothing, and an svn update of the file will fold the latest changes into your working copy.
Il file non è stato modificato nella directory di lavoro, ma ha subito dei cambiamenti nel repository. Il file dovrebbe essere aggiornato per renderlo sincronizzato con l'attuale revisione pubblica. Un svn commit del file non farà nulla, ed un svn update del file caricherà gli ultimi cambiamenti nella copia di lavoro.
The file has been changed both in the working directory, and in the repository. An svn commit of the file will fail with an “out-of-date” error. The file should be updated first; an svn update command will attempt to merge the public changes with the local changes. If Subversion can't complete the merge in a plausible way automatically, it leaves it to the user to resolve the conflict.
Il file è stato cambiato sia nella directory di lavoro, sia nel repository. Un comando svn commit del file fallirà con un errore di «out-of-date». Il file dovrebbe prima essere aggiornato; un comando svn update tenterà di incorporare le modifiche pubbliche con le modifiche locali. Se Subversion non può completare la fusione automatica in un modo coerente, lascerà all'utente il compito di risolvere il conflitto.
This may sound like a lot to keep track of, but the svn status command will show you the state of any item in your working copy. For more information on that command, see sezione chiamata «svn status».
Potrebbe sembrare eccessivo tener traccia di tutto questo, ma il comando svn status mostrerà la stato di ogni elemento nella copia di lavoro. Per altre informazioni su questo comando, si veda sezione chiamata «svn status».
As a general principle, Subversion tries to be as flexible as possible. One special kind of flexibility is the ability to have a working copy containing files and directories with a mix of different working revision numbers. Unfortunately, this flexibility tends to confuse a number of new users. If the earlier example showing mixed revisions perplexed you, here's a primer on both why the feature exists and how to make use of it.
Come principio generale, Subversion vuole essere il più flessibile possibile. Una particolare flessibilità deriva dalla possibilità di avere una copia di lavoro contenente file e directory con un insieme di differenti numeri di revisione. Sfortunatamente questa flessibilità tende a confondere alcuni utenti. Segue quindi un'introduzione sul perché esiste questa caratteristica e su come utilizzarla.
One of the fundamental rules of Subversion is that a “push” action does not cause a “pull”, nor the other way around. Just because you're ready to submit new changes to the repository doesn't mean you're ready to receive changes from other people. And if you have new changes still in progress, then svn update should gracefully merge repository changes into your own, rather than forcing you to publish them.
Una delle regole fondamentali di Subversion è che un'azione di «invio» non causa una «ricezione», né viceversa. Il fatto che ci siano le condizioni per inviare nuove modifiche al repository non significa che si sia pronti per ricevere quelle apportate dagli altri utenti. Se si sta lavorando a delle modifiche, il comando svn update deve integrare gli eventuali cambiamenti avvenuti sul repository in quelle su cui si sta lavorando, piuttosto che forzare la pubblicazione.
The main side-effect of this rule is that it means a working copy has to do extra bookkeeping to track mixed revisions, and be tolerant of the mixture as well. It's made more complicated by the fact that directories themselves are versioned.
La conseguenza principale di questa regola è che implica che una copia di lavoro debba compiere attività supplementari per tener traccia delle diverse revisioni, oltre a tollerare le diversità stesse. Ciò inoltre è reso più complicato dal fatto che anche le directory stesse siano sotto controllo di versione.
For example, suppose you have a working copy entirely at
revision 10. You edit the
file foo.html
and then perform
an svn commit, which creates revision 15
in the repository. After the commit succeeds, many new
users would expect the working copy to be entirely at
revision 15, but that's not the case! Any number of changes
might have happened in the repository between revisions 10
and 15. The client knows nothing of those changes in the
repository, since you haven't yet run svn
update, and svn commit doesn't
pull down new changes. If, on the other hand,
svn commit were to
automatically download the newest changes, then it would be
possible to set the entire working copy to revision
15—but then we'd be breaking the fundamental rule
of “push” and “pull” remaining
separate actions. Therefore the only safe thing the
Subversion client can do is mark the one
file—foo.html
—as being at
revision 15. The rest of the working copy remains at
revision 10. Only by running svn update
can the latest changes be downloaded, and the whole working
copy be marked as revision 15.
Ad esempio, si suppone di avere una copia di lavoro completamente
allineata alla revisione 10. Il file foo.html
viene modificato e successivamente viene eseguito un
svn commit il quale crea la revisione numero 15 nel
repository. Visto l'esito positivo del comando di commit, molti utenti
potrebbero pensare che la copia di lavoro sia interamente allineata
con la revisione 15, ma non è così! Molti cambiamenti potrebbero
essersi verificati nel repository tra la revisione 10 e la 15. Il
client non sa nulla di questi cambiamenti in quanto non si è ancora
eseguito il comando svn update, ed il comando
svn commit non riceve nessun cambiamento.
D'altronde, se il comando svn commit scaricasse
automaticamente le nuove modifiche dal repository, allora sarebbe
possibile allineare tutta la copia di lavoro alla revisione 15 —
ma si verrebbe così ad infrangere la regola fondamentale che impone a
invio e ricezione di essere azioni separate. Quindi l'unica cosa
sicura che il client di Subversion possa fare è ricordare che il file
—foo.html
— sia aggiornato alla
revisione 15. Il resto della copia di lavoro rimane alla revisione 10.
Solo eseguendo un svn update si possono scaricare
gli ultimissimi cambiamenti, e tutta la copia di lavoro sarà
contrassegnata alla revisione 15.
The fact is, every time you run svn commit, your working copy ends up with some mixture of revisions. The things you just committed are marked as having larger working revisions than everything else. After several commits (with no updates in-between) your working copy will contain a whole mixture of revisions. Even if you're the only person using the repository, you will still see this phenomenon. To examine your mixture of working revisions, use the svn status --verbose command (see sezione chiamata «svn status» for more information.)
Di fatto ogni volta che si esegue il comando svn commit la copia di lavoro si viene a trovare in un insieme misto di revisioni. Gli elementi che sono appena stati inviati al repository avranno la revisione di lavoro più alta di ogni altro. Dopo diversi commit (senza operazioni di aggiornamento intermedie) la copia di lavoro conterrà una vasta combinazione di revisioni. Anche se una sola persona stesse usando il repository, si continuerebbe a verificare questo fenomeno. Per esaminare la miscela delle revisioni di lavoro, si può usare il comando svn status --verbose (per maggiori informazioni vedere sezione chiamata «svn status»).
Often, new users are completely unaware that their working copy contains mixed revisions. This can be confusing, because many client commands are sensitive to the working revision of the item they're examining. For example, the svn log command is used to display the history of changes to a file or directory (see sezione chiamata «svn log»). When the user invokes this command on a working copy object, they expect to see the entire history of the object. But if the object's working revision is quite old (often because svn update hasn't been run in a long time), then the history of the older version of the object is shown.
Spesso i nuovi utenti ignorano completamente che la loro copia di lavoro contenga diverse revisioni. Ciò può generare confusione, perché molti comandi sono sensibili alla revisione di lavoro degli oggetti che devono esaminare. Per esempio, il comando svn log viene utilizzato per mostrare la storia dei cambiamenti di un file o una directory (vedere sezione chiamata «svn log»). Quando un utente invoca questo comando sulla copia di lavoro di un oggetto, si aspetta di vedere l'intera storia dell'oggetto stesso. In realtà se la revisione di lavoro è piuttosto vecchia (solitamente perché non si è usato il comando svn update da molto tempo), allora viene mostrata la storia della precedente versione dell'oggetto.
If your project is sufficiently complex, you'll discover that it's sometimes nice to forcibly “backdate” portions of your working copy to an earlier revision; you'll learn how to do that in Chapter 3. Perhaps you'd like to test an earlier version of a sub-module contained in a subdirectory, or perhaps you'd like to figure out when a bug first came into existence in a specific file. This is the “time machine” aspect of a version control system — the feature which allows you to move any portion of your working copy forward and backward in history.
Se il progetto è piuttosto complesso, a volte è meglio forzare alcune porzioni della copia di lavoro a «retrocedere» a versioni precedenti; nel Capitolo 3 si potrà vedere come fare. Si potrebbe voler testare una versione precedente di qualche componente contenuta in una sotto directory; oppure si vorrebbe capire quando un difetto è comparso per la prima volta in un certo file. Questo è l'aspetto di un sistema di controllo delle versioni che lo caratterizza come una «macchina del tempo» — la caratteristica che permette di muovere ogni porzione della copia di lavoro avanti e indietro nella storia.
However you make use of mixed revisions in your working copy, there are limitations to this flexibility.
Qualunque uso si faccia delle revisioni miste nella copia di lavoro, ci sono sempre delle limitazioni a questa flessibilità.
First, you cannot commit the deletion of a file or directory which isn't fully up-to-date. If a newer version of the item exists in the repository, your attempt to delete will be rejected, to prevent you from accidentally destroying changes you've not yet seen.
Primo, non si può effettuare la commit della cancellazione di un file o directory che non sia completamente aggiornato. Se nel repository esiste una versione più recente, il tentativo di eliminazione verrà rifiutato, per evitare la distruzione accidentale di modifiche che non si siano ancora viste.
Second, you cannot commit a metadata change to a directory unless it's fully up-to-date. You'll learn about attaching “properties” to items in Chapter 6. A directory's working revision defines a specific set of entries and properties, and thus committing a property change to an out-of-date directory may destroy properties you've not yet seen.
Secondo, non è possibile effettuare la commit della modifica di un metadato su una directory senza che questa sia completamente aggiornata. Nel capitolo 6 si imparerà ad assegnare «proprietà» agli oggetti. La revisione di lavoro di una directory definisce un insieme specifico di voci e proprietà, quindi effettuare la commit della modifica di una proprietà a una directory non aggiornata potrebbe distruggere qualche proprietà che non sia ancora stata esaminata.