Diritto d'autore © 2002, 2003, 2004, 2005, 2006 Ben Collins-Sussman, Brian W. Fitzpatrick, C. Michael Pilato
This work is licensed under the Creative Commons Attribution License. To view a copy of this license, visit http://creativecommons.org/licenses/by/2.0/ or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
Questo lavoro è rilasciato sotto la licenza Creative Commons Attribution. Per vedere una copia di questa licenza consultare il sito http://creativecommons.org/licenses/by/2.0/ od inviare una lettera a Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
(TBA)
Indice
Lista delle figure
Lista delle tabelle
Lista degli esempi
.svn/entriesA bad Frequently Asked Questions (FAQ) sheet is one that is composed not of the questions people actually asked, but of the questions the FAQ's author wished people had asked. Perhaps you've seen the type before:
Una pagina scadente delle domande frequenti (Frequently Asked Questions-FAQ) è quella composta non dalle domande che la gente veramente pone, ma da domande che l'autore di quella FAQ avrebbe voluto che fossero state poste. Forse avete già incontrato cose di questo tipo:
Q: How can I use Glorbosoft XYZ to maximize team productivity?
D: Come posso usare Glorbosoft XYZ per massimizzare la produttività del gruppo?
A: Many of our customers want to know how they can maximize productivity through our patented office groupware innovations. The answer is simple: first, click on the “
File” menu, scroll down to “Increase Productivity”, then…R: Molti dei nostri clienti vogliono sapere come possono massimizzare la produttività attraverso le nostre innovazioni brevettate di software collaborativo per ufficio. La risposta è semplice: prima cliccare sul menù «
File», scorrere giù fino ad «Aumentare produttività», poi…
The problem with such FAQs is that they are not, in a literal sense, FAQs at all. No one ever called the tech support line and asked, “How can we maximize productivity?”. Rather, people asked highly specific questions, like, “How can we change the calendaring system to send reminders two days in advance instead of one?” and so on. But it's a lot easier to make up imaginary Frequently Asked Questions than it is to discover the real ones. Compiling a true FAQ sheet requires a sustained, organized effort: over the lifetime of the software, incoming questions must be tracked, responses monitored, and all gathered into a coherent, searchable whole that reflects the collective experience of users in the wild. It calls for the patient, observant attitude of a field naturalist. No grand hypothesizing, no visionary pronouncements here—open eyes and accurate note-taking are what's needed most.
Il problema di queste FAQ è che non sono, in senso letterale, per nulla FAQ. Nessuno ha mai chiamato il supporto tecnico per chiedere: «Come possiamo massimizzare la produttività?». La gente, piuttosto, pone domande molto specifiche, tipo: «Come possiamo cambiare il sistema di calendario per spedire i promemoria con anticipo di due giorni invece di uno?» e via dicendo. Ma è molto più semplice costruire FAQ immaginarie che elaborarne una reale. Compilare una vera pagina delle FAQ richiede uno sforzo continuo ed organizzato: durante il ciclo di vita del software le domande pervenute devono essere tracciate, le risposte monitorate e tutto deve essere messo insieme in un modo coerente e consultabile, che rifletta l'esperienza collettiva di tutti gli utenti. È richiesta l'attitudine all'osservazione paziente propria di un naturalista. Non grandi ipotesi, non dichiarazioni visionarie—occhi aperti ed un accurato prender nota, è tutto quel che serve.
What I love about this book is that it grew out of just such a process, and shows it on every page. It is the direct result of the authors' encounters with users. It began with Ben Collins-Sussman's observation that people were asking the same basic questions over and over on the Subversion mailing lists: What are the standard workflows to use with Subversion? Do branches and tags work the same way as in other version control systems? How can I find out who made a particular change?
Quel che amo di questo libro è il fatto che sia cresciuto proprio da un processo di questo tipo e lo mostra in ogni pagina. Esso è il risultato diretto dell'incontro tra gli autori e gli utenti. È cominciato dall'osservazione di Ben Collins-Sussman che le persone ponevano sempre le stesse domande base nelle mailing list di Subversion: Quali sono i flussi di lavoro standard da usare con Subversion? Branch e tag funzionano come negli altri sistemi per il controllo di versione? Come posso scoprire chi ha fatto una particolare modifica?
Frustrated at seeing the same questions day after day, Ben worked intensely over a month in the summer of 2002 to write The Subversion Handbook, a sixty page manual that covered all the basics of using Subversion. The manual made no pretense of being complete, but it was distributed with Subversion and got users over that initial hump in the learning curve. When O'Reilly and Associates decided to publish a full-length Subversion book, the path of least resistance was obvious: just expand the Subversion handbook.
Frustrato dal vedere sempre le stesse domande giorno dopo giorno, Ben ha lavorato intensamente per più di un mese nell'estate 2002 per scrivere The Subversion Handbook, manualetto di 60 pagine che copriva tutte le nozioni di base sull'uso di Subversion. Il manuale non pretendeva di essere completo, ma fu distribuito con Subversion ed ha dato agli utenti la spinta iniziale nella curva d'apprendimento. Quando O'Reilly and Associates hanno deciso di pubblicare un libro su Subversion in edizione completa, la via più facile era ovvia: semplicemente espandere Subversion handbook.
The three co-authors of the new book were thus presented with an unusual opportunity. Officially, their task was to write a book top-down, starting from a table of contents and an initial draft. But they also had access to a steady stream—indeed, an uncontrollable geyser—of bottom-up source material. Subversion was already in the hands of thousands of early adopters, and those users were giving tons of feedback, not only about Subversion, but about its existing documentation.
Ai tre co-autori del nuovo libro si è presentata un'opportunità non comune. Ufficialmente, loro compito era scrivere un libro 'top-down', cominciando dall'indice e da una bozza iniziale. Ma gli autori avevano anche accesso ad una massiccia corrente— davvero un geyser incontrollabile— di materiale originale di tipo 'bottom-up'. Subversion era già nelle mani di migliaia di utenti neofiti e questi fornivano tonnellate di feedback non solo riguardo Subversion ma anche riguardo la sua documentazione.
During the entire time they wrote this book, Ben, Mike, and Brian haunted the Subversion mailing lists and chat rooms incessantly, carefully noting the problems users were having in real-life situations. Monitoring such feedback is part of their job descriptions at CollabNet anyway, and it gave them a huge advantage when they set out to document Subversion. The book they produced is grounded firmly in the bedrock of experience, not in the shifting sands of wishful thinking; it combines the best aspects of user manual and FAQ sheet. This duality might not be noticeable on a first reading. Taken in order, front to back, the book is simply a straightforward description of a piece of software. There's the overview, the obligatory guided tour, the chapter on administrative configuration, some advanced topics, and of course a command reference and troubleshooting guide. Only when you come back to it later, seeking the solution to some specific problem, does its authenticity shine out: the telling details that can only result from encounters with the unexpected, the examples honed from genuine use cases, and most of all the sensitivity to the user's needs and the user's point of view.
Durante la stesura del libro, Ben, Mike e Brian hanno perlustrato senza sosta le mailing list e chat room di Subversion, annotando con cura quali problemi avevano gli utenti in situazioni reali. Monitorare assiduamente il feedback degli utenti è parte del loro lavoro presso CollabNet, e ciò li avvantaggiò molto quando si misero a documentare Subversion. Il libro che hanno prodotto è ancorato saldamente sulla roccia dell'esperienza, non sulle sabbie mobili dei desideri; esso combina gli aspetti migliori di un manuale per utenti e di una pagina delle FAQ. Questa dualità forse non si nota alla prima lettura. Preso in ordine, dalla prima al'ultima pagina, il libro è semplicemente una chiara descrizione di un software. Ci sono introduzione, l'obbligatoria 'visita guidata', il capitolo sulla configurazione, alcuni concetti avanzati e naturalmente, la dettagliata spiegazione delle opzioni dei comandi e la guida alla risoluzione dei problemi. Solo quando ci si torna in seguito, cercando la soluzione d'un particolare problema, salta fuori la sua autenticità: i dettagli parlanti che possono essere solo frutto di incontri con l'inaspettato, gli esempi affinati da casi d'uso genuini, e soprattutto la sensibilità ai bisogni degli utenti ed al loro punto di vista
Of course, no one can promise that this book will answer
every question you have about Subversion. Sometimes, the
precision with which it anticipates your questions will seem
eerily telepathic; yet occasionally, you will stumble into a
hole in the community's knowledge, and come away empty-handed.
When this happens, the best thing you can do is email
<users@subversion.tigris.org> and present your
problem. The authors are still there, still watching, and they
include not just the three listed on the cover, but many others
who contributed corrections and original material. From the
community's point of view, solving your problem is merely a
pleasant side effect of a much larger project—namely,
slowly adjusting this book, and ultimately Subversion itself, to
more closely match the way people actually use it. They are
eager to hear from you not merely because they can help you, but
because you can help them. With Subversion as with all active
free software projects, you are not
alone.
Certamente, nessuno può promettere che questo libro
risponderà ad ogni domanda che si possa avere riguardo Subversion.
Qualche volta, la precisione con cui anticipa le vostre domande
potrà sembrare misteriosamente telepatica; ma alle volte
ci si imbatte in una lacuna nel bagaglio di conoscenze della comunità e
si torna a mani vuote. Quando succede, la cosa migliore è
inviare una email a <users@subversion.tigris.org> ed
esporre il proprio problema. Gli autori sono ancora lì, ancora
osservano e non sono solo i tre citati sulla prima pagina,
ma molti altri che hanno contribuito con correzioni e con
nuovo materiale. Dal punto di vista della comunità, risolvere
il vostro problema è solo il piacevole effetto collaterale di un
progetto più ampio— cioè, pian piano sistemare
questo libro, e alla fine Subversion stesso, per avvicinarsi di più
al modo in cui la gente lo usa. Sono desiderosi di sentirvi non
solo perché vi possono aiutare, ma perché voi potete aiutare loro.
Con Subversion come nel caso di tutti i progetti attivi di software libero
non siete soli.
Let this book be your first companion.
Che questo libro sia il vostro primo compagno.
— , Chicago, 14 March, 2004
Indice
«If C gives you enough rope to hang yourself, think of Subversion as a sort of rope storage facility.» «Se il C fornisce corda a sufficienza per impiccarti, pensa a Subversion come una sorta di magazzino di corde.» —Brian W. Fitzpatrick
In the world of open-source software, the Concurrent Versions System (CVS) has long been the tool of choice for version control. And rightly so. CVS itself is free software, and its non-restrictive modus operandi and support for networked operation—which allow dozens of geographically dispersed programmers to share their work—fits the collaborative nature of the open-source world very well. CVS and its semi-chaotic development model have become cornerstones of open-source culture.
Nel mondo del software open-source, Concurrent Versions System (CVS) è stato a lungo e giustamente lo strumento preferito per il controllo di versione. Lo stesso CVS è software libero ed il suo modus operandi non-restrittivo, unito al supporto per il funzionamento in rete—che permette a dozzine di programmatori sparsi per il mondo di condividere il proprio lavoro—calza perfettamente alla natura collaborativa del mondo open-source. CVS ed il suo modello di sviluppo semi-caotico sono diventati un elemento fondamentale della cultura open-source.
But like many tools, CVS is starting to show its age. Subversion is a relatively new version control system designed to be the successor to CVS. The designers set out to win the hearts of CVS users in two ways: by creating an open-source system with a design (and “look and feel”) similar to CVS, and by attempting to fix most of CVS's noticeable flaws. While the result isn't necessarily the next great evolution in version control design, Subversion is very powerful, very usable, and very flexible.
Ma come molti altri strumenti, CVS sta iniziando a mostrare la sua età. Subversion è un sistema di controllo di versione relativamente nuovo, progettato per essere il successore di CVS. I progettisti hanno mirato al cuore degli utenti CVS in due modi: creando un sistema open-source con un'architettura (ed un «look and feel») simile a CVS, e contemporaneamente provando ad eliminare la maggior parte dei difetti più evidenti di CVS. Sebbene il risultato non sia necessariamente il prossimo grande salto evolutivo dei sistemi di controllo di versione, Subversion è molto potente, usabile e flessibile.
This book is written to document the 1.2 series of the Subversion version control system. We have made every attempt to be thorough in our coverage. However, Subversion has a thriving and energetic development community, so there are already a number of features and improvements planned for future versions of Subversion that may change some of the commands and specific notes in this book.
Questo libro documenta la serie 1.2 del sistema di controllo di versione Subversion. Abbiamo cercato di essere esaustivi nella nostra analisi. Tuttavia, Subversion ha una comunità di sviluppo fiorente e piena di energie ed esiste già un nutrito numero di funzionalità e miglioramenti pianificati per le prossime versioni che potranno apportare modifiche ad alcuni dei comandi e delle annotazioni contenute in questo libro.
This book is written for computer-literate folk who want to use Subversion to manage their data. While Subversion runs on a number of different operating systems, its primary user interface is command-line based. It is that command-line tool (svn) which is discussed and used in this book. For consistency, the examples in this book assume the reader is using a Unix-like operating system, and is relatively comfortable with Unix and command-line interfaces.
Questo libro è scritto per persone con una certa dimestichezza con il computer e che vogliono utilizzare Subversion per gestire i propri dati. Nonostante Subversion sia disponibile per un certo numero di sistemi operativi, la sua interfaccia utente primaria è basata sulla riga di comando. È proprio tale tool a riga di comando (svn) ad essere discusso e usato in questo libro. Per coerenza, gli esempi di questo libro assumono che il lettore utilizzi un sistema operativo di derivazione Unix e sia relativamente a proprio agio con Unix e le interfacce a riga di comando.
That said, the svn program also runs on
non-Unix platforms like Microsoft Windows. With a few minor
exceptions, such as the use of backward slashes
(\) instead of forward slashes
(/) for path separators, the input to and
output from this tool when run on Windows are identical to its
Unix counterpart. However, Windows users may find more success
by running the examples inside the Cygwin Unix emulation
environment.
Detto questo, il programma svn funziona anche
su piattaforme non-Unix come Microsoft Windows. Con qualche piccola
eccezione, come l'uso del backslash (\) al posto
dello slash (/) come separatore di percorso,
l'input e l'output prodotti dal programma quando questo è eseguito
su Windows sono identici a quelli prodotti dalla controparte su Unix.
Tuttavia, gli utenti Windows potrebbero avere più successo eseguendo
gli esempi all'interno dell'ambiente di emulazione Unix: Cygwin.
Most readers are probably programmers or system administrators who need to track changes to source code. This is the most common use for Subversion, and therefore it is the scenario underlying all of the book's examples. But Subversion can be used to manage changes to any sort of information: images, music, databases, documentation, and so on. To Subversion, all data is just data.
La maggior parte dei lettori saranno probabilmente programmatori o amministratori di sistema che necessitano di tenere traccia delle modifiche al codice sorgente. Questo è l'uso più comune di Subversion e quindi è lo scenario utilizzato in tutti gli esempi del libro. Subversion, tuttavia, può essere utilizzato per gestire modifiche apportate a qualunque tipo di informazione: immagini, musica, database, documentazione e via dicendo. Per Subversion, i dati sono solo dati.
While this book is written with the assumption that the reader has never used version control, we've also tried to make it easy for users of CVS to make a painless leap into Subversion. Special sidebars may discuss CVS from time to time, and a special appendix summarizes most of the differences between CVS and Subversion.
Nonostante questo libro sia stato scritto presumendo che il lettore non abbia mai utilizzato un sistema di controllo di versione, abbiamo anche provato a rendere indolore la transizione di utenti CVS verso Subversion. Speciali trafiletti discuteranno CVS di tanto in tanto e un'apposita appendice fornisce un sommario delle principali differenze tra CVS e Subversion.
This book aims to be useful to people of widely different backgrounds—from people with no previous experience in version control to experienced system administrators. Depending on your own background, certain chapters may be more or less important to you. The following can be considered a “recommended reading list” for various types of readers:
Questo libro mira ad essere utile per utenti con differenti gradi di preparazione—da persone senza nessuna precedente esperienza con il controllo di versione ad amministratori di sistema esperti. A seconda del proprio background, certi capitoli potranno essere più o meno importanti. La seguente può essere considerata una «lista di letture consigliate» per i vari tipi di lettore:
The assumption here is that you've probably used CVS before, and are dying to get a Subversion server up and running ASAP. Capitolo 5, Repository Administration and Capitolo 6, Configurazione del server will show you how to create your first repository and make it available over the network. After that's done, Capitolo 3, Visita guidata and Appendice A, Subversion per utenti CVS are the fastest routes to learning the Subversion client while drawing on your CVS experience.
Your administrator has probably set up Subversion already, and you need to learn how to use the client. If you've never used a version control system (like CVS), then Capitolo 2, Concetti base and Capitolo 3, Visita guidata are a vital introduction. If you're already an old hand at CVS, chapter 3 and appendix A are the best place to start.
Whether you're a user or administrator, eventually your project will grow larger. You're going to want to learn how to do more advanced things with Subversion, such as how to use branches and perform merges (Capitolo 4, Ramificazioni e fusioni), how to use Subversion's property support, how to configure runtime options (Capitolo 7, Temi avanzati), and other things. These two chapters aren't vital at first, but be sure to read them once you're comfortable with the basics.
Presumably, you're already familiar with Subversion, and now want to either extend it or build new software on top of its many APIs. Capitolo 8, Informazioni per lo sviluppatore is just for you.
L'assunto è che l'utente abbia usato CVS in precedenza e che muoia dalla voglia di avere un server Subversion funzionante il prima possibile. Il Capitolo 5, Repository Administration e il Capitolo 6, Configurazione del server mostreranno come creare il primo repository e come renderlo disponibile in rete. Fatto questo, il Capitolo 3, Visita guidata e l'Appendice A, Subversion per utenti CVS sono la via più veloce per imparare ad usare il client Subversion attingendo dall'esperienza con CVS.
L'amministratore ha già installato Subversion, e si vuole imparare ad utilizzare il client. Per chi non ha mai utilizzato un sistema di controllo di versione (come CVS), il Capitolo 2, Concetti base e il Capitolo 3, Visita guidata forniscono un'introduzione essenziale. Se invece si ha già una discreta esperienza con CVS, il capitolo 3 e l'appendice A sono il miglior punto di partenza.
Che si sia un utente o un amministratore, prima o poi si avrà a che fare con progetti grandi. Si vorrà quindi imparare come fare cose più avanzate con Subversion, ad esempio come usare i branch ed effettuare merge (Capitolo 4, Ramificazioni e fusioni), come usare il supporto di Subversion per le proprietà, come configurare le opzioni di runtime (Capitolo 7, Temi avanzati), e altro ancora. Questi due capitoli non sono di importanza vitale all'inizio, ma è meglio assicurarsi di leggerli, una volta presa confidenza con le operazioni di base.
Presubimilmente si ha già familiarità con Subversion ed ora si vuole estenderne le funzionalità o sviluppare nuovo software utilizzando le sue numerose API. Il Capitolo 8, Informazioni per lo sviluppatore è quello che ci vuole.
The book ends with reference material—Capitolo 9, Riferimento completo di Subversion is a reference guide for all Subversion commands, and the appendices cover a number of useful topics. These are the chapters you're mostly likely to come back to after you've finished the book.
Il libro si chiude con materiale di riferimento—il Capitolo 9, Riferimento completo di Subversion è una guida di riferimento per tutti i comandi di Subversion e le appendici coprono una serie di argomenti utili. Questi sono i capitoli su cui si tornerà con maggior probabilità, una volta finito di leggere il libro.
This section covers the various conventions used in this book.
Questa sezione descrive le varie convenzioni utilizzate nel resto del libro.
Used for commands, command output, and switches
Constant width italicUsed for replaceable items in code and text
ItalicUsed for file and directory names
Utilizzato per comandi, output di comandi e switch
Corsivo a larghezza fissaUtilizzato per elementi sostituibili nel codice e nel testo
CorsivoUtilizzato per nomi di file e directory
![]() | Nota |
|---|---|
This icon designates a note relating to the surrounding text. Questa icona indica una nota relativa al testo adiacente. |
![]() | Suggerimento |
|---|---|
This icon designates a helpful tip relating to the surrounding text. Questa icona indica un suggerimento utile relativo al testo adiacente. |
![]() | Avvertimento |
|---|---|
This icon designates a warning relating to the surrounding text. Questa icona indica un avviso relativo al testo adicente. |
Note that the source code examples are just that—examples. While they will compile with the proper compiler incantations, they are intended to illustrate the problem at hand, not necessarily serve as examples of good programming style.
Notare che gli esempi di codice sorgente sono solo esempi. Sebbene compilino, sono stati scritti a supporto dell'illustrazione dei vari problemi, non sono necessariamente da prendere come esempi di buona programmazione.
The chapters that follow and their contents are listed here:
Segue la lista dei capitoli e del loro contenuto:
Covers the history of Subversion as well as its features, architecture, components, and install methods. Also includes a quick-start guide.
Riporta la storia di Subversion come pure le sue caratteristiche, l'architettura, i componenti ed i metodi d'installazione. Include anche una guida rapida.
Explains the basics of version control and different versioning models, along with Subversion's repository, working copies, and revisions.
Spiega le basi del controllo di versione e dei diversi modelli di versionamento, insieme a repository, copie di lavoro (working copies) e revisioni con Subversion.
Walks you through a day in the life of a Subversion user. It demonstrates how to use Subversion to obtain, modify, and commit data.
Descrive una giornata di lavoro di un utente di Subversion. Mostra come usare Subversion per ottenere, modificare ed effettuare commit di dati.
Discusses branches, merges, and tagging, including best practices for branching and merging, common use cases, how to undo changes, and how to easily swing from one branch to the next.
Discute branch, merge e tag, comprendendo consigli su come creare ramificazioni e fusioni (branching and merging), casi d'uso comuni, istruzioni su come annullare i cambiamenti e su come dondolarsi agilmente da un ramo (branch) ad un altro.
Describes the basics of the Subversion repository, how to create, configure, and maintain a repository, and the tools you can use to do all of this.
Descrive le basi del repository di Subversiion, come creare, configurare e manutenere un repository e i tool a disposizione per fare tutto questo.
Explains how to configure your Subversion server and
the three ways to access your repository:
HTTP, the svn
protocol, and local access. It also covers the details
of authentication, authorization and anonymous
access.
Spiega come configurare un server Subversion e
i tre modi per accedere al repository:
HTTP, il protocollo svn
e l'accesso locale. Copre anche i dettagli riguardanti autenticazione,
autorizzazione e accesso anonimo.
Explores the Subversion client configuration files,
file and directory properties, how to
ignore files in your working copy,
how to include external trees in your working copy, and
lastly, how to handle vendor branches.
Esplora i file di configurazione del client Subversion,
le proprietà di file e directory, come ignorare (ignore)
file nella copia di lavoro (working copy), come includere
alberature esterne nella copia di lavoro (working copy) e infine,
come gestire branch di terze parti.
Describes the internals of Subversion, the Subversion filesystem, and the working copy administrative areas from a programmer's point of view. Demonstrates how to use the public APIs to write a program that uses Subversion, and most importantly, how to contribute to the development of Subversion.
Descrive gli aspetti interni di Subversion, il file system di Subversion, e le aree amministrative della copia di lavoro (working copy), dal punto di vista di un programmatore. Mostra come usare le API pubbliche per scrivere un programma che utilizzi Subversion e, la cosa più importante, come contribuire allo sviluppo di Subversion.
Explains in great detail every subcommand of svn, svnadmin, and svnlook with plenty of examples for the whole family!
Spiega nei dettagli ogni comando di svn, svnadmin, e svnlook con molti esempi al riguardo!
Covers the similarities and differences between Subversion and CVS, with numerous suggestions on how to break all the bad habits you picked up from years of using CVS. Included are descriptions of Subversion revision numbers, versioned directories, offline operations, update vs. status, branches, tags, metadata, conflict resolution, and authentication.
Tratta le similitudini e differenze tra Subversion e CVS, con numerosi suggerimenti riguardanti come evitare le cattive abitudini acquisite in anni di utilizzo di CVS. Include descrizioni dei numeri di revisione in Subversion, delle directory versionate, delle operazioni offline, di update rispetto a status, di branch, tag, metadati, risoluzione di conflitti e autenticazione.
Describes the details of WebDAV and DeltaV, and how you can configure your Subversion repository to be mounted read/write as a DAV share.
Descrive i dettagli di WebDAV e DeltaV e come configurare il repository Subversion per essere montato in lettura/scrittura come condivisioe DAV.
Discusses tools that support or use Subversion, including alternative client programs, repository browser tools, and so on.
Discute tool che supportano o utilizzano Subversion, includendo programmi client alternativi, tool per l'esplorazione del repository e così via.
This book started out as bits of documentation written by Subversion project developers, which were then coalesced into a single work and rewritten. As such, it has always been under a free license. (See Appendice D, Copyright.) In fact, the book was written in the public eye, as a part of Subversion. This means two things:
Questo libro è nato da frammenti di documentazione scritti dagli sviluppatori del progetto Subversion, che in seguito li hanno unificati e riscritti a formare un unico scritto. Come tale, il libro è sempre stato sotto una licenza libera (vedere Appendice D, Copyright.). Infatti, il libro è stato scritto sotto i riflettori, come parte di Subversion. Cio' significa due cose:
You will always find the latest version of this book in the book's own Subversion repository.
È sempre possibile trovare la versione piu' aggiornata di questo libro nello specifico repository Subversion.
You can distribute and make changes to this book however you wish—it's under a free license. Of course, rather than distribute your own private version of this book, we'd much rather you send feedback and patches to the Subversion developer community. See la sezione chiamata «Contribuire a Subversion» to learn about joining this community.
Si può distribuire e modificare questo libro a piacimento — è sotto licenza libera. Naturalmente, piuttosto che distribuire la vostra versione privata di questo libro, noi preferiremmo che inviaste feedback e correzioni alla comunità di sviluppo di Subversion. Vedere la sezione chiamata «Contribuire a Subversion» per sapere come unirsi a questa comunità.
A relatively recent online version of this book can be found at http://svnbook.red-bean.com.
Una copia relativamente recente della versione online di questo libro si trova all'indirizzo: http://svnbook.red-bean.com.
This book would not be possible (nor very useful) if Subversion did not exist. For that, the authors would like to thank Brian Behlendorf and CollabNet for the vision to fund such a risky and ambitious new Open Source project; Jim Blandy for the original Subversion name and design—we love you, Jim; Karl Fogel for being such a good friend and a great community leader, in that order.[1]
Questo libro non esisterebbe (né sarebbe molto utile) se Subversion non esistesse. Per questo, gli autori vogliono ringraziare Brian Behlendorf e CollabNet per l'intuito nel finanziare un progetto Open Source così rischioso ed ambizioso; Jim Blandy per il nome e il progetto orginale di Subversion— ti vogliamo bene, Jim; Karl Fogel per essere, in quest'ordine, un così buon amico ed un grande leader per la comunità. [2]
Thanks to O'Reilly and our editors, Linda Mui and Tatiana Diaz for their patience and support.
Thanks alla O'Reilly ed ai suoi editori, Linda Mui e Tatiana Diaz per la loro pazienza e il loro sostegno.
Finally, we thank the countless people who contributed to this book with informal reviews, suggestions, and fixes: While this is undoubtedly not a complete list, this book would be incomplete and incorrect without the help of: Jani Averbach, Ryan Barrett, Francois Beausoleil, Jennifer Bevan, Matt Blais, Zack Brown, Martin Buchholz, Brane Cibej, John R. Daily, Peter Davis, Olivier Davy, Robert P. J. Day, Mo DeJong, Brian Denny, Joe Drew, Nick Duffek, Ben Elliston, Justin Erenkrantz, Shlomi Fish, Julian Foad, Chris Foote, Martin Furter, Dave Gilbert, Eric Gillespie, Matthew Gregan, Art Haas, Greg Hudson, Alexis Huxley, Jens B. Jorgensen, Tez Kamihira, David Kimdon, Mark Benedetto King, Andreas J. Koenig, Nuutti Kotivuori, Matt Kraai, Scott Lamb, Vincent Lefevre, Morten Ludvigsen, Paul Lussier, Bruce A. Mah, Philip Martin, Feliciano Matias, Patrick Mayweg, Gareth McCaughan, Jon Middleton, Tim Moloney, Mats Nilsson, Joe Orton, Amy Lyn Pilato, Kevin Pilch-Bisson, Dmitriy Popkov, Michael Price, Mark Proctor, Steffen Prohaska, Daniel Rall, Tobias Ringstrom, Garrett Rooney, Joel Rosdahl, Christian Sauer, Larry Shatzer, Russell Steicke, Sander Striker, Erik Sjoelund, Johan Sundstroem, John Szakmeister, Mason Thomas, Eric Wadsworth, Colin Watson, Alex Waugh, Chad Whitacre, Josef Wolf, Blair Zajac, and the entire Subversion community.
Infine, ringraziamo le innumerevoli persone che hanno contribuito a questo libro con revisioni informali, suggerimenti e correzioni: sebbene questa lista sia sicuramente incompleta, questo libro sarebbe incompleto e non corretto senza l'aiuto di: Jani Averbach, Ryan Barrett, Francois Beausoleil, Jennifer Bevan, Matt Blais, Zack Brown, Martin Buchholz, Brane Cibej, John R. Daily, Peter Davis, Olivier Davy, Robert P. J. Day, Mo DeJong, Brian Denny, Joe Drew, Nick Duffek, Ben Elliston, Justin Erenkrantz, Shlomi Fish, Julian Foad, Chris Foote, Martin Furter, Dave Gilbert, Eric Gillespie, Matthew Gregan, Art Haas, Greg Hudson, Alexis Huxley, Jens B. Jorgensen, Tez Kamihira, David Kimdon, Mark Benedetto King, Andreas J. Koenig, Nuutti Kotivuori, Matt Kraai, Scott Lamb, Vincent Lefevre, Morten Ludvigsen, Paul Lussier, Bruce A. Mah, Philip Martin, Feliciano Matias, Patrick Mayweg, Gareth McCaughan, Jon Middleton, Tim Moloney, Mats Nilsson, Joe Orton, Amy Lyn Pilato, Kevin Pilch-Bisson, Dmitriy Popkov, Michael Price, Mark Proctor, Steffen Prohaska, Daniel Rall, Tobias Ringstrom, Garrett Rooney, Joel Rosdahl, Christian Sauer, Larry Shatzer, Russell Steicke, Sander Striker, Erik Sjoelund, Johan Sundstroem, John Szakmeister, Mason Thomas, Eric Wadsworth, Colin Watson, Alex Waugh, Chad Whitacre, Josef Wolf, Blair Zajac, e l'intera comunità di Subversion.
Thanks to my wife Frances, who, for many months, got to hear, “But honey, I'm still working on the book”, rather than the usual, “But honey, I'm still doing email.” I don't know where she gets all that patience! She's my perfect counterbalance.
Grazie a mia moglie Frances, che, per molti mesi, ha dovuto sentirmi rispondere: «Ma tesoro, sto ancora lavorando al libro», invece del solito, «Ma tesoro, sto ancora scrivendo delle email. » Non so da dove prenda tutta quella pazienza! Mi controbilancia perfettamente.
Thanks to my extended family for their sincere encouragement, despite having no actual interest in the subject. (You know, the ones who say, “Ooh, you're writing a book?”, and then when you tell them it's a computer book, sort of glaze over.)
Grazie ai miei familiari per il loro sincero incoraggiamento, nonostante non abbiano un reale interesse nell'argomento. (Sono il tipo di persone che dicono: «Ooh, stai scrivendo un libro?», e poi quando gli si dice che è un libro di computer, entrano in confusione.)
Thanks to all my close friends, who make me a rich, rich man. Don't look at me that way—you know who you are.
Grazie a tutti i miei amici più vicini, che mi rendono un uomo ricco, ricco davvero. Non guardatemi in quel modo—voi sapete chi siete.
Huge thanks to my wife Marie for being incredibly understanding, supportive, and most of all, patient. Thank you to my brother Eric who first introduced me to UNIX programming way back when. Thanks to my Mom and Grandmother for all their support, not to mention enduring a Christmas holiday where I came home and promptly buried my head in my laptop to work on the book.
Un enorme ringraziamento a mia moglie Marie per essere incredibilmente comprensiva, di aiuto e, soprattutto, paziente. Grazie a mio fratello Eric che per primo mi ha introdotto al modo di programmare UNIX. Grazie a mia Mamma e a mia Nonna per tutto il loro aiuto, per non parlare dell'aver sopportato delle vacanze di Natale durante le quali sono tornato a casa ed immediatamente ho ficcato la testa nel portatile per lavorare al libro.
To Mike and Ben: It was a pleasure working with you on the book. Heck, it's a pleasure working with you at work!
A Mike e Ben: è stato un piacere lavorare con voi al libro. Accidenti, è un piacere lavorare con voi!
To everyone in the Subversion community and the Apache Software Foundation, thanks for having me. Not a day goes by where I don't learn something from at least one of you.
A chiunque nella comunità Subversion e nella Apache Software Foundation, grazie per avermi tra voi. Non passa giorno nel quale non impari qualcosa da almeno uno di voi.
Lastly, thanks to my Grandfather who always told me that “freedom equals responsibility.” I couldn't agree more.
Infine, grazie a mio Nonno che mi ha sempre detto che «libertà significa responsabilità.» Non potrei essere più d'accordo.
Special thanks to my wife, Amy, for her love and patient support, for putting up with late nights, and for even reviewing entire sections of this book—you always go the extra mile, and do so with incredible grace. Gavin, when you're old enough to read, I hope you're as proud of your Daddy as he is of you. Mom and Dad (and the rest of the family), thanks for your constant support and enthusiasm.
Un ringraziamento speciale a mia moglie, Amy, per il suo amore e paziente sostegno, per aver sopportato pazientemente di stare alzata fino a notte fonda, e per aver persino revisionato intere sezioni di questo libro—fai sempre più di quello che ci si aspetta e lo fai con una grazia incredibile. Gavin, quando sarai abbastanza grande per leggere, spero che tu possa essere orgoglioso di tuo padre come lui lo è di te. Mamma e papà (e il resto della famiglia), grazie per il vostro costante sostegno ed entusiamo.
Hats off to Shep Kendall, through whom the world of
computers was first opened to me; Ben Collins-Sussman, my
tour-guide through the open-source world; Karl Fogel—you
are my .emacs; Greg
Stein, for oozing practical programming know-how; Brian
Fitzpatrick—for sharing this writing experience with me.
To the many folks from whom I am constantly picking up new
knowledge—keep dropping it!
Giù il cappello per Shep Kendall, il quale mi ha introdotto al
mondo dei computer; Ben Collins-Sussman, la mia guida turistica
nel mondo open-source; Karl Fogel— tu
sei il mio .emacs; Greg
Stein, per aver distillato conoscenze pratiche di programmazione;
Brian Fitzpatrick— per avere condiviso come me questa esperienza di scrittura.
A tutti coloro dai quali costantemente raccolgo nuova conoscenza
—continuate a lasciarla cadere!
Finally, to the One who perfectly demonstrates creative excellence—thank you.
Infine, all'Unico che davvero dimostra eccellenza creativa — grazie a te.
Indice
Version control is the art of managing changes to information. It has long been a critical tool for programmers, who typically spend their time making small changes to software and then undoing those changes the next day. But the usefulness of version control software extends far beyond the bounds of the software development world. Anywhere you can find people using computers to manage information that changes often, there is room for version control. And that's where Subversion comes into play.
Il controllo di versione è l'arte di gestire i cambiamenti delle informazioni. È stato per molto tempo uno strumento critico per i programmatori che, tipicamente, passano le loro giornate ad effettuare piccoli cambiamenti al software per poi cancellare le modifiche il giorno seguente. Ma l'utilità di un software di versionamento si estende ben oltre i confini del mondo dello sviluppo di software. Ovunque ci siano persone che utilizzano il computer per gestire informazioni che cambiano di frequente, lì trova spazio il controllo di versione. Qui entra in gioco Subversion.
This chapter contains a high-level introduction to Subversion—what it is; what it does; how to get it.
Questo capitolo contiene un'introduzione di alto livello a Subversion—cos'è; cosa fa; come ottenerlo.
Subversion is a free/open-source version control system. That is, Subversion manages files and directories over time. A tree of files is placed into a central repository. The repository is much like an ordinary file server, except that it remembers every change ever made to your files and directories. This allows you to recover older versions of your data, or examine the history of how your data changed. In this regard, many people think of a version control system as a sort of “time machine”.
Subversion è un sistema di controllo di versione libero e open-source. Cioè Subversion gestisce file e directory nel tempo. Un'alberatura di file è inserita all'interno di un repository centrale. Il repository è paragonabile ad un file server, in più esso ricorda qualsiasi cambiamento apportato ai file e alle directory. Ciò permette di ripristinare vecchie versioni dei dati o di esaminare lo storico dei cambiamenti. Per questo motivo, molte persone considerano un sistema di controllo di versione come una sorta di «macchina del tempo».
Subversion can access its repository across networks, which allows it to be used by people on different computers. At some level, the ability for various people to modify and manage the same set of data from their respective locations fosters collaboration. Progress can occur more quickly without a single conduit through which all modifications must occur. And because the work is versioned, you need not fear that quality is the trade-off for losing that conduit—if some incorrect change is made to the data, just undo that change.
Subversion può accedere al suo repository attraverso reti di computer; ciò gli permette di essere utilizzato da più persone contemporaneamente su più computer. In qualche modo, la possibilità per più persone di modificare e gestire lo stesso insieme di dati, dalle rispettive postazioni, alimenta la collaborazione. I Miglioramenti possono intervenire più velocemente se le modifiche non devono per forza passare per un unico canale. Dato che il lavoro è sotto controllo di versione, non c'è da temere che la qualità scadente sia il prezzo da pagare per poter evitare quell'unico canale—se vengono applicate ai dati alcune modifiche non corrette, basta annullare tali cambiamenti.
Some version control systems are also software configuration management (SCM) systems. These systems are specifically tailored to manage trees of source code, and have many features that are specific to software development—such as natively understanding programming languages, or supplying tools for building software. Subversion, however, is not one of these systems. It is a general system that can be used to manage any collection of files. For you, those files might be source code—for others, anything from grocery shopping lists to digital video mixdowns and beyond.
Alcuni sistemi per il controllo di versione sono anche sistemi di software configuration management (SCM). Questi sistemi sono orientati specificatamente alla gestione di alberature di codice sorgente e hanno molte caratteristiche che sono specifiche dello sviluppo software—come la capacità nativa di riconoscere i linguaggi di programmazione o l'integrazione di strumenti per la compilazione del software. Subversion, tuttavia, non è uno di questi sistemi. È un sistema generico che può essere utilizzato per gestire qualsiasi insieme di file. Per qualcuno questi file possono contenere codice sorgente—per altri qualunque altra cosa, dalla lista della spesa a montaggi video digitali e così via.
In early 2000, CollabNet, Inc. (http://www.collab.net) began seeking developers to write a replacement for CVS. CollabNet offers a collaboration software suite called CollabNet Enterprise Edition (CEE) [3] of which one component is version control. Although CEE used CVS as its initial version control system, CVS's limitations were obvious from the beginning, and CollabNet knew it would eventually have to find something better. Unfortunately, CVS had become the de facto standard in the open source world largely because there wasn't anything better, at least not under a free license. So CollabNet determined to write a new version control system from scratch, retaining the basic ideas of CVS, but without the bugs and misfeatures.
All'inizio del 2000, CollabNet, Inc. (http://www.collab.net) iniziò a cercare sviluppatori per scrivere un software che sostituisse CVS. CollabNet offre una suite di software collaborativi chiamata CollabNet Enterprise Edition (CEE) [4] di cui un componente è il controllo di versione. Sebbene CEE usasse inizialmente CVS come sistema di versionamento, le limitazioni di CVS erano evidenti fin dal principio e CollabNet sapeva che alla fine avrebbe dovuto trovare qualcosa di meglio. Sfortunatamente, CVS nel frattempo era diventato lo standard de facto nel mondo open source, principalmente perché non c'era nulla di meglio, per lo meno non sotto una licenza libera. Così CollabNet decise di scrivere da zero un nuovo sistema per il controllo di versione, mantenendo l'idea base di CVS ma evitando i suoi bug e aggiungendo funzionalità.
In February 2000, they contacted Karl Fogel, the author of Open Source Development with CVS (Coriolis, 1999), and asked if he'd like to work on this new project. Coincidentally, at the time Karl was already discussing a design for a new version control system with his friend Jim Blandy. In 1995, the two had started Cyclic Software, a company providing CVS support contracts, and although they later sold the business, they still used CVS every day at their jobs. Their frustration with CVS had led Jim to think carefully about better ways to manage versioned data, and he'd already come up with not only the name “Subversion”, but also with the basic design of the Subversion repository. When CollabNet called, Karl immediately agreed to work on the project, and Jim got his employer, Red Hat Software, to essentially donate him to the project for an indefinite period of time. CollabNet hired Karl and Ben Collins-Sussman, and detailed design work began in May. With the help of some well-placed prods from Brian Behlendorf and Jason Robbins of CollabNet, and Greg Stein (at the time an independent developer active in the WebDAV/DeltaV specification process), Subversion quickly attracted a community of active developers. It turned out that many people had had the same frustrating experiences with CVS, and welcomed the chance to finally do something about it.
Nel febbraio del 2000, fu contattato Karl Fogel, l'autore del libro Open Source Development with CVS (Coriolis, 1999), al quale fu chiesto se avrebbe avuto piacere di lavorare su questo nuovo progetto. Coincidenza volle che, in quel periodo, Karl stesse già lavorando a un progetto per un nuovo sistema di versionamento con il suo amico Jim Blandy. Nel 1995, i due avevano fondato la Cyclic Software, una compagnia che si occupava di fornire supporto all'utilizzo di CVS e, sebbene in seguito essi avessero ceduto la loro attività, avevano continuato ad utilizzare CVS nel loro lavoro di tutti i giorni. La loro frustrazione nel lavorare con CVS, aveva portato Jim a ragionare accuratamente per trovare modi migliori per gestire dati versionati e aveva già ideato non solo il nome «Subversion», ma anche il progetto di base del repository Subversion. Quando CollabNet li contattò, Karl accettò immediatamente di lavorare al progetto, e Jim ottenne dalla sua azienda, la Red Hat Software, sostanzialmente di potersi dedicare al progetto a tempo indeterminato. CollabNet assunse Karl e Ben Collins-Sussman e il lavoro vero e proprio sul progetto iniziò nel mese di maggio. Con l'aiuto di alcune spinte nella giusta direzione da parte di Brian Behlendorf e Jason Robbins di CollabNet e di Greg Stein (al tempo sviluppatore indipendente attivo nel processo di specifica di WebDAV/DeltaV), Subversion in breve tempo attrasse intorno a sé una gruppo di attivi sviluppatori. Ciò dimostrava che molte persone avevano avuto le stesse frustranti esperienze con CVS, e accoglievano con entusiasmo la possibilità di fare finalmente qualcosa per migliorarlo.
The original design team settled on some simple goals. They didn't want to break new ground in version control methodology, they just wanted to fix CVS. They decided that Subversion would match CVS's features, and preserve the same development model, but not duplicate CVS's most obvious flaws. And although it did not need to be a drop-in replacement for CVS, it should be similar enough that any CVS user could make the switch with little effort.
Il team di sviluppo originario si concentrò su alcuni semplici obiettivi. Essi non volevano introdurre un nuovo approccio nella metodologia del controllo di versione ma volevano solamente migliorare CVS. Decisero che Subversion avrebbe incluso le caratteristiche di CVS e preservato il medesimo modello di sviluppo, ma non avrebbe riproposto le sue più ovvie debolezze. E sebbene il loro software non avesse bisogno di presentarsi come una copia di CVS, sarebbe comunque dovuto essere abbastanza simile da permettere a qualsiasi utente di CVS di cambiare e utilizzare Subversion con pochissima fatica.
After fourteen months of coding, Subversion became “self-hosting” on August 31, 2001. That is, Subversion developers stopped using CVS to manage Subversion's own source code, and started using Subversion instead.
Dopo quattordici mesi passati a scrivere codice, Subversion divenne «self-hosting» il 31 agosto 2001. Da quel momento, cioè, gli sviluppatori smisero di utilizzare CVS per gestire il codice di Subversion e iniziarono ad utilizzare Subversion stesso.
While CollabNet started the project, and still funds a large chunk of the work (it pays the salaries of a few full-time Subversion developers), Subversion is run like most open-source projects, governed by a loose, transparent set of rules that encourage meritocracy. CollabNet's copyright license is fully compliant with the Debian Free Software Guidelines. In other words, anyone is free to download, modify, and redistribute Subversion as he pleases; no permission from CollabNet or anyone else is required.
Sebbene CollabNet abbia avviato il progetto e tuttora finanzi la maggior parte del lavoro (paga lo stipendio di un piccolo gruppo di sviluppatori che lavora su Subversion a tempo pieno), Subversion viene portato avanti come la maggior parte dei progetti open-source, gestito attraverso un insieme di regole aperto e trasparente che incoraggia la meritocrazia. La licenza di copyright di CollabNet rispetta pienamente le linee guida Debian Free Software. In altre parole, chiunque è libero di scaricare, modificare e redistribuire Subversion come preferisce; senza richiedere alcun permesso a CollabNet o a chiunque altro.
When discussing the features that Subversion brings to the version control table, it is often helpful to speak of them in terms of how they improve upon CVS's design. If you're not familiar with CVS, you may not understand all of these features. And if you're not familiar with version control at all, your eyes may glaze over unless you first read Capitolo 2, Concetti base, in which we provide a gentle introduction to version control in general.
Discutere le caratteristiche che Subversion porta al tavolo del controllo di versione, è spesso utile per approfondire in che modo tali peculiarità apportino miglioramenti alla struttura di CVS. Se non si ha familiarità con CVS, si rischia di non comprenderne a dovere l'efficacia. Se, poi, il lettore non ha dimestichezza con il controllo di versione in generale, i suoi occhi potrebbero coprirsi di una patina a meno che non si legga prima Capitolo 2, Concetti base, nel quale viene fornita una precisa introduzione al generale concetto di versionamento.
Subversion provides:
Subversion offre:
CVS only tracks the history of individual files, but Subversion implements a “virtual” versioned filesystem that tracks changes to whole directory trees over time. Files and directories are versioned.
Solo CVS traccia la storia dei soli files, mentre Subversion implementa il versionamento di un filesystem «virtuale» che traccia i cambiamenti nel tempo degli interi alberi directory. I files e le directory vengono quindi versionate.
Since CVS is limited to file versioning, operations such as copies and renames—which might happen to files, but which are really changes to the contents of some containing directory—aren't supported in CVS. Additionally, in CVS you cannot replace a versioned file with some new thing of the same name without the new item inheriting the history of the old—perhaps completely unrelated—file. With Subversion, you can add, delete, copy, and rename both files and directories. And every newly added file begins with a fresh, clean history all its own.
Dal momento che CVS è limitato al versionamento dei soli files, operazioni come copia e rinomina—che dovrebbero essere propri dei files, ma che poi non sono altro che modifiche ai contenuti di ciò che contiene una directory—non sono supportate in CVS. In più, in CVS non è possibile rimpiazzare un file versionato con un nuovo file che ne erediti il nome ma non la storia—perché completamente differente dal vecchio file. Con Subversion, è possibile aggiungere, cancellare, copiare e rinominare sia files che directories. E ogni file aggiunto nuovamente, inizia con una storia nuova e pulita tutta per se.
A collection of modifications either goes into the repository completely, or not at all. This allows developers to construct and commit changes as logical chunks, and prevents problems that can occur when only a portion of a set of changes is successfully sent to the repository.
Un insieme di modifiche o vengono inserite nel repository tutte insieme o non ne viene inserita nessuna. Ciò permette agli sviluppatori di costruire ed effettuare commit di cambiamenti come un blocco logico unico, prevenendo problemi che possono occorrere quando solo una parte di un set di modifiche vengono inviate con successo al repository.
Each file and directory has a set of properties—keys and their values—associated with it. You can create and store any arbitrary key/value pairs you wish. Properties are versioned over time, just like file contents.
Ogni file e directory ha un set di proprietà—chiavi e rispettivi valori—ad esso associati . L'utilizzatore può creare e memorizzare arbitrariamente qualsiasi coppia di chiave/valore che preferisce. Le proprietà sono soggette a versionamento esattamente come il file a cui sono associate.
Subversion has an abstracted notion of repository access, making it easy for people to implement new network mechanisms. Subversion can plug into the Apache HTTP Server as an extension module. This gives Subversion a big advantage in stability and interoperability, and instant access to existing features provided by that server—authentication, authorization, wire compression, and so on. A more lightweight, standalone Subversion server process is also available. This server speaks a custom protocol which can be easily tunneled over SSH.
Subversion ha una nozione astratta di accesso al repository, che rende semplice per chiunque implementare nuovi meccanismi di accesso via rete. Inoltre è possibile integrarlo con Apache HTTP Server, come modulo di estensione. Ciò conferisce a Subversion un grande vantaggio in stabilità e interoperabilità, oltre ad un accesso istantaneo alle caratteristiche che tale webserver mette a disposizione—autenticazione, autorizzazione, wire compression, e così via. È comunque disponibile anche un processo server a se stante e 'leggero' dedicato a Subversion. Questo server è progettato su un protocollo proprio che può essere facilmente veicolato su SSH.
Subversion expresses file differences using a binary differencing algorithm, which works identically on both text (human-readable) and binary (human-unreadable) files. Both types of files are stored equally compressed in the repository, and differences are transmitted in both directions across the network.
Subversion esprime le differenze di un file usando un algoritmo di differenziazione binario, che lavora ugualmente sia sui files di testo (leggibili dall'uomo) che sui files binari (illeggibili dall'uomo). Entrambi i tipi di files sono memorizzati ugualmente compressi nel repository e le differenze sono trasmesse in entrambi i casi attraverso la rete.
The cost of branching and tagging need not be proportional to the project size. Subversion creates branches and tags by simply copying the project, using a mechanism similar to a hard-link. Thus these operations take only a very small, constant amount of time.
Il costo in termini di tempo e spazio dedicato al branching e al tagging non deve essere proporzionale alla grandezza del progetto. Subversion crea branches e tags utilizzando un meccanismo simile all'hard-link unix (collegamento) per copiare il progetto. In questo modo, tali operazioni occupano solo una quantità di tempo molto breve e costante.
Subversion has no historical baggage; it is implemented as a collection of shared C libraries with well-defined APIs. This makes Subversion extremely maintainable and usable by other applications and languages.
Subversion non ha alcun bagaglio storico; è implementato come una collezione di librerie C condivise con delle APIs ben definite. Ciò lo rende estremamente mantenibile e utilizzabile da altre applicazioni e in altre lingue.
Figura 1.1, «Architettura di Subversion» illustra ciò che si può chiamare una vista «dall'altezza di un miglio» dell'architettura di Subversion.
On one end is a Subversion repository that holds all of your versioned data. On the other end is your Subversion client program, which manages local reflections of portions of that versioned data (called “working copies”). Between these extremes are multiple routes through various Repository Access (RA) layers. Some of these routes go across computer networks and through network servers which then access the repository. Others bypass the network altogether and access the repository directly.
Ad un estremo c'è il repository Subversion che contiene tutti i vostri dati sotto controllo di versione. All'altro estremo c'è il vostro client Subversion, che gestisce le specchiature locali di parte dei dati sotto controllo di versione (chiamate «copie locali»). Tra questi estremi vi sono diversi percorsi tramite vari strati per l'Accesso al Repository (AR). Alcune di queste strade attraversano reti di computer e reti di server che che a loro volta accedono il repository. Altre scavalcano del tutto la rete ed accedono direttamente il repository.
Subversion is built on a portability layer called APR—the Apache Portable Runtime library. The APR library provides all the interfaces that Subversion needs to function on different operating systems: disk access, network access, memory management, and so on. While Subversion is able to use Apache as one of its network server programs, its dependence on APR does not mean that Apache is a required component. APR is a standalone library useable by any application. It does mean, however, that like Apache, Subversion clients and servers run on any operating system that the Apache httpd server runs on: Windows, Linux, all flavors of BSD, Mac OS X, Netware, and others.
Subversion è costruito su uno strato portabile chiamato APR— la libreria Apache Portable Runtime. La libreria APR fornisce tutte le interfaccie per le funzioni richieste da Subversion per funzionare su diversi sistemi operativi: l'accesso al disco, alla rete, la gestione della memoria e così via. Anche se Subversion è in grado di utilizzare Apache come uno dei possibili componenti lato server, la sua dipendenza da APR non significa che Apache sia un componente rihiesto per funzionare. Significa, comunque, che come Apache, i client ed i server di Subversion funzionano su ogni sistema operativo sul quale gira il server httpd Apache: Windows, Linux, tutte le varianti di BSD, MAc OS X, Netware ed altri.
The easiest way to get Subversion is to download a binary package built for your operating system. Subversion's website (http://subversion.tigris.org) often has these packages available for download, posted by volunteers. The site usually contains graphical installer packages for users of Microsoft operating systems. If you run a Unix-like operating system, you can use your system's native package distribution system (RPMs, DEBs, the ports tree, etc.) to get Subversion.
Il modo più facile per ottenere Subversion è scaricare il pacchetto di eseguibili già pronto per il vostro sistema operativo. Il sito web di Subversion (http://subversion.tigris.org) rende disponibili questi pacchetti, preparati ed inviati da volontari. Il sito normalmente contiene pacchetti d'installazione grafici per gli utenti dei sistemi operativi Microsoft. Se siete utenti di un sistema operativo di tipo Unix, per ottenere Subversion potete utilizzare i sistemi di distribuzione nativi per il vostro sistema (RPMs. DEBs, ports tree, etc.).
Alternately, you can build Subversion directly from source
code. From the Subversion website, download the latest
source-code release. After unpacking it, follow the
instructions in the INSTALL file to build
it. Note that a released source package contains everything you
need to build a command-line client capable of talking to a
remote repository (in particular, the apr, apr-util, and neon
libraries). But optional portions of Subversion have many other
dependencies, such as Berkeley DB and possibly Apache httpd. If
you want to do a complete build, make sure you have all of the
packages documented in the INSTALL file.
If you plan to work on Subversion itself, you can use your
client program to grab the latest, bleeding-edge source code.
This is documented in la sezione chiamata «Prendere il codice sorgente».
Come alternativa, si può costruire Subversion direttamente dai codici sorgenti.
Scaricate l'ultima release del codice sorgente dal sito web di Subversion.
Dopo averlo spacchettato, seguite le istruzioni contenute nel file
INSTALL per costruirlo.
Da notare che un pacchetto di sorgenti rilasciato, contiene tutto ciò di
cui si necessiti per costruire un client a linea di comando in grado di parlare con
un repository remoto (in particolare, apr, apr-util, e le librerie neon).
Ma parti opzionali di Subversion hanno molte altre dipendenze, come il DB Berkeley ed anche
Apace httpd.
Se volete realizzare una costruzione completa, siate sicuri di avere tutti i pacchetti
descritti nel file INSTALL.
Se avete intenzione di lavorare su Subversion stesso, potete utilizzare il client
per ottenere l'ultima copia dei sorgenti allineata con la frontiera degli sviluppi.
Ciò è documentato in la sezione chiamata «Prendere il codice sorgente».
Subversion, once installed, has a number of different pieces. The following is a quick overview of what you get. Don't be alarmed if the brief descriptions leave you scratching your head—there are plenty more pages in this book devoted to alleviating that confusion.
Subversion, una volta installato, possiede un certo numero di differenti pezzi. Segue un veloce riferimento al riguardo. Non allarmatevi se le brevi descrizioni vi lasciano dei grattacapi— in questo libro ci sono molte altre pagine dedicate ad alleviare la vostra confusione.
The command-line client program.
Il client a linea di comando.
A program for reporting the state (in terms of revisions of the items present) of a working copy.
Un programma per conoscere lo stato (in termini di revisione degli elementi presenti) di una copia di lavoro.
A tool for inspecting a Subversion repository.
Un tool per ispezionare una repository Subversion.
A tool for creating, tweaking or repairing a Subversion
Un tool per creare, operare e riparare una repository Subversion.
A program for filtering Subversion repository dump streams.
Un programma per filtrare i flussi di dump di una repository Subversion.
A plug-in module for the Apache HTTP Server, used to make your repository available to others over a network.
Un modulo plug-in per il Server Apache HTTP, usato per rendere disponibile ad altri la vostra repository via rete.
A custom standalone server program, runnable as a daemon process or invokable by SSH; another way to make your repository available to others over a network.
Un programma server specializzato per essere eseguito come un processo demone oppure essere invocato tramite SSH; un altro modo per rendere accessibile via rete ad altri il vostro repository.
Assuming you have Subversion installed correctly, you should be ready to start. The next two chapters will walk you through the use of svn, Subversion's command-line client program.
Assumendo di avere Subversion correttamente installato, dovreste essere pronti a partire. I prossimi due capitoli vi condurranno attraverso l'uso di svn il client command line di Subversion.
Some people have trouble absorbing a new technology by reading the sort of “top down” approach provided by this book. This section is a very short introduction to Subversion, and is designed to give “bottom up” learners a fighting chance. If you prefer to learn by experimentation, the following demonstration will get you up and running. Along the way, we give links to the relevant chapters of this book.
Alcune persone hanno dei problemi ad assorbire una nuova tecnologia tramite l'approccio «top down» di questo libro. Questa sezione è un'introduzione a Subversion molto sintetica, ed è pensata per fornire una possibilità in più a chi è abituato ad imparare con un approccio «bottom up». Se si preferisce imparare sperimentando, gli esempi seguenti vi permetteranno di essere subito operativi. Strada facendo, saranno evidenziati i collegamenti ai capitoli più importanti di questo libro.
If you're new to the entire concept of version control or to the “copy-modify-merge” model used by both CVS and Subversion, then you should read Capitolo 2, Concetti base before going any further.
Se per voi sono nuovi sia l'insieme dei concetti di controllo di versione, sia il modello «copia-modifica-fusione (copy-modify-merge)» usato sia da CVS che da Subversion, allora dovreste leggere Capitolo 2, Concetti base prima di andare avanti.
![]() | Nota |
|---|---|
The following example assumes that you have svn, the Subversion command-line client, and svnadmin, the administrative tool, ready to go. It also assumes you are using Subversion 1.2 or later (run svn --version to check.) Il seguente esempio assume di avere pronti all'uso svn, il client a linea di comando di Subversion, e svnadmin, il tool di amministrazione. Si assume anche che stiate usando Subversion 1.2 o successivo (usare il comando svn --version per controllare.) |
Subversion stores all versioned data in a central repository. To begin, create a new repository:
Subversion memorizza tutti i dati sotto controllo di versione in un repository centrale. Per iniziare, creiamo un nuovo repoitory:
$ svnadmin create /path/to/repos $ ls /path/to/repos conf/ dav/ db/ format hooks/ locks/ README.txt
This command creates a new directory
/path/to/repos which contains a Subversion
repository. This new directory contains (among other things) a
collection of database files. You won't see your versioned
files if you peek inside. For more information about repository
creation and maintenance, see
Capitolo 5, Repository Administration.
Questo comando crea una nuova directory
/path/to/repos che contiene un repository Subversion.
Questa nuova directory contiene (tra le altre cose) un insieme di files di database.
Non vedreste i vostri file sotto il controllo di versione se provaste a sbirciarci dentro.
Per maggiori informazioni riguardo la creazione e la manutenzione del repository, vedi anche
Capitolo 5, Repository Administration.
Subversion has no concept of a “project”. The repository is just a virtual versioned filesystem, a large tree that can hold anything you wish. Some administrators prefer to store only one project in a repository, and others prefer to store multiple projects in a repository by placing them into separate directories. The merits of each approach are discussed in la sezione chiamata «Choosing a Repository Layout». Either way, the repository only manages files and directories, so it's up to humans to interpret particular directories as “projects”. So while you might see references to projects throughout this book, keep in mind that we're only ever talking about some directory (or collection of directories) in the repository.
Subversion non ha il concetto di «progetto». Il repository è solo un filesystem virtuale versionato, un albero di directory molto vasto che può conservare ciò che si desidera. Alcuni sistemisti preferiscono memorizzare solo un progetto per repository alti memorizzano più progetti in un repository ponendoli in directory separate. I pregi di ogni approcci sono discussi in la sezione chiamata «Choosing a Repository Layout». Ad ogni modo il repository gestisce solo file e directory, in tal senso è copito degli umani interpretare le particolari directory, come «projects». Per questo ogni qual volta in questo libro venga fatto riferimento ai progetti, si tenga presente che è come se si parlasse di directory (od insiemi di directories) nel repository.
In this example, we assume that you already have some sort
of project (a collection of files and directories) that you wish
to import into your newly created Subversion repository. Begin
by organizing them into a single directory
called myproject (or whatever you wish).
For reasons that will be clear later (see
Capitolo 4, Ramificazioni e fusioni), your project's tree
structure should contain three top-level directories
named branches,
tags, and
trunk. The trunk
directory should contain all of your data,
while branches
and tags directories are empty:
In questo esempio, si assume di avere una qualche sorta di progetto
(un insieme di files e directories) che vorreste importare in un repository
appena creato.
Iniziamo organizzandoli in una sola directory chiamata myproject
(oppure un qualunque altro nome vi piaccia).
Per ragioni che saranno chiare tra poco (vedi Capitolo 4, Ramificazioni e fusioni),
l'alberatura del vostro progetto dovrà contenere tre directory di livello piu' alto
chiamate branches,
tags, and
trunk. La directory trunk
conterrà tutti i vostri dati,
mentre le directory branches
e tags sono vuote:
/tmp/myproject/branches/
/tmp/myproject/tags/
/tmp/myproject/trunk/
foo.c
bar.c
Makefile
…
The branches, tags,
and trunk subdirectories aren't actually
required by Subversion. They're merely a popular convention
that you'll most likely want to use later on.
Le sottodirectory branches, tags,
e trunk non sono in realta' richieste da Subversion
Sono semplicemente una convenzione comune che molto probabilmente
vorrete usare in seguito anche voi.
Once you have your tree of data ready to go, import it into the repository with the svn import command (see la sezione chiamata «svn import»):
Non appena la vostra struttura di directory è pronta, importatela in una repository svn con il comando svn import (see la sezione chiamata «svn import»):
$ svn import /tmp/myproject file:///path/to/repos/myproject -m "initial import" Adding /tmp/myproject/branches Adding /tmp/myproject/tags Adding /tmp/myproject/trunk Adding /tmp/myproject/trunk/foo.c Adding /tmp/myproject/trunk/bar.c Adding /tmp/myproject/trunk/Makefile … Committed revision 1. $
Now the repository contains this tree of data. As mentioned
earlier, you won't see your files by directly peeking into the
repository; they're all stored within a database. But the
repository's imaginary filesystem now contains a top-level
directory named myproject, which in turn
contains your data.
Ora il repository contiene questa struttura di directory. Come citato prima,
non vedreste i vostri file sbirciando direttamente nel repository;
sono tutti memorizzati all'interno di un database. Ma il filesystem immaginario
del repository ora contiene una directory di livello più alto chiamata
myproject, che contiene i vostri dati.
Note that the original /tmp/myproject
directory is unchanged; Subversion is unaware of it. (In fact,
you can even delete that directory if you wish.) In order to
start manipulating repository data, you need to create a new
“working copy” of the data, a sort of private
workspace. Ask Subversion to “check out” a working
copy of the myproject/trunk directory in
the repository:
Notare che la directory originaria /tmp/myproject
non e' cambiata; Subversion non lo sa. (Infatti, potete anche cancellare quella
directory se volete.) Per essere in grado di iniziare a manipolare i dati nel repository,
avete bisogno di creare una nuova «copia di lavoro (working copy)» dei dati,
una sorta di spazio di lavoro privato.
Domandate a Subversion di effettuare un «check out» della copia di lavoro
della directory myproject/trunk memorizzata nel repository:
$ svn checkout file:///path/to/repos/myproject/trunk myproject A myproject/foo.c A myproject/bar.c A myproject/Makefile … Checked out revision 1.
Now you have a personal copy of part of the repository in a
new directory named myproject. You can edit
the files in your working copy and then commit those changes
back into the repository.
Ora avete una copia personale di parte del repository
in una nuova directory chiamata myproject.
Potete modificare i files nella copia di lavoro e poi sottomettere a svn (commit)
i cambiamenti nel repository.
Enter your working copy and edit a file's contents.
Entrare nella copia di lavoro e modificare il contento di un file.
Run svn diff to see unified diff output of your changes.
Esegure svn diff per vedere i cambiamenti risultanti in formato unified diff.
Run svn commit to commit the new version of your file to the repository.
Eseguire svn commit per sottomettere a svn la nuova versione del vostro file nel repository.
Run svn update to bring your working copy “up-to-date” with the repository.
Eseguire svn update per «allineare» la vostra copia locale con il contenuto del repository.
For a full tour of all the things you can do with your working copy, read Capitolo 3, Visita guidata.
Per un tour completo riguado tutte le cose che si possono fare con la copia locale, leggere Capitolo 3, Visita guidata.
At this point, you have the option of making your repository available to others over a network. See Capitolo 6, Configurazione del server to learn about the different sorts of server processes available and how to configure them.
A questo punto, potete scegliere di rendere accessibile il vostro repository via rete. Consultare anche Capitolo 6, Configurazione del server per imparare riguardo i diversi tipi di processi server disponibili e come configurarli.
This chapter is a short, casual introduction to Subversion. If you're new to version control, this chapter is definitely for you. We begin with a discussion of general version control concepts, work our way into the specific ideas behind Subversion, and show some simple examples of Subversion in use.
Questo paragrafo è una introduzione corta ed informale a Subversion. Se si è nuovi rispetto al controllo di versione, questo è sicuramente il capitolo più adatto da cui partire. Inizieremo con una introduzione ai concetti generali del controllo di versione, approfondiremo le idee specifiche che sono dietro Subversion ed illustreremo qualche semplice esempio di Subversion in uso.
Even though the examples in this chapter show people sharing collections of program source code, keep in mind that Subversion can manage any sort of file collection—it's not limited to helping computer programmers.
Anche se gli esempi in questo capitolo mostrano persone che condividono collezioni di codice sorgente di programmi, è bene tenere presente che Subversion può gestire qualsiasi tipo di collezione di file — non è limitato ad aiutare programmatori.
Subversion is a centralized system for sharing information. At its core is a repository, which is a central store of data. The repository stores information in the form of a filesystem tree—a typical hierarchy of files and directories. Any number of clients connect to the repository, and then read or write to these files. By writing data, a client makes the information available to others; by reading data, the client receives information from others. Figura 2.1, «Un tipico sistema client/server» illustrates this.
Subversion è un sistema centralizzato per la condivisione delle informazioni. Al suo centro c'è il repository, che è l'archivio principale di dati. Il repository memorizza informazioni nella forma di un filesystem ad albero— la tipica gerarchia di file e directory. Un numero arbitrario di client può connettersi al repository e leggere o scrivere questi file. Scrivendo i dati, un client rende le informazioni disponibili agli altri; leggendo i dati, il client riceve le informazioni dagli altri. Figura 2.1, «Un tipico sistema client/server» illustra il meccanismo.
So why is this interesting? So far, this sounds like the definition of a typical file server. And indeed, the repository is a kind of file server, but it's not your usual breed. What makes the Subversion repository special is that it remembers every change ever written to it: every change to every file, and even changes to the directory tree itself, such as the addition, deletion, and rearrangement of files and directories.
Perché quindi questo aspetto dovrebbe sembrare interessante? Inizialmente potrebbe sembrare la tipica definizione di un file server. In effetti il repository è una sorta di file server, ma non nell'accezione comune. Quello che rende Subversion un repository speciale è che ricorda qualsiasi cambiamento scritto in esso: ogni cambiamento ad ogni file, e perfino modifiche allo stesso albero delle directory, come l'aggiunta, la cancellazione ed il riarrangiamento di file e directory.
When a client reads data from the repository, it normally sees only the latest version of the filesystem tree. But the client also has the ability to view previous states of the filesystem. For example, a client can ask historical questions like, “What did this directory contain last Wednesday?” or “Who was the last person to change this file, and what changes did he make?” These are the sorts of questions that are at the heart of any version control system: systems that are designed to record and track changes to data over time.
Quando un client legge i dati dal repository, normalmente vede solo l'ultima versione dell'albero del filesystem. Il client in realtà ha anche la possibilità di vedere uno stato precedente del filesystem. Ad esempio, un client può chiedere domande storiche come «Cosa conteneva questa directory l'ultimo Mercoledì?» oppure «Chi è stata l'ultima persona a cambiare questo file, e che modifiche ha apportato?». Queste sono le tipologie di domande che sono alla base di qualsiasi sistema di controllo di versione: sistemi che sono progettati per registrare e tenere traccia delle modifiche ai dati nel tempo.
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à.
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 la 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 la 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 la 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 la 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 la 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 la 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.
We've covered a number of fundamental Subversion concepts in this chapter:
In questo capitolo sono stati affrontati alcuni concetti fondamentali di Subversion:
We've introduced the notions of the central repository, the client working copy, and the array of repository revision trees.
Sono state introdotte le nozioni di repository centrale, copia di lavoro e serie di alberi di revisione.
We've seen some simple examples of how two collaborators can use Subversion to publish and receive changes from one another, using the “copy-modify-merge” model.
Si è visto qualche semplice esempio di come due collaboratori possano usare Subversion per pubblicare e ricevere le modifiche l'uno dall'altro secono il modello «copia-modifica-fondi».
We've talked a bit about the way Subversion tracks and manages information in a working copy.
Si è parlato di come Subversion traccia e gestisce le informazioni in una copia di lavoro
At this point, you should have a good idea of how Subversion works in the most general sense. Armed with this knowledge, you should now be ready to jump into the next chapter, which is a detailed tour of Subversion's commands and features.
A questo punto, si dovrebbe avere una buona idea di come lavora Subversion nel senso più generale. Armati di questa conoscenza si dovrebbe essere ora pronti a passare al prossimo capitolo, che rappresenta un'analisi dettagliata dei comandi e delle caratteristiche di Subversion.
Indice
Now we will go into the details of using Subversion. By the time you reach the end of this chapter, you will be able to perform almost all the tasks you need to use Subversion in a normal day's work. You'll start with an initial checkout of your code, and walk through making changes and examining those changes. You'll also see how to bring changes made by others into your working copy, examine them, and work through any conflicts that might arise.
Entriamo nei dettagli dell'utilizzo di Subversion. Alla fine di questo capitolo, si sarà in grado di compiere al meglio tutte le attività di cui si ha bisogno per utilizzare Subversion in un normale giorno di lavoro. La prima cosa da fare è il checkout del proprio codice, per poi procedere effettuando modifiche ed esaminando i cambiamenti. Si imparerà anche ad importare cambiamenti fatti da altri nella propria directory di lavoro, ad esaminarli ed a risolvere qualsiasi tipo di conflitto possa nascere.
Note that this chapter is not meant to be an exhaustive list of all Subversion's commands—rather, it's a conversational introduction to the most common Subversion tasks you'll encounter. This chapter assumes that you've read and understood Capitolo 2, Concetti base and are familiar with the general model of Subversion. For a complete reference of all commands, see Capitolo 9, Riferimento completo di Subversion.
Questo capitolo non vuole essere un elenco esaustivo di tutti i comandi di Subversion — piuttosto, è un'introduzione alle più comuni attività che si possono compiere con Subversion. Si assume che sia stato letto e compreso Capitolo 2, Concetti base e che si abbia familiarità con il modello di Subversion. Per un riferimento completo a tutti i comandi si rimanda a Capitolo 9, Riferimento completo di Subversion.
Before reading on, here is the most important command you'll ever need when using Subversion: svn help. The Subversion command-line client is self-documenting—at any time, a quick svn help <subcommand> will describe the syntax, switches, and behavior of the subcommand.
Prima di andare oltre, segue uno dei comando più importanti di cui si ha bisogno quando si usa Subversion: svn help. Il client a riga di comando di Subversion è autoesplicativo — in ogni momento, il veloce ricorso al comando svn help, svn help <subcommand> descriverà la sintassi, le opzioni ed il comportamento del sottocomando
You use svn import to import a new project into a Subversion repository. While this is most likely the very first thing you will do when you set up your Subversion server, it's not something that happens very often. For a detailed description of import, see la sezione chiamata «svn import» later in this chapter.
Per importare un nuovo progetto nel repository di Subversion, si usa il comando svn import. Sebbene questa sia la prima cosa da fare quando si prepara un server Subversion, non è una cosa che si debba fare frequentemente. Per una descrizione dettagliata dell'import si rimanda a la sezione chiamata «svn import» nel seguito di questo capitolo.
Before we go on, you should know a bit about how to identify a particular revision in your repository. As you learned in la sezione chiamata «Revisioni», a revision is a “snapshot” of the repository at a particular moment in time. As you continue to commit and grow your repository, you need a mechanism for identifying these snapshots.
Prima di andare avanti, bisogna sapere qualcosa su come identificare una particolare revisione nel proprio repository. Come si è visto in la sezione chiamata «Revisioni», una revisione è «un'istantanea» del repository fatta in un particolare istante di tempo. Man mano che si continua a fare commit aumentano le dimensioni del repository, perciò bisogna avere un metodo per identificare queste istantanee.
You specify these revisions by using the
--revision (-r) switch plus
the revision you want (svn --revision REV) or
you can specify a range by separating two revisions with a colon
(svn --revision REV1:REV2). And Subversion
lets you refer to these revisions by number, keyword, or
date.
Per specificare le revisioni si usa l'opzione
--revision (-r) unito alla
revisione desiderata (svn --revision REV) oppure si
può specificare un intervallo separando le due revisioni con i due
punti «:» (svn --revision
REV1:REV2).Subversion permette di referenziare queste
revisioni attraverso numeri, chiavi oppure data.
When you create a new Subversion repository, it begins its life at revision zero and each successive commit increases the revision number by one. After your commit completes, the Subversion client informs you of the new revision number:
Quando si crea un nuovo repository Subversion, questo comincia la sua vita dalla revisione zero ed ogni successivo commit incrementa il numero di revisione di uno. Quando si completa la commit, il client Subversion comunica il nuovo numero della revisione:
$ svn commit --message "Corrected number of cheese slices."
Sending sandwich.txt
Transmitting file data .
Committed revision 3.
If at any point in the future you want to refer to that revision (we'll see how and why we might want to do that later in this chapter), you can refer to it as “3”.
Se ad un certo punto in futuro ci si vorrà riferire a quella particolare revisione (si vedrà come e perché si dovrebbe volerlo nel seguito di questo capitolo), ci si potrà riferire ad essa con il numero «3».
The Subversion client understands a number of
revision keywords. These keywords
can be used instead of integer arguments to the
--revision switch, and are resolved into
specific revision numbers by Subversion:
Il client Subversion riconosce un numero di chiavi di
revisioni. Queste chiavi possono essere usate al posto
degli argomenti interi con l'opzione --revision,
e vengono risolte da Subversion in specifici numeri di revisione:
![]() | Nota |
|---|---|
Each directory in your working copy contains an
administrative subdirectory called
Ogni directory della propria copia di lavoro contiene una
sottodirectory di amministrazione chiamata
|
The latest (or “youngest”) revision in the repository.
L'ultima revisione (o «la più recente») nel repository.
The revision number of an item in a working copy. If the item has been locally modified, the «BASE version » refers to the way the item appears without those local modifications.
Il numero di revisione di un oggetto in una copia di lavoro. Se l'oggetto è stato modificato in locale, la «versione BASE» fa riferimento al modo in cui l'oggetto appare senza le modifiche effettuate.
The most recent revision prior to, or equal to,
BASE, in which an item changed.
La revisione più recente prima di, o uguale a
BASE, nella quale è cambiato un oggetto.
The revision immediately before
the last revision in which an item changed.
(Technically, COMMITTED - 1.)
La revisione immediatamente precedente
rispetto all'ultima revisione nella quale è cambiato un
oggetto. (Tecnicamente, COMMITTED - 1.)
![]() | Nota |
|---|---|
|
Here are some examples of revision keywords in action. Don't worry if the commands don't make sense yet; we'll be explaining these commands as we go through the chapter:
Diamo alcuni esempi di chiavi di revisione in azione. Non bisogna preoccuparsi se i comandi sembrano non aver senso; saranno spiegati in seguito.
$ svn diff --revision PREV:COMMITTED foo.c
# shows the last change committed to foo.c
$ svn log --revision HEAD
# shows log message for the latest repository commit
$ svn diff --revision HEAD
# compares your working file (with local changes) to the latest version
# in the repository
$ svn diff --revision BASE:HEAD foo.c
# compares your «pristine» foo.c (no local changes) with the
# latest version in the repository
$ svn log --revision BASE:HEAD
# shows all commit logs since you last updated
$ svn update --revision PREV foo.c
# rewinds the last change on foo.c
# (foo.c's working revision is decreased)
These keywords allow you to perform many common (and helpful) operations without having to look up specific revision numbers or remember the exact revision of your working copy.
Queste chiavi permettono di effettuare le più comuni (ed utili) operazioni senza bisogno di specificare i numeri di revisione o di ricordare l'esatta revisione della propria copia di lavoro.
Anywhere that you specify a revision number or revision keyword, you can also specify a date inside curly braces “{}”. You can even access a range of changes in the repository using both dates and revisions together!
Ovunque si specifichi un numero di revisione o una chiave di revisione, si può anche specificare una data racchiusa fra parentesi graffe «{}». Sarà addirittura possibile accedere ad un insieme di cambiamenti nel repository usando assieme le date e le revisioni!
Here are examples of the date formats that Subversion accepts. Remember to use quotes around any date that contains spaces.
Qui potete trovare alcuni esempi di formati di data accettati da Subversion. Ricordatevi di racchiudere la data tra doppi apici se al suo interno sono presenti degli spazi.
$ svn checkout --revision {2002-02-17}
$ svn checkout --revision {15:30}
$ svn checkout --revision {15:30:00.200000}
$ svn checkout --revision {"2002-02-17 15:30"}
$ svn checkout --revision {"2002-02-17 15:30 +0230"}
$ svn checkout --revision {2002-02-17T15:30}
$ svn checkout --revision {2002-02-17T15:30Z}
$ svn checkout --revision {2002-02-17T15:30-04:00}
$ svn checkout --revision {20020217T1530}
$ svn checkout --revision {20020217T1530Z}
$ svn checkout --revision {20020217T1530-0500}
…
When you specify a date as a revision, Subversion finds the most recent revision of the repository as of that date:
Quando si speicifica una data come revisione, Subversion trova la più recente revisione del repository registrata fino a quella specifica data:
$ svn log --revision {2002-11-28}
------------------------------------------------------------------------
r12 | ira | 2002-11-27 12:31:51 -0600 (Wed, 27 Nov 2002) | 6 lines
…
You can also use a range of dates. Subversion will find all revisions between both dates, inclusive:
Si può anche usare un intervallo di date. Subversion troverà tutte le revisioni comprese tra le due date (estremi compresi):
$ svn log --revision {2002-11-20}:{2002-11-29}
…
As we pointed out, you can also mix dates and revisions:
Come abbiamo visto, è possibile combinare le date e le revisioni:
$ svn log --revision {2002-11-20}:4040
Users should be aware of a subtlety that can become quite a stumbling-block when dealing with dates in Subversion. Since the timestamp of a revision is stored as a property of the revision—an unversioned, modifiable property—revision timestamps can be changed to represent complete falsifications of true chronology, or even removed altogether. This will wreak havoc on the internal date-to-revision conversion that Subversion performs.
Gli utenti dovrebbero fare attenzione ad una sottigliezza che si potrebbe rilevare un ostacolo quando si utilizzano le date in Subversion. Poiché il timestamp di una revisione è salvato come una proprietà della revisione — una proprietà modificabile e non gestita dal sistema di controllo di versione — i timestamp di revisione possono essere modificati per falsificare completamente l'ordine cronologico, o possono essere rimossi completamente. Questo porterà problemi sul sistema di conversione data-revisione utilizzato da Subversion.
Most of the time, you will start using a Subversion
repository by doing a checkout of your
project. Checking out a repository creates a copy of it on your
local machine. This copy contains the HEAD
(latest revision) of the Subversion repository that you specify
on the command line:
La maggior parte delle volte si inizierà ad utilizzare un repository
Subversion, effettuando un checkout di un
determinato progetto. Il checkout crea una copia sulla macchina locale di
un repository. Questa copia contiene la HEAD (ultima
versione) del repository di Subversion che abbiamo specificato dalla
linea di comando:
$ svn checkout http://svn.collab.net/repos/svn/trunk A trunk/subversion.dsw A trunk/svn_check.dsp A trunk/COMMITTERS A trunk/configure.in A trunk/IDEAS … Checked out revision 2499.
Although the above example checks out the trunk directory, you can just as easily check out any deep subdirectory of a repository by specifying the subdirectory in the checkout URL:
Sebbene l'esempio sopra effettui un ckeckout della directory trunk, si può semplicemente effettuare il chekout di una qualunque sottodirectory di un repository specificando la sottodirectory nell'URL
$ svn checkout http://svn.collab.net/repos/svn/trunk/doc/book/tools A tools/readme-dblite.html A tools/fo-stylesheet.xsl A tools/svnbook.el A tools/dtd A tools/dtd/dblite.dtd … Checked out revision 2499.
Since Subversion uses a “copy-modify-merge” model instead of “lock-modify-unlock” (see Capitolo 2, Concetti base), you're already able to start making changes to the files and directories in your working copy. Your working copy is just like any other collection of files and directories on your system. You can edit and change them, move them around, you can even delete the entire working copy and forget about it.
Dal momento che Subversion utilizza un modello «copy-modify-merge» invece di uno «lock-modify-unlock» (see Capitolo 2, Concetti base), possiamo direttamente effettuare cambiamenti sui file e le directory della nostra copia di lavoro. La nostra copia di lavoro è semplicemente come ogni altro file e directory sul nostro sistema. Si possono modificare e spostare, si può anche cancellare l'intera copia di lavoro e dimenticarsi completamente della sua esistenza.
![]() | Nota |
|---|---|
While your working copy is “just like any other collection of files and directories on your system”, you need to let Subversion know if you're going to be rearranging anything inside of your working copy. If you want to copy or move an item in a working copy, you should use svn copy or svn move instead of the copy and move commands provided by your operating system. We'll talk more about them later in this chapter. Mentre la nostra copia di lavoro «è come ogni altro insieme di file e directory sul nostro sistema», dobbiamo far sapere a Subversion se stiamo ridisponendo qualcosa all'interno della copia di lavoro. Se volessimo spostare o copiare un elemento facente parte della copia di lavoro, dovremmo utilizzare svn copy oppure svn move invece dei rispettivi comandi forniti dal sistema operativo da noi utlizzato. Se ne parlerà in modo più approfondito più avanti nel capitolo. |
Unless you're ready to commit a new file or directory, or changes to existing ones, there's no need to further notify the Subversion server that you've done anything.
A meno che non dobbiamo fare una commit di un nuovo file o di una nuova directory, oppure dei cambiamenti effettuati su un file esistente, non è necessario notificare ulteriormente il server Subversion che si sia fatto qualcosa.
While you can certainly check out a working copy with the URL of the repository as the only argument, you can also specify a directory after your repository URL. This places your working copy in the new directory that you name. For example:
Mentre si può certamente effettuare un ckeckout di una copia di lavoro con l'URL del repository come unico argomento, si può anche specificare una directory dopo l'URL del repository. Questo posiziona la copia di lavoro nella directory con quel nome. Ad esempio:
$ svn checkout http://svn.collab.net/repos/svn/trunk subv A subv/subversion.dsw A subv/svn_check.dsp A subv/COMMITTERS A subv/configure.in A subv/IDEAS … Checked out revision 2499.
That will place your working copy in a directory named
subv instead of a directory named
trunk as we did previously.
Questo
posizionerà la nostra working copy nella directory
subv invece che nella directory
trunk come era accaduto precedentemente.
Subversion has numerous features, options, bells and whistles, but on a day-to-day basis, odds are that you will only use a few of them. In this section we'll run through the most common things that you might find yourself doing with Subversion in the course of a day's work.
Subversion ha numerose caratteristiche ed opzioni ed offre moltissime opportunità, ma nel lavoro quotidiano è probabile che serva usarne solo alcune. In questa sezione verrà presentata una panoramica delle cose più comuni che bisogna imparare a fare con Subversion nel corso di un normale giorno di lavoro.
The typical work cycle looks like this:
Un tipico ciclo di lavoro assomiglia grossomodo a questo:
Update your working copy
Aggiornare la propria copia di lavoro
svn update
Make changes
Effettuare cambiamenti
svn add
svn delete
svn copy
svn move
Examine your changes
Esaminare i propri cambiamenti
svn status
svn diff
svn revert
Merge others' changes into your working copy
Far confluire i cambiamenti operati da altri nella propria copia di lavoro
svn update
svn resolved
Commit your changes
Affidare (commit) i propri cambiamenti al repository
svn commit
When working on a project with a team, you'll want to update your working copy to receive any changes made since your last update by other developers on the project. Use svn update to bring your working copy into sync with the latest revision in the repository.
Quando si lavora ad un progetto in gruppo, si dovrà aggiornare la propria copia di lavoro per ricevere tutte le modifiche fatte, dopo l'ultimo aggiornamento, dagli altri sviluppatori. Si usa il comando svn update per allineare la propria copia di lavoro con l'ultima versione nel repository.
$ svn update U foo.c U bar.c Updated to revision 2.
In this case, someone else checked in modifications to
both foo.c and bar.c
since the last time you updated, and Subversion has updated
your working copy to include those changes.
In questo caso, qualcun altro ha effettuato delle modifiche ad
entrambi i file foo.c e
bar.c dall'ultima volta che si è fatto l'update
e Subversion ha aggiornato la copia di lavoro per includere queste
modifiche.
Let's examine the output of svn update a bit more. When the server sends changes to your working copy, a letter code is displayed next to each item to let you know what actions Subversion performed to bring your working copy up-to-date:
Andiamo ad esaminare un po' meglio l'output del comando svn update. Quando il server invia le modifiche alla propria copia di lavoro, viene visualizzata una lettera subito prima di ogni elemento per indicare l'azione compiuta da Subversion per aggiornare la copia di lavoro:
U fooFile foo was
Updated (received changes
from the server).
Il file foo è stato
Updated (Aggiornato, ha
ricevuto le modifiche dal server).
A fooFile or directory foo was
Added to your working
copy.
Il file o la directory foo è stato
Added (Aggiunto) alla vostra
copia di lavoro locale.
D fooFile or directory foo was
Deleted from your working
copy.
Il file o la directory foo è stato
Deleted (Cancellato) dalla
vostra copia di lavoro locale.
R fooFile or directory foo was
Replaced in your working
copy; that is, foo was deleted, and a
new item with the same name was added. While they may have
the same name, the repository considers them to be distinct
objects with distinct histories.
Il file o la directory foo è stato
Replaced (Sostituito) nella
vostra copia di lavoro; il che significa che
foo è stato cancellato, ed un nuovo
oggetto con lo stesso nome è stato aggiunto. Nonostante possano
avere lo stesso nome, il repository li considera due oggetti
distinti con storie distinte.
G fooFile foo received new changes
from the repository, but your local copy of the file had
your modifications. Either the changes did not intersect,
or the changes were exactly the same as your local
modifications, so Subversion has successfully
merGed the repository's
changes into the file without a problem.
Il file foo ha ricevuto le nuove
modifiche dal repository, ma la copia locale del file ha
conservato le proprie modifiche. Sia che le modifiche non
coincidano o che siano le stesse, Subversion ha fatto
confluire con successo le modifiche presenti nel repository nel
file senza problemi.
C fooFile foo received
Conflicting changes from
the server. The changes from the server directly overlap
your own changes to the file. No need to panic, though.
This overlap needs to be resolved by a human (you); we
discuss this situation later in this chapter.
Il file foo ha ricevuto modifiche
Conflicting (Conflittuali) dal
server. Le modifiche dal server si sovrappongono direttamente
alle proprie modifiche sul file. Niente panico. Questa
sovrapposizione deve essere risolta da un intervento umano (il
vostro); questa situazione sarà discussa nel seguito di questo
capitolo.
Now you can get to work and make changes in your working copy. It's usually most convenient to decide on a particular change (or set of changes) to make, such as writing a new feature, fixing a bug, etc. The Subversion commands that you will use here are svn add, svn delete, svn copy, and svn move. However, if you are merely editing files that are already in Subversion, you may not need to use any of these commands until you commit. Changes you can make to your working copy:
A questo punto si è in grado di lavorare ed apportare modifiche alla propria copia di lavoro. Di solito è più conveniente decidere un particolare cambiamento (o un insieme di cambiamenti) da fare, come se si dovesse scrivere una nuova caratteristica, fissare un bug, etc. I comandi Subversion da usare sono svn add, svn delete, svn copy e svn move. Comunque se si stanno semplicemente modificando file che sono già presenti in Subversion, potrebbe non essere necessario nessuno di questi comandi finché non si fa la commit. Modifiche che si possono apportare alla propria copia di lavoro:
This is the simplest sort of change. You don't need to tell Subversion that you intend to change a file; just make your changes. Subversion will be able to automatically detect which files have been changed.
Questo è il tipo di modifica più semplice. Non c'è bisogno di dire a Subversion che si intende modificare un file; basta solo eseguire le modifiche. Subversion è in grado di stabilire automaticamente quali file siano stati modificati.
You can ask Subversion to «mark» files and directories for scheduled removal, addition, copying, or moving. While these changes may take place immediately in your working copy, no additions or removals will happen in the repository until you commit them.
Si può richiedere a Subversion di «marcare» file e directory per la rimozione, l'aggiunta, la copia o lo spostamento. Queste modifiche avvengono istantaneamente nella propria copia di lavoro, ma non appariranno rimozioni o aggiunte nel repository finché non si fa la commit.
To make file changes, use your text editor, word processor, graphics program, or whatever tool you would normally use. Subversion handles binary files just as easily as it handles text files—and just as efficiently too.
Per apportare modifiche ad un file si può usare un editor di testi, un word processor, programmi di grafica e qualsiasi tool che si usa normalmente. Subversion gestisce i files binari con la stessa facilità con cui gestisce i file di testo— e con la stessa efficienza.
Here is an overview of the four Subversion subcommands that you'll use most often to make tree changes (we'll cover svn import and svn mkdir later).
Ecco una panoramica su 4 dei comandi di Subversion che si usano più spesso per apportare modifiche ad un albero di directory (si analizzeranno in seguito i comandi: svn import e svn mkdir).
![]() | Avvertimento |
|---|---|
While you can edit your files with whatever tool you like, you shouldn't change the structure of your working copy without letting Subversion know what you're doing. Use the svn copy, svn delete, and svn move commands to change the structure of your working copy, and use the svn add command to place new files and directories under version control. Mentre si possono modificare i files con qualsiasi tool si desideri, non è possibile modificare la struttura della propria directory di lavoro senza dire a Subversion quello che si sta per fare. Si utilizzano i comandi svn copy, svn delete, e svn move per modificare la struttura, ed il comando svn add per collocare nuovi file e directory sotto il controllo di versione. |
Schedule file, directory, or symbolic link
foo to be added to the repository.
When you next commit, foo will
become a child of its parent directory. Note that if
foo is a directory, everything
underneath foo will be scheduled
for addition. If you only want to add
foo itself, pass the
--non-recursive (-N)
switch.
Marca quali file, directory o link simbolici
foo per l'aggiunta al repository. Quando
si esegue la commit, foo diventerà un
figlio della directory padre. Si noti che
foo è una directory, tutto ciò che è
contenuto in essa verrà pianificato per essere aggiunto. Se si
vuole aggiungere soltanto foo bisogna
usare l'opzione --non-ricorsivo.
(-N).
Schedule file, directory, or symbolic link
foo to be deleted from the
repository. If foo is a file or
link, it is immediately deleted from your working copy.
If foo is a directory, it is not
deleted, but Subversion schedules it for deletion. When
you commit your changes, foo will
be removed from your working copy and the repository.
[5]
Marca i file, le directory ed i link simbolici per la
cancellazione dal repository. Se foo è un
file o un link, viene cancellato immediatamente dalla propria
copia di lavoro. Se foo è una directory,
non viene cancellata ma Subversion la marca per la
cancellazione. Quando si fa la commit delle modifiche,
foo sarà rimosso sia dalla copia di lavoro
locale che dal repository. [6]
Create a new item bar as a
duplicate of foo.
bar is automatically scheduled for
addition. When bar is added to the
repository on the next commit, its copy history is
recorded (as having originally come from
foo). svn copy
does not create intermediate directories.
Si crea un nuovo elemento bar come
duplicato di foo. bar
viene automaticamente marcato per essere aggiunto. Quando
bar viene aggiunto al repository alla
commit successiva, la storia della copia viene ereditata (come
se provenisse originariamnete da foo).
svn copy non crea directory
intermedie.
This command is exactly the same as running
svn copy foo bar; svn delete foo.
That is, bar is scheduled for
addition as a copy of foo, and
foo is scheduled for removal.
svn move does not create intermediate
directories.
Questo comando è esattamente equivalente a svn
copy foo bar; svn delete foo.
bar è pianificato per essere aggiunto come
copia di foo, e foo
è pianificato per la rimozione. svn move non
crea directory itermedie.
Once you've finished making changes, you need to commit them to the repository, but before you do so, it's usually a good idea to take a look at exactly what you've changed. By examining your changes before you commit, you can make a more accurate log message. You may also discover that you've inadvertently changed a file, and this gives you a chance to revert those changes before committing. Additionally, this is a good opportunity to review and scrutinize changes before publishing them. You can see exactly what changes you've made by using svn status, svn diff, and svn revert. You will usually use the first two commands to find out what files have changed in your working copy, and then perhaps the third to revert some (or all) of those changes.
Una volta che si è finito di apportare le modifiche, bisogna fare la commit sul repository, ma prima è una buona norma guardare con attenzione cosa si è cambiato esattamente. Esaminando le modifiche prima di effettuare la commit si può scrivere un messaggio di log più accurato. Ci si può anche rendere conto di aver modificato un file inavvertitamente e si può tornare indietro prima di fare la commit. Inoltre questa è una buona opportunità per rivedere ed analizzare le modifiche fatte prima di pubblicarle. Per vedere esattamente le modifiche apportate si possono usare i comandi svn status, svn diff e svn revert. In genere si usano i primi due comandi per vedere quali file siano stati modificati nella propria copia di lavoro, ed il terzo per annullare alcune delle modifiche effettuate (o anche tutte).
Subversion has been optimized to help you with this task,
and is able to do many things without communicating with the
repository. In particular, your working copy contains a
secret cached “pristine” copy of each version
controlled file within the .svn area.
Because of this, Subversion can quickly show you how your
working files have changed, or even allow you to undo your
changes without contacting the repository.
Subversion è stato ottimizzato per aiutare in questo compito, e
riesce a fare molte cose senza comunicare con il repository. In
particolare, la propria directory di lavoro contiene una copia
nascosta «originale», di ogni file sotto controllo di
versione, all'interno della directory .svn. Per
questo motivo, Subversion può mostrare velocemente come sono stati
modificati i file di lavoro o anche permettere di annullare le
modifiche senza contattare il repository.
You'll probably use the svn status command more than any other Subversion command.
Il comando svn status è probabilmente il più usato tra i comandi di Subversion.
If you run svn status at the top of
your working copy with no arguments, it will detect all file
and tree changes you've made. Below are examples of
the different status codes that svn
status can return. (Note that the text following
# is not
actually printed by svn status.)
Digitando il comando svn status in testa
alla propria directory di lavoro, senza argomenti, esso cercherà
tutti i file e le strutture ad albero che sono state create.
Riportiamo degli esempi di codice relativi a stati differenti che
il comando svn status può restituire. (Si noti
che il testo che segue # non è attualmente
visualizzato da svn status.)
L some_dir # svn left a lock in the .svn area of some_dir
M bar.c # the content in bar.c has local modifications
M baz.c # baz.c has property but no content modifications
X 3rd_party # dir is part of an externals definition
? foo.o # svn doesn't manage foo.o
! some_dir # svn manages this, but it's missing or
incomplete
~ qux # versioned as file/dir/link, but type has
changed
I .screenrc # svn doesn't manage this, and is set to ignore
it
A + moved_dir # added with history of where it came from
M + moved_dir/README # added with history and has local modifications
D stuff/fish.c # file is scheduled for deletion
A stuff/loot/bloo.h # file is scheduled for addition
C stuff/loot/lump.c # file has textual conflicts from an update
C stuff/loot/glub.c # file has property conflicts from an update
R xyz.c # file is scheduled for replacement
S stuff/squawk # file or dir has been switched to a branch
K dog.jpg # file is locked locally; lock-token present
O cat.jpg # file is locked in the repository by other user
B bird.jpg # file is locked locally, but lock has been
broken
T fish.jpg # file is locked locally, but lock has been
stolen
In this output format svn status prints five columns of characters, followed by several whitespace characters, followed by a file or directory name. The first column tells the status of a file or directory and/or its contents. The codes printed here are:
In questo formato di output il comando svn status visualizza cinque colonne di caratteri, seguite da diversi spazi, seguiti da un nome di file o directory e/o il loro contenuto. I codici visualizzati sono:
A elementoThe file, directory, or symbolic link
item has been scheduled for
addition into the repository.
Il file, la directory o il collegamento simbolico
elemento è stato pianificato per
essere aggiunti al repository.
C elementoThe file item is in a
state of conflict. That is, changes received from the server
during an update overlap with local changes that you have in
your working copy. You must resolve this conflict before
committing your changes to the repository.
Il file elemento è in uno stato di
conflitto. Questo succede quando le modifiche ricevute dal
server, durante un aggiornamento, sono state sovraposte a
modifiche fatte localmente nella propria directory di lavoro.
Bisogna risolvere questo conflitto prima di fare la commit
delle modifiche sul repository.
D elementoThe file, directory, or symbolic link
item has been scheduled for
deletion from the repository.
Il file, la directory o il collegamento simbolico
elemento è stato pianificato per
essere cancellati dal repository.
M elementoThe contents of the file
item have been modified.
Il contenuto del file elemento è
stato modificato.
R elementoThe file, directory, or symbolic link
item has been scheduled to
replace item in the repository.
This means that the object is first deleted, then
another object of the same name is added, all within a
single revision.
Il file, la directory o il collegamento simbolico
elemento è stato marcato per sostituire
l'oggetto nel repository. Questo
significa che prima l'oggetto viene cancellato, poi viene
aggiunto un altro oggetto con lo stesso nome, tutto nella
stessa versione.
X elementoThe directory item is
unversioned, but is related to a Subversion externals
definition. To find out more about externals
definitions, see la sezione chiamata «Externals Definitions».
La directory elemento non è sotto
controllo di versione, ma è collegata ad una definizione
esterna di Subversion. Per saperne di più sulle definizioni
esterne si veda la sezione chiamata «Externals Definitions».
? elementoThe file, directory, or symbolic link
item is not under version
control. You can silence the question marks by either
passing the --quiet
(-q) switch to svn
status, or by setting the
svn:ignore property on the parent
directory. For more information on ignored files, see
la sezione chiamata «svn:ignore».
Il file, la directory o il collegamento simbolico
elemento non è sotto il controllo di
versione. Si può evitare il punto interrogativo usando
l'opzione --quiet (-q) con
il comando svn status, oppure impostando la
proprietà svn:ignore nella directory
padre. Per maggiori informazioni sui file ignorati, si veda
la sezione chiamata «svn:ignore».
! elementoThe file, directory, or symbolic link
item is under version control but
is missing or somehow incomplete. The item can be
missing if it's removed using a non-Subversion
command. In the case of a directory, it can be
incomplete if you happened to interrupt a checkout or
update. A quick svn update will
refetch the file or directory from the repository, or
svn revert file will restore a
missing file.
Il file, la directory o il collegamento simbolico
elemento è sotto il controllo di
versione ma è mancante o incompleto. L'elemento può essere
mancante perché è stato rimosso senza usare un comando
Subversion. Nel caso di una directory, può essere incompleta
se si è interrotto un checkout o un update. Il rapido uso del
comando svn update andrà a riprendere il
file o la directory dal repository, o il comando svn
revert file riparerà il file mancante.
~ itemThe file, directory, or symbolic link
item is in the repository as one
kind of object, but what's actually in your working
copy is some other kind. For example, Subversion
might have a file in the repository, but you removed
the file and created a directory in its place, without
using the svn delete or
svn add command.
Il file, la directory o il collegamento simbolico
elemento è salvato nel repository come
un tipo di oggetto, ma è salvato, attualmente, nella propria
copia di lavoro come oggetto di altro tipo. Ad esempio
Subversion, potrebbe avere un file nel repository, ma è stato
rimosso il file ed è stata creata una directory al suo posto,
senza aver usato il comando svn delete
oppure il comando svn add.
I elementoThe file, directory, or symbolic link
item is not under version control, and
Subversion is configured to ignore it during svn
add, svn import and
svn status operations. For more
information on ignored files, see la sezione chiamata «svn:ignore». Note that this
symbol only shows up if you pass the
--no-ignore option to svn
status—otherwise the file would be ignored
and not listed at all!
Il file, la directory o il collegamento simbolico
elemento non è sotto il controllo di
versione e Subversion è configurato per ignorarlo durante le
operazioni di svn add, svn
import and svn status. Per
maggiori informazioni sui file ignorati si veda la sezione chiamata «svn:ignore». Si noti che
questo simbolo viene mostrato soltanto se si è usata
l'opzione --no-ignore con il comando
svn status—altrimenti il file viene
ignorato e non viene elencato.
The second column tells the status of a file or
directory's properties (see la sezione chiamata «Proprietà» for more information on
properties). If an M
appears in the second column, then the properties have been
modified, otherwise a whitespace will be printed.
La seconda colonna indica lo stato del file o le proprietà
della directory (si veda la sezione chiamata «Proprietà» per
maggiori informazioni sulle proprietà). Se appare una
M nella seconda colonna, allora
vuol dire che le proprietà sono state modificate, altrimenti sarà
visualizzato uno spazio vuoto.
The third column will only show whitespace or an
L which means that
Subversion has locked the directory's
.svn working area. You will see an
L if you run svn
status in a directory where an svn
commit is in progress—perhaps when you are
editing the log message. If Subversion is not running, then
presumably Subversion was interrupted and the lock needs to
be cleaned up by running svn cleanup
(more about that later in this chapter).
La terza colonna mostra soltanto spazi bianchi o una
L che indica che la directory
.svn è stata bloccata (Lock) da Subversion. Si
vedrà una L se si esegue il
comando svn status in una directory in cui è in
corso un comando di svn commit —ad
esempio quando si modificano messaggi di log. Se Subversion non è in
esecuzione, probabilmente è stato interrotto ed il blocco deve
essere rimosso tramite il comando svn cleanup
(si dirà di più su questo argomento nel seguito del
capitolo).
The fourth column will only show whitespace or a
+ which means that the file
or directory is scheduled to be added or modified with
additional attached history. This typically happens when you
svn move or svn copy a file
or directory. If you see
A +, this means
the item is scheduled for addition-with-history. It could be
a file, or the root of a copied directory.
+
means the item is part of a subtree scheduled for
addition-with-history, i.e. some parent got copied, and it's
just coming along for the ride.
M + means the item
is part of a subtree scheduled for addition-with-history,
and it has local modifications. When you
commit, first the parent will be added-with-history (copied),
which means this file will automatically exist in the copy.
Then the local modifications will be uploaded into the
copy.
La quarta colonna mostra soltanto spazi bianchi o un
+ che indica che il file o la
directory sono stati marcati per essere aggiunti o modificati con
uno storico allegato. Questo succede tipicamente quando si eseguono
i comandi svn move o svn
copy. Se si vede
A +, vuol dire che
l'oggetto è marcato per essere aggiunto con il suo storico.
Potrebbe essere un file oppure la radice di una directory copiata.
+ indica che l'oggetto è parte di
un sottoalbero marcato per essere aggiunto con il suo storico,
alcuni nodi padre possono essere stati già copiati e si sta
aspettando il suo turno.
M +, indica che
l'oggetto è parte di un sottoalbero marcato per essere aggiunto con
il suo storico, ed è stato modificato
localmente. Quando si esegue la commit, per prima cosa viene
aggiunto il nodo padre (copiato), il che significa che il file
esisterà automaticamente nella copia. In seguito, le modifiche
locali saranno ricopiate nella copia.
The fifth column will only show whitespace or an
S. This signifies that the
file or directory has been switched from the path of the
rest of the working copy (using svn
switch) to a branch.
La quinta colonna mostra solo spazi bianchi o una
S. Questo significa che il file o
la directory sono stati spostati dal percorso della directory di
lavoro in un ramo (usando il comando svn
switch).
The sixth column shows information about locks, which is
further explained in la sezione chiamata «Locking».
(These are not the same locks as the ones indicated by an
L in the third column;
see Three meanings of «lock».)
La sesta colonna mostra informazioni sui blocchi (lock), che
sono stati spiegati in la sezione chiamata «Locking». (Non
sono gli stessi blocchi indicati dalla
L nella terza colonna; si veda
Three meanings of «lock».)
If you pass a specific path to svn status, it gives you information about that item alone:
Se si passa un percorso specifico al comando svn status, si ottengono informazioni solo su quell'oggetto:
$ svn status stuff/fish.c D stuff/fish.c
svn status also has a
--verbose (-v) switch,
which will show you the status of every
item in your working copy, even if it has not been
changed:
Il comando svn status ha anche un'opzione
--verbose (-v), che mostra lo
stato di ogni oggetto presente nella propria
directory di lavoro, anche se non è stato modificato:
$ svn status --verbose
M 44 23 sally README
44 30 sally INSTALL
M 44 20 harry bar.c
44 18 ira stuff
44 35 harry stuff/trout.c
D 44 19 ira stuff/fish.c
44 21 sally stuff/things
A 0 ? ? stuff/things/bloo.h
44 36 harry stuff/things/gloo.c
This is the “long form” output of svn status. The first column remains the same, but the second column shows the working-revision of the item. The third and fourth columns show the revision in which the item last changed, and who changed it.
Questa è la «forma estesa» del risultato del comando svn status. La prima colonna rimane la stessa, ma la seconda mostra la revisione di lavoro dell'oggetto. La terza e la quarta colonna mostrano la revisione nella quale l'oggetto ha subito l'ultimo cambiamento, e chi lo ha eseguito.
None of the above invocations to svn
status contact the repository, they work only
locally by comparing the metadata in the
.svn directory with the working copy.
Finally, there is the --show-updates
(-u) switch, which contacts the repository
and adds information about things that are
out-of-date:
Nessuna delle precedenti invocazioni del comando svn
status contatta il repository, poiché lavorano solo
localmente confrontando i metadati presenti nella directory
.svn con la directory di lavoro. Infine, c'è
l'opzione --show-updates (-u) ,
che contatta il repository ed aggiunge informazioni sulle cose che
non sono aggiornate:
$ svn status --show-updates --verbose
M * 44 23 sally README
M 44 20 harry bar.c
* 44 35 harry stuff/trout.c
D 44 19 ira stuff/fish.c
A 0 ? ? stuff/things/bloo.h
Status against revision: 46
Notice the two asterisks: if you were to run
svn update at this point, you would
receive changes to README
and trout.c. This tells you some very
useful information—you'll need to update and get the
server changes on README before you
commit, or the repository will reject your commit for being
out-of-date. (More on this subject later.)
Si notino i due asterischi: se si esegue il comando
svn update a questo punto, si riceveranno le
modifiche al file README ed al file
trout.c. Questo fornisce alcune informazioni
molto utili — c'è bisogno di aggiornare e prendere le
modifiche del server riguardo il file README
prima di fare la commit, altrimenti il repository la rifiuterà
perché non si è aggiornati. (Maggiori informazioni sull'argomento in
seguito).
Another way to examine your changes is with the svn diff command. You can find out exactly how you've modified things by running svn diff with no arguments, which prints out file changes in unified diff format:[7]
Un altro modo per esaminare le proprie modifiche è quello di usare il comando svn diff. Si può verificare esattamente quali siano i cambiamenti apportati lanciando svn diff senza argomenti, il quale stampa le modifiche nel formato 'unified diff':[8]
$ svn diff
Index: bar.c
===================================================================
--- bar.c (revision 3)
+++ bar.c (working copy)
@@ -1,7 +1,12 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <stdio.h>
int main(void) {
- printf("Sixty-four slices of American Cheese...\n");
+ printf("Sixty-five slices of American Cheese...\n");
return 0;
}
Index: README
===================================================================
--- README (revision 3)
+++ README (working copy)
@@ -193,3 +193,4 @@
+Note to self: pick up laundry.
Index: stuff/fish.c
===================================================================
--- stuff/fish.c (revision 1)
+++ stuff/fish.c (working copy)
-Welcome to the file known as 'fish'.
-Information on fish will be here soon.
Index: stuff/things/bloo.h
===================================================================
--- stuff/things/bloo.h (revision 8)
+++ stuff/things/bloo.h (working copy)
+Here is a new file to describe
+things about bloo.
The svn diff command produces this
output by comparing your working files against the cached
“pristine” copies within the
.svn area. Files scheduled for
addition are displayed as all added-text, and files
scheduled for deletion are displayed as all deleted
text.
Il comando svn diff produce questo risultato
confrontando i propri file di lavoro con le copie
«di ripristino» che si trovano nell'area
.svn. I file pianificati per essere aggiunti
vengono visualizzati come testi aggiunti, e i file pianificati per
essere cancellati vengono visualizzati come testi cancellati.
Output is displayed in unified diff
format. That is, removed lines are prefaced
with a - and added lines are prefaced
with a +. svn diff
also prints filename and offset information useful to the
patch program, so you can generate
“patches” by redirecting the diff output to a
file:
L'output è visualizzato in un formato unificato diff
. Questo vuol dire che le linee cancellate sono
precedute da un - e le linee aggiunte sono
precedute da un +. svn diff
visualizza inoltre il nome del file e un insieme di informazioni
utili per il programma patch, così da poter
generare «patch» ridirezionando l'output delle
differenze in un file:
$ svn diff > patchfile
You could, for example, email the patch file to another developer for review or testing prior to commit.
Ad esempio si può inviare il file patch ad un altro sviluppatore via email, per una revisione o un test prima di eseguire la commit.
Now suppose you see the above diff output, and realize
that your changes to README are a
mistake; perhaps you accidentally typed that text into the
wrong file in your editor.
A questo punto si supponga che si siano analizzati gli output
del comando diff visualizzati sopra,e si sia compreso che le
modifiche apportate al file README siano un
errore; forse si è accidentalmente scritto del testo nel file
sbagliato.
This is a perfect opportunity to use svn revert.
È l'occasione perfetta per usare il comando svn revert.
$ svn revert README Reverted 'README'
Subversion reverts the file to its pre-modified state by
overwriting it with the cached “pristine” copy
from the .svn area. But also note that
svn revert can undo
any scheduled operations—for
example, you might decide that you don't want to add a new
file after all:
Subversion riporta il file allo stato precedente alla modifica
sovrascrivendo la copia «di ripristino» presente
nell'area .svn. Ma si noti anche che il
comando svn revert può annullare
qualsiasi operazione pianificata — ad
esempio, si può decidere di non voler aggiungere un nuovo file dopo
tutto:
$ svn status foo ? foo $ svn add foo A foo $ svn revert foo Reverted 'foo' $ svn status foo ? foo
![]() | Nota |
|---|---|
svn revert
svn revert |
Or perhaps you mistakenly removed a file from version control:
O forse per errore è stato rimosso un file dal controllo di versione:
$ svn status README
README
$ svn delete README
D README
$ svn revert README
Reverted 'README'
$ svn status README
README
We've already seen how svn status -u can predict conflicts. Suppose you run svn update and some interesting things occur:
Si è già visto come il comando svn status -u può prevedere i conflitti. Si supponga di eseguire il comando svn update e che accada qualcosa di interessante:
$ svn update U INSTALL G README C bar.c Updated to revision 46.
The U and
G codes are no cause for
concern; those files cleanly absorbed changes from the
repository. The files marked with
U contained no local changes
but were Updated with changes
from the repository. The G
stands for merGed, which
means that the file had local changes to begin with, but the
changes coming from the repository didn't overlap with the local
changes.
I codici di output U e
G non sono utili alla causa; questi
file hanno semplicemente assorbito le modifiche dal repository. I file
marcati con U non contengono modifiche
locali ma sono stati aggiornati con le modifiche presenti nel
repository. La G indica la fusione, il
che significa che il file ha modifiche locali ma che le modifiche
provenienti dal repository non hanno sovrascritto quelle locali.
But the C stands for
conflict. This means that the changes from the server overlapped
with your own, and now you have to manually choose between
them.
La C indica un conflitto. Questo
vuol dire che le modifiche del server hanno sovrascritto quelle locali,
ed ora bisogna scegliere manualmente tra esse.
Whenever a conflict occurs, three things typically occur to assist you in noticing and resolving that conflict:
Ogni volta che si crea un conflitto, servono tipicamente tre cose per avvisare del conflitto ed aiutare a risolverlo:
Subversion prints a C
during the update, and remembers that the file is in a
state of conflict.
Subversion visualizza una C
durante l'aggiornamento, e ricorda che il file è in stato di
conflitto.
If Subversion considers the file to be of a mergeable
type, it places conflict
markers—special strings of text which
delimit the “sides” of the
conflict—into the file to visibly demonstrate the
overlapping areas. (Subversion uses the
svn:mime-type property to decide if a
file is capable of contextual, line-based merging. See
la sezione chiamata «svn:mime-type» to learn
more.)
Se Subversion considera che il file possa essere fuso,
inserisce dei marcatori di conflitto
— stringhe speciali di testo che delimitano gli
«estremi» del conflitto — all'interno del file
per rendere visibili le aree sovrapponibili. (Subversion usa la
proprietà svn:mime-typeper decidere se si può
fare il merge del file. Per saperne di più si veda la sezione chiamata «svn:mime-type».)
For every conflicted file, Subversion places up to three extra unversioned files in your working copy:
Per ogni file che ha avuto un conflitto, Subversion mette nella propria copia di lavoro tre file extra che non sono sotto il controllo di versione.
filename.mineThis is your file as it existed in your working
copy before you updated your working copy—that
is, without conflict markers. This file has your
latest changes in it and nothing else. (If
Subversion considers the file to be unmergeable,
then the .mine file isn't
created, since it would be identical to the working
file.)
Questo è il file che c'era nella copia di lavoro prima
dell'aggiornamento — ovvero, che non ha marcatori di
conflitto. Questo file contiene le ultime modifiche fatte e
nient'altro. (Se Subversion considera il file non fondibile,
allora il file .mine non viene creato,
poiché potrebbe essere identico al file di lavoro).
filename.rOLDREVThis is the file that was the
BASE revision before you updated
your working copy. That is, the file that you
checked out before you made your latest
edits.
Questo è il file nella versione BASE
precedente all'aggiornamento della copia di lavoro. È il file
di cui si è fatto il check out prima delle ultime
modifiche.
filename.rNEWREVThis is the file that your Subversion client
just received from the server when you updated your
working copy. This file corresponds to the
HEAD revision of the
repository.
Questo è il file che il client di Subversion ha appena
ricevuto dal server quando si è fatto l'aggiornamento della
copia di lavoro. Questo file corrisponde alla revisione
HEAD del repository.
Here OLDREV is the revision number
of the file in your .svn directory
and NEWREV is the revision number of
the repository HEAD.
OLDREV è il numero di revisione del file
nella directory .svn e
NEWREV è il numero di revisione del repository
HEAD.
For example, Sally makes changes to the file
sandwich.txt in the repository. Harry has
just changed the file in his working copy and checked it in.
Sally updates her working copy before checking in and she gets
a conflict:
Ad esempio, Sally modifica il file sandwich.txt
nel repository. Harry ha appena modificato il file nella sua copia di
lavoro e ha fatto la commit. Sally ha aggiornato la sua copia di lavoro
prima della propria commit ed ottiene un conflitto:
$ svn update C sandwich.txt Updated to revision 2. $ ls -1 sandwich.txt sandwich.txt.mine sandwich.txt.r1 sandwich.txt.r2
At this point, Subversion will not
allow you to commit the file sandwich.txt
until the three temporary files are removed.
A questo punto, Subversion non permetterà la
commit del file sandwich.txt finché non verranno
rimossi i tre files temporanei.
$ svn commit --message "Add a few more things" svn: Commit failed (details follow): svn: Aborting commit: '/home/sally/svn-work/sandwich.txt' remains in conflict
If you get a conflict, you need to do one of three things:
Se si ha un conflitto, è necessario fare una di queste tre cose:
Merge the conflicted text “by hand” (by examining and editing the conflict markers within the file).
Sistemare il conflitto «a mano» (esaminando e modificando i marcatori di conflitto all'interno del file).
Copy one of the temporary files on top of your working file.
Usare uno dei file temporanei per sovrascrivere il file di lavoro.
Run svn revert <filename> to throw away all of your local changes.
Eseguire il comando svn revert < filename> per annullare tutte le modifiche fatte in locale.
Once you've resolved the conflict, you need to let Subversion know by running svn resolved. This removes the three temporary files and Subversion no longer considers the file to be in a state of conflict.[9]
Una volta risolto il conflitto, bisogna informare Subversion eseguendo il comando svn resolved. In questo modo vengono rimossi i tre file temporanei e Subversion non considera più il file in stato di conflitto. [10]
$ svn resolved sandwich.txt Resolved conflicted state of 'sandwich.txt'
Merging conflicts by hand can be quite intimidating the first time you attempt it, but with a little practice, it can become as easy as falling off a bike.
Risolvere i conflitti a mano può risultare difficile la prima volta che ci si prova, ma con un po' di pratica, può diventare facile come cadere dalla bicicletta.
Here's an example. Due to a miscommunication, you and
Sally, your collaborator, both edit the file
sandwich.txt at the same time. Sally
commits her changes, and when you go to update your working
copy, you get a conflict and we're going to have to edit
sandwich.txt to resolve the conflicts.
First, let's take a look at the file:
Ecco un esempio. A causa di una cattiva comunicazione, si
modifica, insieme alla collaboratrice Sally, il file
sandwich.txt nello stesso momento. Sally fa la
commit delle sue modifiche, e quando si farà l'aggiornamento della
propria copia di lavoro, si otterrà un conflitto e sarà necessario
modificare il file sandwich.txt per risolverlo.
Per prima cosa diamo uno sguardo al file:
$ cat sandwich.txt Top piece of bread Mayonnaise Lettuce Tomato Provolone <<<<<<< .mine Salami Mortadella Prosciutto ======= Sauerkraut Grilled Chicken >>>>>>> .r2 Creole Mustard Bottom piece of bread
The strings of less-than signs, equal signs, and greater-than signs are conflict markers, and are not part of the actual data in conflict. You generally want to ensure that those are removed from the file before your next commit. The text between the first two sets of markers is composed of the changes you made in the conflicting area:
I segni di minore, maggiore e uguale sono marcatori di conflitto, e non fanno parte dei dati presenti nel conflitto. Bisogna assicurarsi di toglierli prima di eseguire la commit. Il testo compreso tra i primi due insiemi di marcatori è composto dalle modifiche fatte nell'area in conflitto:
<<<<<<< .mine Salami Mortadella Prosciutto =======
The text between the second and third sets of conflict markers is the text from Sally's commit:
Il testo compreso tra il secondo e terzo insieme di marcatori di conflitto è il testo del commit di Sally:
======= Sauerkraut Grilled Chicken >>>>>>> .r2
Usually you won't want to just delete the conflict markers and Sally's changes—she's going to be awfully surprised when the sandwich arrives and it's not what she wanted. So this is where you pick up the phone or walk across the office and explain to Sally that you can't get sauerkraut from an Italian deli.[11] Once you've agreed on the changes you will check in, edit your file and remove the conflict markers.
Di solito non si vogliono solo cancellare i marcatori di conflitto e le modficihe di Sally — che resterebbe spiacevolmente sorpresa quando arriva il panino e non è quello che voleva. Così è il caso di prendere il telefono o di andare nell'ufficio di Sally e spiegarle che non si può avere un sauerkraut da un ristorante Italiano.[12] Una volta che si è d'accordo sulle modifiche, si modificherà il file, si cancelleranno i marcatori di conflitto e si effettuerà la commit.
Top piece of bread Mayonnaise Lettuce Tomato Provolone Salami Mortadella Prosciutto Creole Mustard Bottom piece of bread
Now run svn resolved, and you're ready to commit your changes:
A questo punto con il comando svn resolved, si è pronti per fare la commit delle modifiche:
$ svn resolved sandwich.txt $ svn commit -m "Go ahead and use my sandwich, discarding Sally's edits."
Remember, if you ever get confused while editing the conflicted file, you can always consult the three files that Subversion creates for you in your working copy—including your file as it was before you updated. You can even use a third-party interactive merging tool to examine those three files.
Si ricordi che, se si hanno dubbi mentre si modifica un file in conflitto, si possono consultare i tre files che Subversion crea nella copia di lavoro — includendo il file com'era prima dell'aggiornamento. Si può anche usare una terza-parte, un tool interattivo per esaminare questi tre files.
If you get a conflict and decide that you want to throw out your changes, you can merely copy one of the temporary files created by Subversion over the file in your working copy:
Se si è generato un conflitto e si decide di scartare le modifiche apportate, basta semplicemente copiare uno dei file temporanei i creati da Subversion sul file presente nella propria copia di lavoro:
$ svn update C sandwich.txt Updated to revision 2. $ ls sandwich.* sandwich.txt sandwich.txt.mine sandwich.txt.r2 sandwich.txt.r1 $ cp sandwich.txt.r2 sandwich.txt $ svn resolved sandwich.txt
If you get a conflict, and upon examination decide that you want to throw out your changes and start your edits again, just revert your changes:
Se si è generato un conflitto e dopo aver esaminato le modifiche fatte si decide di scartarle e ricominciare a scrivere basta fare il revert delle modifiche:
$ svn revert sandwich.txt Reverted 'sandwich.txt' $ ls sandwich.* sandwich.txt
Note that when you revert a conflicted file, you don't have to run svn resolved.
Si noti che quando si fa il revert di un file con conflitto non serve eseguire il comando svn resolved.
Now you're ready to check in your changes. Note that svn resolved, unlike most of the other commands we've dealt with in this chapter, requires an argument. In any case, you want to be careful and only run svn resolved when you're certain that you've fixed the conflict in your file—once the temporary files are removed, Subversion will let you commit the file even if it still contains conflict markers.
A questo punto si è pronti per controllare le proprie modifiche. Si noti che il comando svn resolved, a differenza della maggior parte degli altri comandi che si sono visti in questo capitolo, richiede un solo argomento. In ogni caso, bisogna essere prudenti ed eseguire il comando svn resolved soltanto se si è sicuri di aver fissato i conflitti nel proprio file — una volta che i file temporanei sono stati rimossi, Subversion permette di eseguire la commit del file anche se contiene ancora marcatori di conflitto.
Finally! Your edits are finished, you've merged all changes from the server, and you're ready to commit your changes to the repository.
Finalmente! Le modifiche sono finite, sono stati presi tutti i cambiamenti dal server e si è pronti ad eseguire la commit delle modifiche fatte sul repository.
The svn commit command sends all of
your changes to the repository. When you commit a change, you
need to supply a log message,
describing your change. Your log message will be attached to
the new revision you create. If your log message is brief,
you may wish to supply it on the command line using the
--message (or -m)
option:
Il comando svn commit invia tutte le modifiche al
repository. Quando si fa la commit di una modifica bisogna aggiungere un
messaggio di log , che descriva il cambiamento.
Il messaggio di log sarà allegato alla nuova revisione appena creata.
Se il messaggio di log è breve, è possibile aggiungerlo da riga di
comando usando l'opzione --message (o
-m):
$ svn commit --message "Corrected number of cheese slices." Sending sandwich.txt Transmitting file data . Committed revision 3.
However, if you've been composing your log message as you
work, you may want to tell Subversion to get the message from
a file by passing the filename with the
--file switch:
Comunque, se si è composto il messaggio di log durante il lavoro, è
possibile comunicare a Subversion di prendere il messaggio da file
passandogli il nome del file con l'opzione
--file:
$ svn commit --file logmsg Sending sandwich.txt Transmitting file data . Committed revision 4.
If you fail to specify either the
--message or --file switch,
then Subversion will automatically launch your favorite editor
(see the editor-cmd section in
la sezione chiamata «Config») for composing a log
message.
Se ci si dimentica di specificare una delle due opzioni
--message o --file, Subversion lancia
automaticamente il proprio editor preferito (si veda la sezione
editor-cmd in la sezione chiamata «Config») per comporre un messaggio
di log.
![]() | Suggerimento |
|---|---|
If you're in your editor writing a commit message and decide that you want to cancel your commit, you can just quit your editor without saving changes. If you've already saved your commit message, simply delete the text and save again. Se si sta compilando con il proprio editor un messaggio di commit e si decide di annullare la commit, basta chiudere l'editor senza salvare le modifiche. Se si è già salvato il messaggio di commit, basta cancellare il testo e salvare di nuovo. $ svn commit Waiting for Emacs...Done Log message unchanged or not specified a)bort, c)ontinue, e)dit a $ |
The repository doesn't know or care if your changes make any sense as a whole; it only checks to make sure that nobody else has changed any of the same files that you did when you weren't looking. If somebody has done that, the entire commit will fail with a message informing you that one or more of your files is out-of-date:
Il repository non sa e non è interessato al fatto che le modifiche apportate abbiano un senso; si assicura soltanto che nessun altro abbia modificato qualcosa degli stessi file senza accorgersene. Se qualcuno l'ha fatto l'intero commit fallirà e un messaggio informerà che uno o più file non sono aggiornati:
$ svn commit --message "Add another rule" Sending rules.txt svn: Commit failed (details follow): svn: Out of date: 'rules.txt' in transaction 'g'
At this point, you need to run svn update, deal with any merges or conflicts that result, and attempt your commit again.
A questo punto bisogna eseguire il comando svn update, gestire conflitti e fusioni risultanti ed eseguire la commit di nuovo.
That covers the basic work cycle for using Subversion. There are many other features in Subversion that you can use to manage your repository and working copy, but you can get by quite easily using only the commands that we've discussed so far in this chapter.
Questo conclude il ciclo base di lavoro per usare Subversion. Ci sono molte altre caratteristiche in Subversion che possono essere usate per gestire il repository e la copia di lavoro, ma si può procedere facilmente usando solo i comandi che sono stati discussi in precedenza in questo capitolo.
As we mentioned earlier, the repository is like a time machine. It keeps a record of every change ever committed, and allows you to explore this history by examining previous versions of files and directories as well as the metadata that accompanies them. With a single Subversion command, you can check out the repository (or restore an existing working copy) exactly as it was at any date or revision number in the past. However, sometimes you just want to peer into the past instead of going into the past.
Come si è detto, il repository è come una macchina del tempo. Mantiene una registrazione di tutte le modifiche di cui si è fatto la commit, e permette di esplorare la storia esaminando precedenti versioni di file e directory così come i metadati che li accompagnano. Con un singolo comando Subversion, si può fare il check out del repository (oppure ripristinare una una copia di lavoro esistente) esattamente come se fosse ad una data o a un numero di revisione nel passato. Comunque, a volte si vuole solo essere al passo con il passato invece di andare nel passato.
There are several commands that can provide you with historical data from the repository:
Ci sono diversi comandi che provvedono alle date nel repository:
Shows you broad information: log messages with date and author information attached to revisions, and which paths changed in each revision.
Mostra informazioni generali: vengono allegati alle revisioni messaggi di log con data e informazioni sull'autore, e quali percorsi sono stati cambiati in ogni revisione.
Shows you the specific details of how a file changed over time.
Mostra i dettagli di come un file è cambiato nel tempo.
This is used to retrieve any file as it existed in a particular revision number and display it on your screen.
È usato per caricare qualsiasi file così com'era in un particolare numero di revisione e visualizzarlo.
Displays the files in a directory for any given revision.
Visualizza i file in una directory per ogni data revisione.
To find information about the history of a file or directory, use the svn log command. svn log will provide you with a record of who made changes to a file or directory, at what revision it changed, the time and date of that revision, and, if it was provided, the log message that accompanied the commit.
Per trovare informazioni sulla storia di un file o una directory, si usa il comando svn log. svn log fornirà una registrazione di chi ha fatto modifiche ad un file o una directory, a quale revisione è stato modificato, l'ora e il giorno della revisione, e, se previsto, il messaggio di log che ha accompagnato la commit.
$ svn log ------------------------------------------------------------------------ r3 | sally | Mon, 15 Jul 2002 18:03:46 -0500 | 1 line Added include lines and corrected # of cheese slices. ------------------------------------------------------------------------ r2 | harry | Mon, 15 Jul 2002 17:47:57 -0500 | 1 line Added main() methods. ------------------------------------------------------------------------ r1 | sally | Mon, 15 Jul 2002 17:40:08 -0500 | 1 line Initial import ------------------------------------------------------------------------
Note that the log messages are printed in
reverse chronological order by default.
If you wish to see a different range of revisions in a
particular order, or just a single revision, pass the
--revision (-r)
switch:
Si noti che i messaggi di log sono stampati predefinitamente in
ordine cronologico inverso. Se si desidera vedere
un differente intrevallo di revisioni in un ordine particolare, o solo
una singola revisione, bisogna usare l'opzione
--revision (-r):
$ svn log --revision 5:19 # shows logs 5 through 19 in chronological order $ svn log -r 19:5 # shows logs 5 through 19 in reverse order $ svn log -r 8 # shows log for revision 8
You can also examine the log history of a single file or directory. For example:
Si può esaminare la storia dei log di un singolo file o directory. Ad esempio:
$ svn log foo.c … $ svn log http://foo.com/svn/trunk/code/foo.c …
These will display log messages only for those revisions in which the working file (or URL) changed.
Sarà mostrato solo il log di quelle revisioni in cui il file di lavoro (o URL) è cambiato.
If you want even more information about a file or
directory, svn log also takes a
--verbose (-v) switch.
Because Subversion allows you to move and copy files and
directories, it is important to be able to track path changes
in the filesystem, so in verbose mode, svn
log will include a list of changed paths in a
revision in its output:
Se si vogliono maggiori informazioni su un file o una directory,
svn log possiede anche l'opzione
--verbose (-v). Poiché Subversion
permette di spostare e copiare file e directory, è importante
riuscire a tener traccia dei cambiamenti di percorso nel filesystem,
così in modalità verbose, svn log nel suo output
includerà una lista dei percorsi modificati in una revisione :
$ svn log -r 8 -v ------------------------------------------------------------------------ r8 | sally | 2002-07-14 08:15:29 -0500 | 1 line Changed paths: M /trunk/code/foo.c M /trunk/code/bar.h A /trunk/code/doc/README Frozzled the sub-space winch. ------------------------------------------------------------------------
svn log also takes a --quiet
(-q) switch, which suppresses the body of the
log message. When combined with --verbose, it
gives just the names of the changed files.
svn log possiede anche un'opzione
--quiet (-q), che sopprime il corpo
del messaggio di log. Quando è combinata con l'opzione
--verbose, essa fornisce solo i nomi dei files
modificati.
We've already seen svn diff before—it displays file differences in unified diff format; it was used to show the local modifications made to our working copy before committing to the repository.
Si è gia visto svn diff precedentemente — mostra le modifiche di un file in un formato unificato diff; è stato usato per mostrare le modifiche locali fatte nella propria copia di lavoro prima di fare la commit al repository.
In fact, it turns out that there are three distinct uses of svn diff:
Infatti, si vede che ci sono tre usi distinti del comandosvn diff:
Examine local changes
Esaminare le modifiche locali
Compare your working copy to the repository
Confrontare la propria copia di lavoro con il repository
Compare repository to repository
Confrontare repository con repository
As we've seen, invoking svn diff with
no switches will compare your working files to the cached
“pristine” copies in
the .svn area:
Come si è visto, invocando il comando svn diff
senza nessuna opzione compariranno i file di lavoro nella copia
«di ripristino» presente nell'area
.svn:
$ svn diff Index: rules.txt =================================================================== --- rules.txt (revision 3) +++ rules.txt (working copy) @@ -1,4 +1,5 @@ Be kind to others Freedom = Responsibility Everything in moderation -Chew with your mouth open +Chew with your mouth closed +Listen when others are speaking $
If a single --revision
(-r) number is passed, then your
working copy is compared to the specified revision in the
repository.
Se si fornisce un solo numero con
l'opzione--revision (-r), allora la
propria copia di lavoro è confrontata con una specifica revisione nel
repository.
$ svn diff --revision 3 rules.txt Index: rules.txt =================================================================== --- rules.txt (revision 3) +++ rules.txt (working copy) @@ -1,4 +1,5 @@ Be kind to others Freedom = Responsibility Everything in moderation -Chew with your mouth open +Chew with your mouth closed +Listen when others are speaking $
If two revision numbers, separated by a colon, are
passed via --revision
(-r), then the two revisions are directly
compared.
Se vengono forniti due numeri di revisione, separati da una
colonna, con l'opzione --revision
(-r), allora vengono confrontate direttamente le due
revisioni.
$ svn diff --revision 2:3 rules.txt Index: rules.txt =================================================================== --- rules.txt (revision 2) +++ rules.txt (revision 3) @@ -1,4 +1,4 @@ Be kind to others -Freedom = Chocolate Ice Cream +Freedom = Responsibility Everything in moderation Chew with your mouth open $
Not only can you use svn diff to compare files in your working copy to the repository, but if you supply a URL argument, you can examine the differences between items in the repository without even having a working copy. This is especially useful if you wish to inspect changes in a file when you don't have a working copy on your local machine:
Per confrontare i file nella propria copia di lavoro con il repository non solo si può usare il comando svn diff, ma se si fornisce come argomento un URL, si possono esaminare le differenze tra oggetti nel repository anche senza avere una copia di lavoro. Questo è molto utile se si desidera ispezionare le modifiche in un file quando non si ha una copia di lavoro sulla propria macchina:
$ svn diff --revision 4:5 http://svn.red-bean.com/repos/example/trunk/text/rules.txt … $
If you want to examine an earlier version of a file and not necessarily the differences between two files, you can use svn cat:
Se si vuole esaminare una versione precedente di un file e non necessariamente le differenze tra due file, si può usare il comando svn cat:
$ svn cat --revision 2 rules.txt Be kind to others Freedom = Chocolate Ice Cream Everything in moderation Chew with your mouth open $
You can also redirect the output directly into a file:
Si può redirezionare l'output direttamente in un file:
$ svn cat --revision 2 rules.txt > rules.txt.v2 $
You're probably wondering why we don't just use svn update --revision to update the file to the older revision. There are a few reasons why we might prefer to use svn cat.
Probabilmente ci si meraviglierà del fatto che non si usa solo il comando svn update --revision per aggiornare il file ad una versione precedente. Ci sono diverse ragioni per preferire il comando svn cat.
First, you may want to see the differences between two revisions of a file using an external diff program (perhaps a graphical one, or perhaps your file is in such a format that the output of unified diff is nonsensical). In this case, you'll need to grab a copy of the old revision, redirect it to a file, and pass both that and the file in your working copy to your external diff program.
Come prima cosa, si possono voler vedere le differenze tra due revisioni di un file usando un programma diff esterno (magari uno grafico, o magari il file è in un formato tale che l'output in formato unificato diff non avrebbe senso). In questo caso, bisogna prendere una copia della revisione precedente, redirezionarla su un file, e passare sia quella sia il file nella propria copia di lavoro al programma diff esterno.
Sometimes it's easier to look at an older version of a file in its entirety as opposed to just the differences between it and another revision.
A volte è più facile guardare una versione precedente di un file per intero che analizzare solo le differenze tra quella ed un'altra revisione.
The svn list command shows you what files are in a repository directory without actually downloading the files to your local machine:
Il comando svn list mostra quali file sono nel repository senza attualmente scaricarli nalla propria macchina:
$ svn list http://svn.collab.net/repos/svn README branches/ clients/ tags/ trunk/
If you want a more detailed listing, pass the
--verbose (-v) flag to get
output like this:
Se si vuole una lista più dettagliata, si deve usrae l'opzione
--verbose (-v) per avere un output
come questo:
$ svn list --verbose http://svn.collab.net/repos/svn 2755 harry 1331 Jul 28 02:07 README 2773 sally Jul 29 15:07 branches/ 2769 sally Jul 29 12:07 clients/ 2698 harry Jul 24 18:07 tags/ 2785 sally Jul 29 19:07 trunk/
The columns tell you the revision at which the file or directory was last modified, the user who modified it, the size if it is a file, the date it was last modified, and the item's name.
Le colonne indicano la revisione nella quale il file o la directory è stato modificato l'ultima volta, l'utente che ha eseguito le modifiche, la dimensione se si tratta di un file, la data dell'ultima modifica, e il nome dell'oggetto.
In addition to all of the above commands, you can use
svn update and svn
checkout with the --revision switch
to take an entire working copy “back in time”
[13]:
In aggiunta a tutti i comandi visti sopra, si possono usare i
comandi svn update e svn checkout
con l'opzione --revision per portare un'intera copia di
lavoro «indietro nel tempo» [14]:
$ svn checkout --revision 1729 # Checks out a new working copy at r1729 … $ svn update --revision 1729 # Updates an existing working copy to r1729 …
While not as frequently used as the commands previously discussed in this chapter, you will occasionally need these commands.
Anche se non frequentemente, come i comandi visti finora in questo capitolo, occasionalmete si può aver bisogno di questi comandi.
When Subversion modifies your working copy (or any
information within .svn), it tries to do
so as safely as possible. Before changing the working copy,
Subversion writes its intentions to a log file. Next it
executes the commands in the log file to apply the requested
change, holding a lock on the relevant part of the working
copy while it works — to prevent othe Subversion clients
from accessing the working copy in mid-change. Finally,
Subversion removes the log file. Architecturally, this is
similar to a journaled filesystem. If a Subversion operation
is interrupted (if the process is killed, or if the machine
crashes, for example), the log files remain on disk. By
re-executing the log files, Subversion can complete the
previously started operation, and your working copy can get
itself back into a consistent state.
Quando Subversion modifica la propria copia di lavoro (o qualsiasi
informazione all'intreno di .svn), cerca di farlo
nel modo più sicuro possibile. Prima di modificare la copia di lavoro,
Subversion scrive le sue intenzioni in un file di log. Dopo esegue i
comandi nel file di log per applicare le modifiche richieste, mettendo
un blocco sulla parte importante della copia di lavoro mentre è in
funzione — per impedire ad altri client Subversion l'accesso alla
copia di lavoro durante la modifica. Infine, Subversion rimuove il file
log. Architetturalmente, è simile ad un filesystem con journaling. Se
un'operazione di Subversion viene interrotta (per esmpio, se il processo
viene terminato, o se la macchina va incrash), i files di log restano
sul disco. Rieseguendo i file di log Subversion può completare le
operazioni iniziate prima, e la copia di lavoro può tornare in un stato
consistente.
And this is exactly what svn cleanup
does: it searches your working copy and runs any leftover
logs, removing working copy locks in the process.
If Subversion ever tells you that some part of your working copy
is “locked”, then this is the command that you
should run. Also, svn status will display
an L next to locked items:
E questo è esattamente quello che fa il comando svn
cleanup: cerca la copia di lavoro e esegue tutti i log
rimasti in sospeso, rimuovendo i blocchi alla copia di lavoro nel
processo. Se Subversion comunica che alcune parti della copia di lavoro
sono «bloccate», allora questo è il comando da eseguire.
Inoltre, il comando svn status visualizzerà una
L vicino agli oggetti bloccati:
$ svn status L somedir M somedir/foo.c $ svn cleanup $ svn status M somedir/foo.c
Don't confuse these working copy locks with the ordinary locks that Subversion users create when using the “lock-modify-unlock” model of concurrent version control; see Three meanings of «lock» for clarification.
Non si confondano questi blocchi alla copia di lavoro con i blocchi ordinari che gli utenti di Subversion creano quando usano il modello di controllo di versione concorrente «blocco-modifica-sblocco»; si veda Three meanings of «lock» per chiarimenti.
The svn import command is a quick way to copy an unversioned tree of files into a repository, creating intermediate directories as necessary.
Il comando svn import è un modo veloce per copiare un albero di file non sotto il controllo di versione in un repository, creando se necessario directory intermedie.
$ svnadmin create /usr/local/svn/newrepos
$ svn import mytree file:///usr/local/svn/newrepos/some/project \
-m "Initial import"
Adding mytree/foo.c
Adding mytree/bar.c
Adding mytree/subdir
Adding mytree/subdir/quux.h
Committed revision 1.
The previous example copied the contents of directory
mytree under the directory
some/project in the repository:
Il precedente esempio ha copiato il contenuto della directory
mytree sotto la directory
some/project nel repository:
$ svn list file:///usr/local/svn/newrepos/some/project bar.c foo.c subdir/
Note that after the import is finished, the original tree is not converted into a working copy. To start working, you still need to svn checkout a fresh working copy of the tree.
Si noti che una volta finita l'importazione, l'albero originale non è convertito in una copia di lavoro. Per cominciare a lavorare, bisogna usare il comandosvn checkout per avere una copia di lavoro dell'albero.
Now we've covered most of the Subversion client commands. Notable exceptions are those dealing with branching and merging (see Capitolo 4, Ramificazioni e fusioni) and properties (see la sezione chiamata «Proprietà»). However, you may want to take a moment to skim through Capitolo 9, Riferimento completo di Subversion to get an idea of all the many different commands that Subversion has—and how you can use them to make your work easier.
Fin qui si sono visti la maggior parte dei comandi del client Subversion. Notevole eccezione è stata fatta per i comandi che si occupano di creare ramificazioni e fusioni (si veda Capitolo 4, Ramificazioni e fusioni) e le proprietà (si veda la sezione chiamata «Proprietà»). Comunque, per avere un'idea di tutti i differenti comandi di Subversion — e di come si possono usare per rendere il proprio lavoro più semplice si può vedere Capitolo 9, Riferimento completo di Subversion.
[5] Of course, nothing is ever totally
deleted from the repository—just from the
HEAD of the repository. You can get
back anything you delete by checking out (or updating
your working copy) a revision earlier than the one in
which you deleted it.
[6] Naturalmente niente
viene completamente cancellato dal repository — ma solo
dalla testa del repository. Si può ritrovare
tutto quello che si è cancellato facendo checkout (o l'update
della copia di lavoro) ad una versione precedente a quella in
cui si è fatta la cancellazione.
[7] Subversion uses its internal diff
engine, which produces unified diff format, by default. If
you want diff output in a different format, specify an
external diff program using --diff-cmd and
pass any flags you'd like to it using the
--extensions switch. For example, to see
local differences in file foo.c in
context output format while ignoring whitespace changes, you
might run svn diff --diff-cmd /usr/bin/diff
--extensions '-bc' foo.c.
[8]
Subversion calcola le differenze utilizzando il suo algoritmo
interno che predefinitamente produce un formato unificato diff. Se
si vuole utilizzare un formato diverso, bisogna specificare un
programma diff esterno usando l'opzione --diff-cmd
e passando tutti i flag necessari con l'opzione
--extensions. Per esempio, per vedere le
differenze locali nel file foo.c in un formato
di stampa che ignori le modifiche degli spazi bianchi, si può usare
il comando svn diff --diff-cmd /usr/bin/diff --extensions
'-bc' foo.c.
[9] You can always remove the temporary files yourself, but would you really want to do that when Subversion can do it for you? We didn't think so.
[10] Si possono sempre rimuovere i file autonomamente, ma perché farlo se Subversion può farlo al nostro posto? Non la pensavamo così.
[11] And if you ask them for it, they may very well ride you out of town on a rail.
[12] E se gielo chiedi ti manderebbero fuori città su un treno.
[13] See? We told you that Subversion was a time machine.
[14] Visto? Si era detto che Subversion era una macchina del tempo.
Indice
Branching, tagging, and merging are concepts common to almost all version control systems. If you're not familiar with these ideas, we provide a good introduction in this chapter. If you are familiar, then hopefully you'll find it interesting to see how Subversion implements these ideas.
Ramificazioni, targhe(etichette) e fusioni sono concetti comuni a quasi tutti sistemi di controllo delle versioni. Se non si conoscono abbastanza queste idee, forniamo noi la buona introduzione in questo capitolo. Se le conoscete già, si spera che troverete interesante di vedere come Subversion implementa queste idee.
Branching is a fundamental part of version control. If you're going to allow Subversion to manage your data, then this is a feature you'll eventually come to depend on. This chapter assumes that you're already familiar with Subversion's basic concepts (Capitolo 2, Concetti base).
Ramificazioni sono la parte fondamentale di controlo delle versioni. Se state per permettere a Subversion di maneggiare i vostri dati, dipenderete da questa caratteristica. In questo capitolo si assume che siete già al corrente di concetti base di Subversion (Capitolo 2, Concetti base).
Suppose it's your job to maintain a document for a division in your company, a handbook of some sort. One day a different division asks you for the same handbook, but with a few parts “tweaked” for them, since they do things slightly differently.
Supponiamo che vostro compito è mantenere un certo documento per un dipartimento della vostra società. Un giorno un altro dipartimento chiede lo stesso documento, ma con alcune parti «modificate» per loro, perché in quel dipartimento le cose fanno in modo legermente diverso.
What do you do in this situation? You do the obvious thing: you make a second copy of your document, and begin maintaining the two copies separately. As each department asks you to make small changes, you incorporate them into one copy or the other.
Che cosa fatte in questa situazione? Una cosa ovvia: fatte la seconda copia del vostro documento e cominciate mantenere le due copie separatamente. Quando uno o altro dipartimento chede di fare modifiche, voi le fatte nell'una o l'altra copia.
You often want to make the same change to both copies. For example, if you discover a typo in the first copy, it's very likely that the same typo exists in the second copy. The two documents are almost the same, after all; they only differ in small, specific ways.
Spesso vi capita di dover fare lo stesso cambiamento in tutte e due copie. Per es. avete scoperto errore di battitura nella prima copia, molto probabilmente lo stesso errore è anche nell'altra. Dopo tutto, le due copie sono quasi identiche, differiscono solo nelle piccole, specifiche parti.
This is the basic concept of a branch—namely, a line of development that exists independently of another line, yet still shares a common history if you look far enough back in time. A branch always begins life as a copy of something, and moves on from there, generating its own history (see Figura 4.1, «Rami di sviluppo»).
Questo è il concetto base di ramo—leteralmente una linea di sviluppo che esiste independemente dall'altra, anche se sempre condividono la storia comune se si guarda abbastanza indietro in tempo. Un ramo sempre comincia la sua vita come copia di qualcosa e prosegue da questo punto generando la sua propria storia (vedi Figura 4.1, «Rami di sviluppo»).
Subversion has commands to help you maintain parallel branches of your files and directories. It allows you to create branches by copying your data, and remembers that the copies are related to one another. It also helps you duplicate changes from one branch to another. Finally, it can make portions of your working copy reflect different branches, so that you can “mix and match” different lines of development in your daily work.
Subversion ha i comandi per aiutarvi mantenere rami paralleli di vostri file e cartelle. Vi permette di creare rami copiando i vostri dati e si ricorda che le copie sono in relazione con altre. Vi aiuta anche di dupplicare cambiamenti da un ramo ad altro. Infine, può creare parti della vostra copia di lavoro che riflettono rami diversi così che potete «mescolare e abbinare» le linee diverse dello sviluppo nel vostro lavoro giornaliero.
At this point, you should understand how each commit creates an entire new filesystem tree (called a “revision”) in the repository. If not, go back and read about revisions in la sezione chiamata «Revisioni».
A questo punto dovete già capire come ogni commit crea in deposito(repository) un albero di filesystem completamente nuovo (chiamato una «revisione»). Se no, tornate a leggere riguardo le revisioni la la sezione chiamata «Revisioni».
For this chapter, we'll go back to the same example from
Chapter 2. Remember that you and your collaborator, Sally, are
sharing a repository that contains two projects,
paint and calc.
Notice that in Figura 4.2, «Forma iniziale del deposito(repository)», however, each
project directory now contains subdirectories named
trunk and branches.
The reason for this will soon become clear.
Per questo capitolo torniamo allo stesso esempio del Capitolo 2.
Ricordate che voi e vostra collaboratrice, Sally, state condividere
un deposito(repository) che contiene due progetti,
paint e calc.
Da notare che nella Figura 4.2, «Forma iniziale del deposito(repository)», comunque,
ogni cartella di progetto adesso contiene sottocartelle denominate
trunk e branches.
La ragione di ciò diventa presto chiara.
As before, assume that Sally and you both have working
copies of the “calc” project. Specifically, you
each have a working copy of /calc/trunk.
All the files for the project are in this subdirectory rather
than in /calc itself, because your team has
decided that /calc/trunk is where the
“main line” of development is going to take
place.
Come prima, assumiamo che tutti e due, Sally e voi, avete
copia di lavoro del progetto «calc». Specificamente,
entrambi avete una copia di lavoro di /calc/trunk.
Tutti i file del progetto sono in questa sottocartella invece nella
cartella /calc stessa, perché vostro gruppo ha deciso
che /calc/trunk è il posto dove va posizionata la
«linea principale» dello sviluppo.
Let's say that you've been given the task of performing a
radical reorganization of the project. It will take a long time
to write, and will affect all the files in the project. The
problem here is that you don't want to interfere with Sally, who
is in the process of fixing small bugs here and there. She's
depending on the fact that the latest version of the project (in
/calc/trunk) is always usable. If you
start committing your changes bit-by-bit, you'll surely break
things for Sally.
Diciamo che vi hanno dato lavoro di radicale riorganizazione del
progetto. Questo prende lungo tempo per scriverlo e toccherà tutti i file
nell progetto. Il problema è che voi non volete interferire con lavoro di
Sally, che sta correggendo piccoli errori qua e là. Ella dipende dall fatto
che l'ultima versione del progetto (in /calc/trunk)
è sempre usabile. Se voi cominciate pubblicare i vostri cambiamenti
pezzo per pezzo, sicuramente rompete le cose a Sally.
One strategy is to crawl into a hole: you and Sally can stop
sharing information for a week or two. That is, start gutting
and reorganizing all the files in your working copy, but don't
commit or update until you're completely finished with the task.
There are a number of problems with this, though. First, it's
not very safe. Most people like to save their work to the
repository frequently, should something bad accidentally happen
to their working copy. Second, it's not very flexible. If you
do your work on different computers (perhaps you have a working
copy of /calc/trunk on two different
machines), you'll need to manually copy your changes back and
forth, or just do all the work on a single computer. By that
same token, it's difficult to share your changes-in-progress
with anyone else. A common software development “best
practice” is to allow your peers to review your work as you
go. If nobody sees your intermediate commits, you lose
potential feedback. Finally, when you're finished with all your
changes, you might find it very difficult to re-merge your final
work with the rest of the company's main body of code. Sally
(or others) may have made many other changes in the repository
that are difficult to incorporate into your working
copy—especially if you run svn update
after weeks of isolation.
Una strategia è nascondersi in una buca: voi e Sally smettete
di condividere le informazioni per una settimana o due.
Proprio così, cominciate sventrare e riorganizzare tutti i file
nella vostra copia di lavoro ma senza commit oppure update finché
non avrete complettamente finito il vostro lavoro.
C'è un numero di problemi con questo, comunque. Prima, non è
molto sicuro. A molte persone piace conservare suo lavoro
nel deposito(repository) frequentemente, nel caso che accidentalmente succede
qualcosa brutto alla loro copia di lavoro. Seconda, non è molto
flessibile. Se state svolgendo vostro lavoro su diversi computer
(magari avete le copie di lavoro del /calc/trunk
su due macchine diverse), avete bisogno di copiare manualmente
i vostri cambiamenti avanti e dietro o fare il lavoro solo su un computer.
E per la stessa ragione, è difficile condividere i vostri cambiamenti in corso
con qualcun altro. «La regola d'arte» comune
nel sviluppo del software è permettere ai vostri compagni di vedere
il vostro lavoro man mano come procede. Se nessuno vede i vostri
commit intermediari, avete perso le potenziali reazioni.
Alla fine, quando avete finito con tutti i vostri cambiamenti,
potete magari trovare molto difficile di ri-fondere vostro lavoro finale
con il resto del corpo principale del codice della vostra società.
Sally (o altri) poteva fare molti altri cambiamenti nel deposito(repository)
che sono difficili da incorporare nella vostra copia di
lavoro—specialmente se fatte svn update
dopo settimane di isolamento.
The better solution is to create your own branch, or line of development, in the repository. This allows you to save your half-broken work frequently without interfering with others, yet you can still selectively share information with your collaborators. You'll see exactly how this works later on.
La soluzione migliore è creare vostro ramo, o linea di sviluppo, nel deposito(repository). Questo vi permette di salvare frequentemente vostro lavoro incompiuto senza interferire con altri, ma nello stesso tempo selettivamente condividere le informazioni con i vostri collaboratori. Vediamo in seguito esattamente come questo approcio funziona.
Creating a branch is very simple—you make a copy of
the project in the repository using the svn
copy command. Subversion is not only able to copy
single files, but whole directories as well. In this case,
you want to make a copy of the
/calc/trunk directory. Where should the
new copy live? Wherever you wish—it's a matter of
project policy. Let's say that your team has a policy of
creating branches in the /calc/branches
area of the repository, and you want to name your branch
my-calc-branch. You'll want to create a
new directory,
/calc/branches/my-calc-branch, which
begins its life as a copy of
/calc/trunk.
Creare un ramo è molto semplice—fatte una copia di progetto
in deposito(repository) usando il comando svn copy.
Subversion è capace non solo di copiare i singoli file,
ma anche intere cartelle. Nel nostro caso, volete fare una copia
della cartella /calc/trunk. Dove la mettiamo?
Dovunque desideriate—è un aspetto di regole del progetto.
Diciamo che il vostro gruppo ha stabilito la regola di creare rami
nella area del deposito(repository) /calc/branches,
e voi volete chiamare vostro ramo my-calc-branch.
State per creare nuova cartella,
/calc/branches/my-calc-branch, che nasce come
copia di /calc/trunk.
There are two different ways to make a copy. We'll
demonstrate the messy way first, just to make the concept
clear. To begin, check out a working copy of the project's
root directory, /calc:
Ci sono due modi diversi di fare una copia. Vi dimostriamo
prima quello ingarbugliato, solo per fare chiaro il concetto.
Per cominciare, tiriamo fuori una copia di lavoro della cartella
principale del progetto, /calc:
$ svn checkout http://svn.example.com/repos/calc bigwc A bigwc/trunk/ A bigwc/trunk/Makefile A bigwc/trunk/integer.c A bigwc/trunk/button.c A bigwc/branches/ Checked out revision 340.
Making a copy is now simply a matter of passing two working-copy paths to the svn copy command:
Creare una copia è adesso semplice questione di passare due percorsi di copia di lavoro al comando svn copy:
$ cd bigwc $ svn copy trunk branches/my-calc-branch $ svn status A + branches/my-calc-branch
In this case, the svn copy command
recursively copies the trunk working
directory to a new working directory,
branches/my-calc-branch. As you can see
from the svn status command, the new
directory is now scheduled for addition to the repository.
But also notice the “+” sign next to the letter
A. This indicates that the scheduled addition is a
copy of something, not something new.
When you commit your changes, Subversion will create
/calc/branches/my-calc-branch in the
repository by copying /calc/trunk, rather
than resending all of the working copy data over the
network:
In questo caso, il comando svn copy
copia ricorsivamente cartella di lavoro trunk
nella nuova cartella di lavoro, branches/my-calc-branch.
Come si può vedere dal comando svn status,
la nuova cartella è adesso pianificata per essere aggiunta
al deposito(repository). Notare anche il segno «+» vicino la lettera
A. Questo indica che la aggiunta pianificata è una copia
di qualcosa, non qualcosa di nuovo. Quando pubblicate i vostri
cambiamenti, Subversion creerà
/calc/branches/my-calc-branch nel deposito(repository)
copiando /calc/trunk, invece di re-inviare tramite
la rete tutti i dati dalla cartella di lavoro:
$ svn commit -m "Creating a private branch of /calc/trunk." Adding branches/my-calc-branch Committed revision 341.
$ svn commit -m "Creato un ramo privato da /calc/trunk." Adding branches/my-calc-branch Committed revision 341.
And now the easier method of creating a branch, which we should have told you about in the first place: svn copy is able to operate directly on two URLs.
E adesso il metodo più semplice di creare un ramo, di cui si doveva parlare per primo: svn copy può operare direttamente su due URL.
$ svn copy http://svn.example.com/repos/calc/trunk \
http://svn.example.com/repos/calc/branches/my-calc-branch \
-m "Creating a private branch of /calc/trunk."
Committed revision 341.
$ svn copy http://svn.example.com/repos/calc/trunk \ http://svn.example.com/repos/calc/branches/my-calc-branch \ -m "Creato un ramo privato da /calc/trunk." Committed revision 341.
There's really no difference between these two methods.
Both procedures create a new directory in revision 341, and
the new directory is a copy of
/calc/trunk. This is shown in Figura 4.3, «Deposito con la nuova copia». Notice that the second method,
however, performs an immediate commit.
[15]
It's an easier procedure, because it doesn't require you to
check out a large mirror of the repository. In fact, this
technique doesn't even require you to have a working copy at
all.
Realmente non c'è differenza tra questi due metodi.
Entrambe le procedure creano una nuova cartella nella revisione 341 e
la nuova cartella è una copia di /calc/trunk.
Come mostrato nella Figura 4.3, «Deposito con la nuova copia». Notare che il secondo
metodo, tuttavia, fa anche commit immediato.
[16]
Questa è una procedura più semplice, perché non richiede di fare
checkout di grande parte del deposito(repository). Infatti, questa tecnica addirittura
non richiede neanche di avere una copia di lavoro.
Now that you've created a branch of the project, you can check out a new working copy to start using it:
Adesso che avete creato un ramo del progetto, potete tirare fuori (check out) una nuova copia di lavoro per cominciar ad usarla:
$ svn checkout http://svn.example.com/repos/calc/branches/my-calc-branch A my-calc-branch/Makefile A my-calc-branch/integer.c A my-calc-branch/button.c Checked out revision 341.
There's nothing special about this working copy; it simply
mirrors a different directory in the repository. When you
commit changes, however, Sally won't ever see them when she
updates. Her working copy is of
/calc/trunk. (Be sure to read la sezione chiamata «Cambiare una copia di lavoro» later in this chapter: the
svn switch command is an alternate way of
creating a working copy of a branch.)
Non c'è niente speciale di questa copia di lavoro; semplicemente
rispecchia una cartella diversa del deposito(repository).
Quando pubblicate le vostre modifiche (commit), tuttavia, Sally
non può nenche vederle quando fa aggiornamento (update). La sua
copia di lavoro è di /calc/trunk.
(Assicuratevi di leggere la la sezione chiamata «Cambiare una copia di lavoro» più avanti in questo capitolo:
il comando svn switch è un modo alternativo di creare
copia di lavoro di un ramo.)
Let's pretend that a week goes by, and the following commits happen:
Facciamo finta che le settimane passano e succedono sequenti pubblicazioni (commit):
You make a change to
/calc/branches/my-calc-branch/button.c,
which creates revision 342.
You make a change to
/calc/branches/my-calc-branch/integer.c,
which creates revision 343.
Sally makes a change to
/calc/trunk/integer.c, which creates
revision 344.
Fatta la modifica di
/calc/branches/my-calc-branch/button.c,
che crea revisione 342.
Fatta la modifica di
/calc/branches/my-calc-branch/integer.c,
che crea revisione 343.
Sally modifica
/calc/trunk/integer.c, che crea
revisione 344.
There are now two independent lines of development, shown
in Figura 4.4, «Ramificazione della storia d'un file», happening on
integer.c.
Ci sono adesso due linee di sviluppo independenti, mostrate
nella Figura 4.4, «Ramificazione della storia d'un file», che toccano
integer.c.
Things get interesting when you look at the history of
changes made to your copy of
integer.c:
Le cose diventano interessanti quando guardate la storia delle
modifiche della vostra copia di
integer.c:
$ pwd /home/user/my-calc-branch $ svn log --verbose integer.c ------------------------------------------------------------------------ r343 | user | 2002-11-07 15:27:56 -0600 (Thu, 07 Nov 2002) | 2 lines Changed paths: M /calc/branches/my-calc-branch/integer.c * integer.c: frozzled the wazjub. ------------------------------------------------------------------------ r341 | user | 2002-11-03 15:27:56 -0600 (Thu, 07 Nov 2002) | 2 lines Changed paths: A /calc/branches/my-calc-branch (from /calc/trunk:340) Creating a private branch of /calc/trunk. ------------------------------------------------------------------------ r303 | sally | 2002-10-29 21:14:35 -0600 (Tue, 29 Oct 2002) | 2 lines Changed paths: M /calc/trunk/integer.c * integer.c: changed a docstring. ------------------------------------------------------------------------ r98 | sally | 2002-02-22 15:35:29 -0600 (Fri, 22 Feb 2002) | 2 lines Changed paths: M /calc/trunk/integer.c * integer.c: adding this file to the project. ------------------------------------------------------------------------
$ pwd /home/user/my-calc-branch $ svn log --verbose integer.c ------------------------------------------------------------------------ r343 | user | 2002-11-07 15:27:56 -0600 (Thu, 07 Nov 2002) | 2 lines Changed paths: M /calc/branches/my-calc-branch/integer.c * integer.c: frozzled the wazjub. ------------------------------------------------------------------------ r341 | user | 2002-11-03 15:27:56 -0600 (Thu, 07 Nov 2002) | 2 lines Changed paths: A /calc/branches/my-calc-branch (from /calc/trunk:340) Creato un ramo privato da /calc/trunk ------------------------------------------------------------------------ r303 | sally | 2002-10-29 21:14:35 -0600 (Tue, 29 Oct 2002) | 2 lines Changed paths: M /calc/trunk/integer.c * integer.c: cambiato un docstring. ------------------------------------------------------------------------ r98 | sally | 2002-02-22 15:35:29 -0600 (Fri, 22 Feb 2002) | 2 lines Changed paths: M /calc/trunk/integer.c * integer.c: aggiunto questo file al progetto. ------------------------------------------------------------------------
Notice that Subversion is tracing the history of your
branch's integer.c all the way back
through time, even traversing the point where it was copied.
It shows the creation of the branch as an event in the
history, because integer.c was implicitly
copied when all of /calc/trunk/ was
copied. Now look what happens when Sally runs the same
command on her copy of the file:
Notare che Subversion tiene traccia della storia di
integer.c del vostro ramo dietro tutto il tempo,
attraversando anche il punto dov'è stato copiato.
Mostra la creazione del ramo come evento nella storia,
perché integer.c era stato implicitamente copiato
quando tutto il /calc/trunk/ era stato copiato.
Adesso guardate che sucede quando Sally avvia lo stesso comando
sulla sua copia del file:
$ pwd /home/sally/calc $ svn log --verbose integer.c ------------------------------------------------------------------------ r344 | sally | 2002-11-07 15:27:56 -0600 (Thu, 07 Nov 2002) | 2 lines Changed paths: M /calc/trunk/integer.c * integer.c: fix a bunch of spelling errors. ------------------------------------------------------------------------ r303 | sally | 2002-10-29 21:14:35 -0600 (Tue, 29 Oct 2002) | 2 lines Changed paths: M /calc/trunk/integer.c * integer.c: changed a docstring. ------------------------------------------------------------------------ r98 | sally | 2002-02-22 15:35:29 -0600 (Fri, 22 Feb 2002) | 2 lines Changed paths: M /calc/trunk/integer.c * integer.c: adding this file to the project. ------------------------------------------------------------------------
$ pwd /home/sally/calc $ svn log --verbose integer.c ------------------------------------------------------------------------ r344 | sally | 2002-11-07 15:27:56 -0600 (Thu, 07 Nov 2002) | 2 lines Changed paths: M /calc/trunk/integer.c * integer.c: riparata una manciata di errori ortografici. ------------------------------------------------------------------------ r303 | sally | 2002-10-29 21:14:35 -0600 (Tue, 29 Oct 2002) | 2 lines Changed paths: M /calc/trunk/integer.c * integer.c: cambiato un docstring. ------------------------------------------------------------------------ r98 | sally | 2002-02-22 15:35:29 -0600 (Fri, 22 Feb 2002) | 2 lines Changed paths: M /calc/trunk/integer.c * integer.c: aggiunto questo file al progetto. ------------------------------------------------------------------------
Sally sees her own revision 344 change, but not the change you made in revision 343. As far as Subversion is concerned, these two commits affected different files in different repository locations. However, Subversion does show that the two files share a common history. Before the branch-copy was made in revision 341, they used to be the same file. That's why you and Sally both see the changes made in revisions 303 and 98.
Sally vede la sua modifica nella versione 344, ma non la modifica che voi avete fatto nella versione 343. Per quel che riguarda Subversion, questi due commit riguardano i file diversi nelle diverse locazioni del deposito(repository). Tuttavia, Subversion mostra che questi due file condividono una storia comune. Prima che era fatta copia del ramo nella versione 341, essi erano l'unico file. E per questo entrambi, voi e Sally, vedete le modifiche fatte nelle versioni 303 e 98.
There are two important lessons that you should remember from this section.
Ci sono due lezioni importanti che dovete ricordare da questa sezione.
Unlike many other version control systems, Subversion's branches exist as normal filesystem directories in the repository, not in an extra dimension. These directories just happen to carry some extra historical information.
Diversamente da molti altri sistemi di controllo delle versioni, rami di Subversion esistono come normali cartelle del filesystem in deposito(repository), non in una dimensione extra. Succede solo che queste cartelle portano qualche storica informazione extra.
Subversion has no internal concept of a branch—only copies. When you copy a directory, the resulting directory is only a “branch” because you attach that meaning to it. You may think of the directory differently, or treat it differently, but to Subversion it's just an ordinary directory that happens to have been created by copying.
Subversion non ha un concetto interno dei rami—solo copie. Quando copiate una cartella, la cartella risultante è un «ramo» solo perché voi le date questo significato. Potete pensare alla cartella diversamente o trattarla diversamente, ma per Subversion essa è solo normale cartella, a quall'è successo di esser creata tramite copiatura.
Now you and Sally are working on parallel branches of the project: you're working on a private branch, and Sally is working on the trunk, or main line of development.
Adesso voi e Sally state lavorando sui rami paralleli del progetto: voi lavorate su un ramo privato e Sally lavora su tronco (trunk), o linea principale dello sviluppo.
For projects that have a large number of contributors, it's common for most people to have working copies of the trunk. Whenever someone needs to make a long-running change that is likely to disrupt the trunk, a standard procedure is to create a private branch and commit changes there until all the work is complete.
Per progetti che hanno grande numero di contribuenti, è comune per molta gente di avere copie di lavoro del tronco. Ogni volta che qualcuno ha bisogno di fare durature modifiche, che potrebbero disturbare il tronco, procedura standard è di creare un ramo privato e pubblicare le modifiche là finché tutto il lavoro no è completo.
So, the good news is that you and Sally aren't interfering with each other. The bad news is that it's very easy to drift too far apart. Remember that one of the problems with the “crawl in a hole” strategy is that by the time you're finished with your branch, it may be near-impossible to merge your changes back into the trunk without a huge number of conflicts.
Allora, la notizia buona è che voi e Sally non vi disturbate a vicenda. La cativa è che è molto facile slittare tropo lontano. Ricordate che uno dei problemi della strategia «nascondersi in una buca» è che quando avrete finito con il vostro ramo, potrebbe essere quasi impossibile fondere vostre modifiche nel tronco principale senza largo numero di conflitti.
Instead, you and Sally might continue to share changes as you work. It's up to you to decide which changes are worth sharing; Subversion gives you the ability to selectively “copy” changes between branches. And when you're completely finished with your branch, your entire set of branch changes can be copied back into the trunk.
Invece, voi e Sally potette continuare di scambiarsi modifiche mentre lavorate. Spetta a voi decidere qualle modifiche vale la pena condividere; Subversion vi dà l'abilità di «copiare» modifiche tra i rami selettivamente. E quando avrete completamente finito con il vostro ramo, vostro completto insieme di modifiche del ramo può essere copiato dietro nel tronco.
In the previous section, we mentioned that both you and
Sally made changes to integer.c on
different branches. If you look at Sally's log message for
revision 344, you can see that she fixed some spelling errors.
No doubt, your copy of the same file still has the same spelling
errors. It's likely that your future changes to this file will
be affecting the same areas that have the spelling errors, so
you're in for some potential conflicts when you merge your
branch someday. It's better, then, to receive Sally's change
now, before you start working too heavily
in the same places.
Nella precedente sezione, abbiamo menzionato che
entrambi, voi e Sally avete fatto modifiche su
integer.c nei rami diversi.
Se date un sguardo al messaggio di log di Sally (versione
344), potete vedere che ella ha corretto qualche errore di battitura.
Senza dubbio, vostra copia dello stesso file ancora ha gli stessi
errori. È probabile che le vostre future modifiche al file toccheranno
gli stessi posti che hanno errori di battitura, così sorgeranno alcuni
potenziali conflitti, quando un giorno andrete a fondere il vostro ramo.
Meglio incorporare le modifiche di Sally adesso,
prima che cominciate lavoro troppo pesante
sugli stessi posti.
It's time to use the svn merge command. This command, it turns out, is a very close cousin to the svn diff command (which you read about in Chapter 3). Both commands are able to compare any two objects in the repository and describe the differences. For example, you can ask svn diff to show you the exact change made by Sally in revision 344:
È ora di usare comando svn merge. Questo comando, come si vedrà, è cugino molto stretto del comando svn diff (di quale avete letto nel Capitolo 3). Entrambi comandi sono capaci di comparare qualsiasi due oggetti in deposito(repository) e descrivere le differenze. Per esempio, potete chiedere a svn diff di mostrare esatta modifica fatta da Sally nella versione 344:
$ svn diff -r 343:344 http://svn.example.com/repos/calc/trunk
Index: integer.c
===================================================================
--- integer.c (revision 343)
+++ integer.c (revision 344)
@@ -147,7 +147,7 @@
case 6: sprintf(info->operating_system, "HPFS (OS/2 or NT)"); break;
case 7: sprintf(info->operating_system, "Macintosh"); break;
case 8: sprintf(info->operating_system, "Z-System"); break;
- case 9: sprintf(info->operating_system, "CPM"); break;
+ case 9: sprintf(info->operating_system, "CP/M"); break;
case 10: sprintf(info->operating_system, "TOPS-20"); break;
case 11: sprintf(info->operating_system, "NTFS (Windows NT)"); break;
case 12: sprintf(info->operating_system, "QDOS"); break;
@@ -164,7 +164,7 @@
low = (unsigned short) read_byte(gzfile); /* read LSB */
high = (unsigned short) read_byte(gzfile); /* read MSB */
high = high << 8; /* interpret MSB correctly */
- total = low + high; /* add them togethe for correct total */
+ total = low + high; /* add them together for correct total */
info->extra_header = (unsigned char *) my_malloc(total);
fread(info->extra_header, total, 1, gzfile);
@@ -241,7 +241,7 @@
Store the offset with ftell() ! */
if ((info->data_offset = ftell(gzfile))== -1) {
- printf("error: ftell() retturned -1.\n");
+ printf("error: ftell() returned -1.\n");
exit(1);
}
@@ -249,7 +249,7 @@
printf("I believe start of compressed data is %u\n", info->data_offset);
#endif
- /* Set postion eight bytes from the end of the file. */
+ /* Set position eight bytes from the end of the file. */
if (fseek(gzfile, -8, SEEK_END)) {
printf("error: fseek() returned non-zero\n");
$ svn diff -r 343:344 http://svn.example.com/repos/calc/trunk
Index: integer.c
===================================================================
--- integer.c (revision 343)
+++ integer.c (revision 344)
@@ -147,7 +147,7 @@
case 6: sprintf(info->operating_system, "HPFS (OS/2 or NT)"); break;
case 7: sprintf(info->operating_system, "Macintosh"); break;
case 8: sprintf(info->operating_system, "Z-System"); break;
- case 9: sprintf(info->operating_system, "CPM"); break;
+ case 9: sprintf(info->operating_system, "CP/M"); break;
case 10: sprintf(info->operating_system, "TOPS-20"); break;
case 11: sprintf(info->operating_system, "NTFS (Windows NT)"); break;
case 12: sprintf(info->operating_system, "QDOS"); break;
@@ -164,7 +164,7 @@
low = (unsigned short) read_byte(gzfile); /* read LSB */
high = (unsigned short) read_byte(gzfile); /* read MSB */
high = high << 8; /* interpreta MSB correttamente */
- total = low + high; /* sommali inseme per un totale corretto */
+ total = low + high; /* sommali insieme per un totale corretto */
info->extra_header = (unsigned char *) my_malloc(total);
fread(info->extra_header, total, 1, gzfile);
@@ -241,7 +241,7 @@
Memorizza offset con ftell() ! */
if ((info->data_offset = ftell(gzfile))== -1) {
- printf("errore: ftell() ha resttituito -1.\n");
+ printf("errore: ftell() ha restituito -1.\n");
exit(1);
}
@@ -249,7 +249,7 @@
printf("Credo che inizio dei dati compressi è %u\n", info->data_offset);
#endif
- /* Imposta poszione otto byte dalla fine del file. */
+ /* Imposta posizione otto byte dalla fine del file. */
if (fseek(gzfile, -8, SEEK_END)) {
printf("errore: fseek() ha restituito non-zero\n");
The svn merge command is almost exactly the same. Instead of printing the differences to your terminal, however, it applies them directly to your working copy as local modifications:
Il comando svn merge è quasi esattamente uguale. Invece di mostrare le differenze sullo schermo, tuttavia, le applica direttamente nella vostra copia di lavoro come modifiche locali:
$ svn merge -r 343:344 http://svn.example.com/repos/calc/trunk U integer.c $ svn status M integer.c
The output of svn merge shows that your
copy of integer.c was patched. It now
contains Sally's change—the change has been
“copied” from the trunk to your working copy of
your private branch, and now exists as a local modification.
At this point, it's up to you to review the local modification
and make sure it works correctly.
L'output di svn merge mostra che vostra
copia di integer.c era stata modificata. Adesso
contiene le modifiche di Sally—le modifiche erano state
«copiate» dal tronco nella copia di lavoro
del vostro ramo privato e adesso esistono come modifiche locali.
A questo punto, tocca a voi rivedere le modifiche locali ed assicurare
che funzionano correttamente.
In another scenario, it's possible that things may not have
gone so well, and that integer.c may have
entered a conflicted state. You might need to resolve the
conflict using standard procedures (see Chapter 3), or if you
decide that the merge was a bad idea altogether, simply give up
and svn revert the local change.
In un altro scenario, è possibile che le cose possono non andare
così bene e perciò integer.c può entrare
nello stato di conflitto. Potette avere bisogno di risolvere
il conflitto usando procedure standard (vedi Capitolo 3), oppure
se decidete che fusione era del tutto una cativa idea,
semplicemente passare sopra e scartare con svn revert
le modifiche locali.
But assuming that you've reviewed the merged change, you can svn commit the change as usual. At that point, the change has been merged into your repository branch. In version control terminology, this act of copying changes between branches is commonly called porting changes.
Ma assumendo che avete ispezionato le modifiche incorporate, potete pubblicarle con svn commit come al solito. A questo punto, la modifica sarà fusa dentro il vostro ramo del deposito(repository). Nella terminologia di controlo delle versioni, questo atto di copiatura delle modifiche tra i rami è comunemnte chaimato porting dele modifiche.
When you commit the local modification, make sure your log message mentions that you're porting a specific change from one branch to another. For example:
Facendo commit delle modifiche locali, assicuratevi che vostro messaggio menziona che state portando una modifica specifica da un ramo ad altro. Per esempio:
$ svn commit -m "integer.c: ported r344 (spelling fixes) from trunk." Sending integer.c Transmitting file data . Committed revision 360.
$ svn commit -m "integer.c: portata r344 (fix di ortografia) dal tronco." Sending integer.c Transmitting file data . Committed revision 360.
As you'll see in the next sections, this is a very important “best practice” to follow.
Come vedrete nella prossima sezione, questa è molto importante «regola d'arte» da seguire.
A word of warning: while svn diff and svn merge are very similar in concept, they do have different syntax in many cases. Be sure to read about them in Chapter 9 for details, or ask svn help. For example, svn merge requires a working-copy path as a target, i.e. a place where it should apply the tree-changes. If the target isn't specified, it assumes you are trying to perform one of the following common operations:
Una parola di avvertimento: anche se svn diff e svn merge sono nel concetto molto simili, hanno in molti casi la sintassi diversa. Assicuratevi di leggere dettagli nel Capitolo 9 o chiedete lumi a svn help. Per esempio, svn merge richiede percorso di copia di lavoro come destinazione, i.e. un posto dove può applicare le modifiche della struttura. Se la destinazione non è specificata, assume che state provando di fare una delle seguenti comuni operazioni:
You want to merge directory changes into your current working directory.
Volete fondere modifiche delle cartelle nella vostra cartella di lavoro.
You want to merge the changes in a specific file into a file by the same name which exists in your current working directory.
Volete fondere le modifiche d'un file specifico dentro un file con lo stesso nome che esiste nella vostra cartella di lavoro.
If you are merging a directory and haven't specified a target path, svn merge assumes the first case above and tries to apply the changes into your current directory. If you are merging a file, and that file (or a file by the same name) exists in your current working directory, svn merge assumes the second case and tries to apply the changes to a local file with the same name.
Se state fondendo una cartella e non avete specificato percorso di destinazione, svn merge assume il primo caso sopra e prova applicare le modifiche dentro vostra cartella attuale. Se state fondendo un file e questo file (o un file con lo stesso nome) esiste dentro vostra cartella attuale, svn merge assume il secondo caso e prova applicare le modifiche dentro file locale con lo stesso nome.
If you want changes applied somewhere else, you'll need to say so. For example, if you're sitting in the parent directory of your working copy, you'll have to specify the target directory to receive the changes:
Se volete applicare le modifiche in un altro posto, dovete dirlo. Per esempio, se siete nella cartella parente della vostra copia di lavoro, dovete specificare cartella destinazione per ricevere le modifiche:
$ svn merge -r 343:344 http://svn.example.com/repos/calc/trunk my-calc-branch U my-calc-branch/integer.c
You've now seen an example of the svn merge command, and you're about to see several more. If you're feeling confused about exactly how merging works, you're not alone. Many users (especially those new to version control) are initially perplexed about the proper syntax of the command, and about how and when the feature should be used. But fear not, this command is actually much simpler than you think! There's a very easy technique for understanding exactly how svn merge behaves.
Abbiamo visto un esempio di comando svn merge, e stiamo per vedere di più. Se vi sentite confusi riguardo come funziona esattamente la fusione, non siete soli. Molti utenti (specialmente quelli nuovi a cotrollo delle versioni) rimangono inizialmente perplessi riguardo la giusta sintassi del comando e come e quando usare questa caratteristica. Non avere paura, questo comando è in verità molto più semplice che si pensa. C'è una tecnica molto semplice per capire esattamente come svn merge agisce.
The main source of confusion is the name of the command. The term “merge” somehow denotes that branches are combined together, or that there's some sort of mysterious blending of data going on. That's not the case. A better name for the command might have been svn diff-and-apply, because that's all that happens: two repository trees are compared, and the differences are applied to a working copy.
La fonte primaria della confusione è il nome del comando. Il termine «merge»(fondere) qualche volta denota che i rami sono combinati tra loro, oppure che ci sta qualche sorta di misterioso mescolamento dei dati. Non è il caso. Più appropriato nome per questo comando forse sarebbe svn diff-and-apply(trova-differenze-e-applicale), perché questo è tutto che accade: due strutture del deposito(repository) sono comparate e le differenze sono applicate alla copia di lavoro.
The command takes three arguments:
Il comando prende tre argomenti:
An initial repository tree (often called the left side of the comparison),
Una struttura del deposito(repository) iniziale (spesso chiamata il lato sinistro della comparazione),
A final repository tree (often called the right side of the comparison),
Una struttura del deposito(repository) finale (spesso chiamata il lato destro della comparazione),
A working copy to accept the differences as local changes (often called the target of the merge).
Una copia di lavoro per ricevere le differenze come modifiche locali (spesso chiamata la destinazione della fusione).
Once these three arguments are specified, the two trees are compared, and the resulting differences are applied to the target working copy as local modifications. When the command is done, the results are no different than if you had hand-edited the files, or run various svn add or svn delete commands yourself. If you like the results, you can commit them. If you don't like the results, you can simply svn revert all of the changes.
Una volta specificati questi tre argomenti, le due strutture sono comparate e le differenze risultanti sono applicate alla copia di lavoro destinataria come modifiche locali. Quando il comando finisce il suo lavoro, il risultato non è diverso da come aveste editato i file manualmente o aveste da soli avviato svariati comandi svn add o svn delete. Se il risultato vi piace, potete fare commit. Se non vi piace, con semplice comando svn revert scartate tutte le modifiche.
The syntax of svn merge allows you to specify the three necessary arguments rather flexibly. Here are some examples:
La sintassi di comando svn merge vi permete di specificare i tre argomenti necessari in modo molto flessibile Qui ci sono alcuni esempi:
$ svn merge http://svn.example.com/repos/branch1@150 \
http://svn.example.com/repos/branch2@212 \
my-working-copy
$ svn merge -r 100:200 http://svn.example.com/repos/trunk my-working-copy
$ svn merge -r 100:200 http://svn.example.com/repos/trunk
The first syntax lays out all three arguments explicitly, naming each tree in the form URL@REV and naming the working copy target. The second syntax can be used as a shorthand for situations when you're comparing two different revisions of the same URL. The last syntax shows how the working-copy argument is optional; if omitted, it defaults to the current directory.
La prima sintassi elenca tutti e tre argomenti esplicitamente, nominando ogni struttura in forma URL@REV e nominando la copia di lavoro ricevente. La seconda sintassi può essere usata, quando state comparando due versioni diverse dello stesso URL. L'ultima sintassi mostra che argomento 'copia di lavoro' è facoltativo; se omesso, il suo valore predefinito è la cartella attuale.
Merging changes sounds simple enough, but in practice it can become a headache. The problem is that if you repeatedly merge changes from one branch to another, you might accidentally merge the same change twice. When this happens, sometimes things will work fine. When patching a file, Subversion typically notices if the file already has the change, and does nothing. But if the already-existing change has been modified in any way, you'll get a conflict.
Fondere modifiche suona abbastanza semplice, ma in prattica può diventare mal di testa. Il problema è che se ripetutamente fondete modifiche da un ramo ad altro, potete accidentalmente fondere la stessa modifica due volte. Se succede questo, a volte tutto va bene. Quando Subversion applica le modifiche su un file, tipicamente si accorge che il file queste modifiche ha già e non fa niente. Ma se la già esistente modifica era ulteriormente modificata, otente un conflitto.
Ideally, your version control system should prevent the double-application of changes to a branch. It should automatically remember which changes a branch has already received, and be able to list them for you. It should use this information to help automate merges as much as possible.
Idealmente, vostro sistema di controlo delle versioni dovrebbe prevenire la doppia applicazione delle modifiche su un ramo. Dovrebbe automaticamente ricordare quale modifiche il ramo ha già ricevuto ed essere capace di elencarle per voi. Dovrebbe usare queste informazioni per automatizzare le fusioni quanto più possibile.
Unfortunately, Subversion is not such a system. Like CVS, Subversion does not yet record any information about merge operations. When you commit local modifications, the repository has no idea whether those changes came from running svn merge, or from just hand-editing the files.
Sfortunatamente, un sistema così non è Subversion. Come il CVS, Subversion non memorizza ancora nessuna informazione riguardo operazioni di fusioni. Quando fatte commit delle modifiche locali, il deposito(repository) non ha idea se queste modifiche arrivano da svn merge eseguito o da editazione a mano dei file.
What does this mean to you, the user? It means that until the day Subversion grows this feature, you'll have to track merge information yourself. The best place to do this is in the commit log-message. As demonstrated in the earlier example, it's recommended that your log-message mention a specific revision number (or range of revisions) that are being merged into your branch. Later on, you can run svn log to review which changes your branch already contains. This will allow you to carefully construct a subsequent svn merge command that won't be redundant with previously ported changes.
Che cosa significa questo per voi, utente? Significa che fino al giorno in cui Subversion avrà questa capacità, dovete tracciare informazioni riguardo le fusioni da soli. Il posto migliore dove farlo è messaggio di commit. Come era dimostrato nel esempio precedente, è raccomandato che vostro messaggio menziona specifico numero della revisione (o rango delle revisioni) che state fondendo nel vostro ramo. In futuro potete avviare comando svn log per vedere quale modifiche contiene già il vostro ramo. Questo vi permete di costruire con cura prossimi comandi svn merge che non saranno redundanti con le modifiche già riportate in precedenza.
In the next section, we'll show some examples of this technique in action.
Nella prossima sezione mostreremo in azione alcuni esempi di questa tecnica.
Because merging only results in local modifications, it's not usually a high-risk operation. If you get the merge wrong the first time, simply svn revert the changes and try again.
Perché risultato delle fusioni sono soltanto le modifiche locali, questa non è normalmente una operazione ad alto rischio. Se vi capita di fondere male prima volta, semplicemente buttate via le modifiche (svn revert) e provate di nuovo.
It's possible, however, that your working copy might already have local modifications. The changes applied by a merge will be mixed with your pre-existing ones, and running svn revert is no longer an option. The two sets of changes may be impossible to separate.
È possibile, comunque, che vostra copia di lavoro contiene anche le modifiche locali. Le modifiche applicate da merge saranno mischiate tra le vostre e avviare comando svn revert non è più una scelta pratticabile. Potrebbe essere impossibile separare i due insiemi delle modifiche.
In cases like this, people take comfort in being able to
predict or examine merges before they happen. One simple
way to do that is to run svn diff with
the same arguments you plan to pass to svn
merge, as we already showed in our first example
of merging. Another method of previewing is to pass the
--dry-run option to the merge
command:
In casi come questo, le persone si confortano con la possibilità
di prevedere o esaminare fusione prima che accade. Un semplice
modo per farlo è avviare svn diff
con gli stessi argomenti che avete in mente di passare a
svn merge, come abbiamo già mostrato nel nostro
primo esempio. Altro metodo di anteprima è aggiungere la opzione
--dry-run(a secco) al comando merge:
$ svn merge \-\-dry-run -r 343:344 http://svn.example.com/repos/calc/trunk U integer.c $ svn status # nothing printed, working copy is still unchanged.
$ svn merge --dry-run -r 343:344 http://svn.example.com/repos/calc/trunk U integer.c $ svn status # non stampa niente, copia di lavoro è ancora intatta.
The --dry-run option doesn't actually
apply any local changes to the working copy. It only shows
status codes that would be printed in a
real merge. It's useful for getting a “high
level” preview of the potential merge, for those
times when running svn diff gives too
much detail.
La opzione --dry-run in verità non applica
nessuna modifica locale alla copia di lavoro. Mostra solo output
che sarebbe mostrato con la fusione vera.
Questo è utile per avere una previsione ad «alto
livello» della potenziale fusione, per quelle volte dove
comando svn diff dà troppi dettagli.
Just like the svn update command, svn merge applies changes to your working copy. And therefore it's also capable of creating conflicts. The conflicts produced by svn merge, however, are sometimes different, and this section explains those differences.
Così come comando svn update, anche svn merge applica modifiche alla vostra copia di lavoro. E perciò è capace generare conflitti. I conflitti prodotti da svn merge, tuttavia, sono a volte diversi e questa sezione spiega queste differenze.
To begin with, assume that your working copy has no local edits. When you svn update to a particular revision, the changes sent by the server will always apply “cleanly” to your working copy. The server produces the delta by comparing two trees: a virtual snapshot of your working copy, and the revision tree you're interested in. Because the left-hand side of the comparison is exactly equal to what you already have, the delta is guaranteed to correctly convert your working copy into the right-hand tree.
Per cominciare, si assume che vostra copia di lavoro non ha editazioni locali. Quando la aggiornate (svn update) ad una particolare versione, le modifiche mandate dal server si applicano sempre alla vostra copia di lavoro in modo «pulito». Il server produce un ??delta? comparando due strutture: un'instantanea virtuale della vostra copia di lavoro e struttura della revisione a quale siete interessati. Perché lato sinistra della comparazione è uguale a quel che già avete il delta garantisce di correttamente convertire vostra copia di lavoro nella struttura di lato destra.
But svn merge has no such guarantees and can be much more chaotic: the user can ask the server to compare any two trees at all, even ones that are unrelated to the working copy! This means there's large potential for human error. Users will sometimes compare the wrong two trees, creating a delta that doesn't apply cleanly. svn merge will do its best to apply as much of the delta as possible, but some parts may be impossible. Just like the Unix patch command sometimes complains about “failed hunks”, svn merge will complain about “skipped targets”:
Ma svn merge non ha tali garanzie e può essere più caotico: utente può chidere al server di comparare qualsiasi due strutture, anche tali che non hanno nessun legame con la copia di lavoro. Questo significa che qui c'è largo potenziale per errori umani. Utenti possono a volte comparare due strutture sbagliate, creando delta che non si applica pulitamente. svn merge farà il meglio per applicare più possibile il delta, ma su alcune parti questo potrà essere impossibile. Nello stesso modo come comando Unix patch a volte si lamenta di ??«failed hunks»?, svn merge può accusare «skipped targets» (destinazioni saltate):
$ svn merge -r 1288:1351 http://svn.example.com/repos/branch U foo.c U bar.c Skipped missing target: 'baz.c' U glub.c C glorb.h $
In the previous example it might be the case that
baz.c exists in both snapshots of the
branch being compared, and the resulting delta wants to
change the file's contents, but the file doesn't exist in
the working copy. Whatever the case, the
“skipped” message means that the user is most
likely comparing the wrong two trees; they're the classic
sign of driver error. When this happens, it's easy to
recursively revert all the changes created by the merge
(svn revert --recursive), delete any
unversioned files or directories left behind after the
revert, and re-run svn merge with
different arguments.
Nel esempio precedente può essere caso che
baz.c esiste in entrambe instantanee del
ramo comparato e delta risultante vuole cambiare il contenuto del
file, ma il file non esiste nella copia di lavoro.
Qualunque sia causa, il messaggio
«skipped»(saltato) significa che
con alta probabilità utente sta comparando le strutture sbagliate;
questo è un segno classico del 'errore del conducente'.
Quando accade ciò, è semplice invertire ricorsivamente tutte le
modifiche create dalla fusione (svn revert --recursive),
cancellare ogni file o cartella rimasta senza controllo delle versioni
dopo revert e rifare svn merge con argomenti
diversi.
Also notice that the previous example shows a conflict
happening on glorb.h. We already
stated that the working copy has no local edits: how can a
conflict possibly happen? Again, because the user can use
svn merge to define and apply any old
delta to the working copy, that delta may contain textual
changes that don't cleanly apply to a working file, even if
the file has no local modifications.
Notare ancora che precedente esempio mostra un conflitto
accaduto su glorb.h. Abbiamo già stabilito
che copia di lavoro non ha editazioni locali: come può allora
accadere un conflitto? Di nuovo, perché l'utente può usare
svn merge per definire ed applicare qualsiasi
delta vecchio a copia di lavoro, tale delta può contenere modifiche
testuali che non si applicano in modo pulito al file di lavoro,
anche se il file non ha le modifiche locali.
Another small difference between svn
update and svn merge are the
names of the full-text files created when a conflict
happens. In la sezione chiamata «Risolvere i conflitti(Mettere insieme i cambiamenti operati da
altri)», we saw
that an update produces files named
filename.mine,
filename.rOLDREV, and
filename.rNEWREV. When svn
merge produces a conflict, though, it creates
three files named filename.working,
filename.left, and
filename.right. In this case, the
terms “left” and “right” are
describing which side of the double-tree comparison the file
came from. In any case, these differing names will help you
distinguish between conflicts that happened as a result of an
update versus ones that happened as a result of a
merge.
Altra piccola differenza tra svn update e
svn merge sono i nomi
dei file testuali creati quando accade un conflitto.
Nella la sezione chiamata «Risolvere i conflitti(Mettere insieme i cambiamenti operati da
altri)», abbiamo visto che
un aggiornamento (update) produce file nominati
filename.mine,
filename.rOLDREV e
filename.rNEWREV. Quando comando svn
merge produce un conflitto, ??though?, crea
tre file nominati filename.working,
filename.left e
filename.right. Qui i
termini «left» e «right» descrivono
da quale lato della comparazione delle strutture proviene il file.
In qualsiasi caso, questi nomi diversi vi aiuteranno
distinguere tra conflitti che accadono come risultato d'un
aggiornamento (update) e tali che accadono come risultato d'una
fusione (merge).
When conversing with a Subversion developer, you might very likely hear reference to the term ancestry. This word is used to describe the relationship between two objects in a repository: if they're related to each other, then one object is said to be an ancestor of the other.
Parlando con sviluppatori di Subversion, uno può molto probabilmente sentire riferimento al termine ascendenza(ancestry). Questa parola è usata per descrivere la relazione tra due oggetti nel deposito(repository): se sono in relazione si dice che uno è antenato dell'altro.
For example, suppose you commit revision 100, which
includes a change to a file foo.c.
Then foo.c@99 is an
“ancestor” of foo.c@100.
On the other hand, suppose you commit the deletion of
foo.c in revision 101, and then add a
new file by the same name in revision 102. In this case,
foo.c@99 and
foo.c@102 may appear to be related
(they have the same path), but in fact are completely
different objects in the repository. They share no history
or “ancestry”.
Per esempio, supponiamo che voi depositate la versione 100,
che include una modifica a file foo.c.
Dopo questo il file foo.c@99 è un
«antenato» di foo.c@100.
Caso oposto, supponiamo che depositate la cancellazione del
foo.c nella versione 101 e dopo aggiugete
nuovo file con lo stesso nome nella versione 102. In questo caso,
foo.c@99 e
foo.c@102 possono apparire in relazione
(hanno lo stesso percorso e nome), ma in verità sono oggetti
del deposito(repository) completamente diversi. Non condividono nessuna storia
o «ascendenza».
The reason for bringing this up is to point out an
important difference between svn diff and
svn merge. The former command ignores
ancestry, while the latter command is quite sensitive to it.
For example, if you asked svn diff to
compare revisions 99 and 102 of foo.c,
you would see line-based diffs; the diff
command is blindly comparing two paths. But if you asked
svn merge to compare the same two objects,
it would notice that they're unrelated and first attempt to
delete the old file, then add the new file; the output would
indicate a deletion followed by an add:
La ragione per spiegare questo è di puntare il dito
sulla differenza importante tra svn diff e
svn merge. Il primo comando ignora
ascendenza, invece il secondo è assai sensibile ad essa.
Per esempio, chiedendo a svn diff di
comparare revisioni 99 e 102 di foo.c,
potete vedere differenze basate sulle linee; il comando
diff ciecamente compara i due file.
Ma se chiedete a svn merge di comparare
gli stessi oggetti, lui si accorge che non sono in relazione
e prima provede a cancellare quello vecchio e poi aggiunge
nuovo; output indicherà una cancellazione seguita da una aggiunta:
D foo.c A foo.c
Most merges involve comparing trees that are ancestrally
related to one another, and therefore svn
merge defaults to this behavior. Occasionally,
however, you may want the merge command to
compare two unrelated trees. For example, you may have
imported two source-code trees representing different vendor
releases of a software project (see la sezione chiamata «Vendor branches»).
If you asked svn merge to compare the two
trees, you'd see the entire first tree being deleted,
followed by an add of the entire second tree!
Molte fusioni coinvolgono comparazioni delle strutture che sono
genealogicamente relazionate tra loro, e perciò svn
merge ha come predefinito questo comportamento. Occasionalmente,
tuttavia, si può volere che comando merge compara
due strutture che non sono in relazione. Per esempio, si può importare
due strutture del codice sorgente che rappresentano due rilasci pubblici
d'un progetto software (vedi la la sezione chiamata «Vendor branches»).
Chiedendo a svn merge di comparare queste due strutture,
si vede prima la cancellazione completta della prima struttura,
seguita da aggiunta di tutta la seconda struttura!
In these situations, you'll want svn
merge to do a path-based comparison only, ignoring
any relations between files and directories. Add the
--ignore-ancestry option to your merge
command, and it will behave just like svn
diff. (And conversely, the
--notice-ancestry option will cause
svn diff to behave like the
merge command.)
In tali situazioni, si chiede a svn
merge di fare comparazione basata solo sui nomi, ignorando
qualsiasi relazione tra i file e cartelle. Si aggiunge opzione
--ignore-ancestry al vostro comando di fusione,
e quello si comporterà esattamente come svn
diff. (E al contrario, la opzione
--notice-ancestry causerà che
svn diff aggirà come comando
merge.)
There are many different uses for branching and svn merge, and this section describes the most common ones you're likely to run into.
Ci sono molti usi diversi per ramificazione e fusione(svn merge) e questa sezione descrive i più comuni tra essi, che probabilmente potete incontrare.
To complete our running example, we'll move forward in time. Suppose several days have passed, and many changes have happened on both the trunk and your private branch. Suppose that you've finished working on your private branch; the feature or bug fix is finally complete, and now you want to merge all of your branch changes back into the trunk for others to enjoy.
Per complettare nostro esempio in corso, ci moviamo avanti nel tempo. Supponiamo che sono passati diversi giorni, e sono accadute molte modifiche su tutte e due strutture, il tronco e vostro ramo privato. Supponiamo che avete finito il lavoro su vostro ramo privato; nuova caratteristica o riparazione del bug è finalmente completta e adesso volete fondere tutte le modifiche del vostro ramo dietro tronco, così che gl'altri possono assaporarle.
So how do we use svn merge in this
scenario? Remember that this command compares two trees, and
applies the differences to a working copy. So to receive the
changes, you need to have a working copy of the trunk. We'll
assume that either you still have your original one lying
around (fully updated), or that you recently checked out a
fresh working copy of /calc/trunk.
Allora, come usiamo svn merge in questo
scenario? Ricordate che questo comando compara due strutture ed
applica le differenze alla copia di lavoro. Perciò per scoprire
le modifiche, avete bisogno della copia di lavoro del tronco.
Assumiamo che o avete ancora quella originale da qualche parte
(complettamente aggiornata) o che di recente avete tirato fuori
(checkout) una fresca copia di /calc/trunk.
But which two trees should be compared? At first glance, the answer may seem obvious: just compare the latest trunk tree with your latest branch tree. But beware—this assumption is wrong, and has burned many a new user! Since svn merge operates like svn diff, comparing the latest trunk and branch trees will not merely describe the set of changes you made to your branch. Such a comparison shows too many changes: it would not only show the addition of your branch changes, but also the removal of trunk changes that never happened on your branch.
Ma quale due strutture devono essere comparate? A primo sguardo, la risposta sembra ovvia: comparare l'ultima struttura di tronco con l'ultima del ramo. Ferma!—questa ??assunzione? è sbagliata, e ha bruciato molti principianti! Perché svn merge opera come svn diff, comparare le ultime strutture di tronco e ramo non descriverà soltanto l'insieme delle modifiche fatte sul ramo. Comparazione come questa mostra trope modifiche: mostrerebbe non solo le agguinte delle vostre modifiche del ramo, ma anche le rimozioni delle modifiche del tronco che non sono mai accadute su vostro ramo.
To express only the changes that happened on your branch,
you need to compare the initial state of your branch to its
final state. Using svn log on your branch,
you can see that your branch was created in revision 341. And
the final state of your branch is simply a matter of using the
HEAD revision. That means you want to
compare revisions 341 and HEAD of your
branch directory, and apply those differences to a working
copy of the trunk.
Per scoprire solo le modifiche che son accadute nel vostro ramo,
dovete comparare lo stato iniziale del ramo con il suo stato finale.
Usando svn log sul vostro ramo,
potete vedere che vostro ramo era stato creato nella versione 341.
E lo stato finale è semplicemente questione di usare la versione
HEAD. Questo significa che dovete comparare versione
341 e HEAD della cartella del vostro ramo
e applicare quelle differenze all copia di lavoro del tronco.
![]() | Suggerimento |
|---|---|
A nice way of finding the revision in which a branch was
created (the “base” of the branch) is to use the
Un bel modo per trovare la versione nella quale era stato
creato un ramo (la «base» del ramo) è usare opzione
So in our continuing example, Così nel nostro esempi continuo,
$ svn log --verbose --stop-on-copy \
http://svn.example.com/repos/calc/branches/my-calc-branch
…
------------------------------------------------------------------------
r341 | user | 2002-11-03 15:27:56 -0600 (Thu, 07 Nov 2002) | 2 lines
Changed paths:
A /calc/branches/my-calc-branch (from /calc/trunk:340)
$
As expected, the final revision printed by this command
is the revision in which Come aspettato, l'ultima versione stampata da questo comando
è la versione in cui |
Here's the final merging procedure, then:
Qui c'è la procedura di fusione finale, allora:
$ cd calc/trunk $ svn update At revision 405. $ svn merge -r 341:405 http://svn.example.com/repos/calc/branches/my-calc-branch U integer.c U button.c U Makefile $ svn status M integer.c M button.c M Makefile # ...examine the diffs, compile, test, etc... $ svn commit -m "Merged my-calc-branch changes r341:405 into the trunk." Sending integer.c Sending b