Cosa significano “branch”, “tag” e “trunk” nei repository di Subversion?

Ho visto queste parole molto in giro per le discussioni di Subversion (e immagino deposito generale). Ho usato SVN per i miei progetti negli ultimi anni, ma non ho mai compreso il concetto completo di queste directory.

Cosa vogliono dire?

Hmm, non sono sicuro di essere d’accordo con Nick re tag essere simile a un ramo. Un tag è solo un marker

  • Il tronco sarebbe il principale corpo di sviluppo, che ha origine dall’inizio del progetto fino al presente.

  • Branch sarà una copia del codice derivata da un determinato punto nel trunk utilizzato per applicare le principali modifiche al codice preservando l’integrità del codice nel trunk. Se le principali modifiche funzionano in base al piano, di solito vengono rimesse nel bagagliaio.

  • Tag sarà un punto nel tempo sul tronco o un ramo che si desidera conservare. Le due ragioni principali per la conservazione sarebbero che questa è una versione importante del software, sia alfa, beta, RC o RTM, o questo è il punto più stabile del software prima che venissero applicate le principali revisioni del tronco.

Nei progetti open source, le principali filiali che non sono accettate nel bagaglio dagli stakeholder del progetto possono diventare le basi per le forche – ad esempio, progetti totalmente separati che condividono un’origine comune con altro codice sorgente.

Prima di tutto, come sottolineano @AndrewFinnell e @KenLiu, in SVN i nomi delle directory non significano nulla – “trunk, branches e tag” sono semplicemente una convenzione comune utilizzata dalla maggior parte dei repository. Non tutti i progetti utilizzano tutte le directory (è abbastanza normale non utilizzare affatto i “tag”), e in effetti nulla ti impedisce di chiamarli come desideri, anche se la rottura della convenzione è spesso confusa.

Descriverò probabilmente lo scenario di utilizzo più comune di rami e tag e fornirò uno scenario di esempio su come vengono utilizzati.

  • Trunk : l’area di sviluppo principale. È qui che si trova la tua prossima versione principale del codice, e in genere ha tutte le funzionalità più recenti.

  • Succursali : ogni volta che rilasci una versione principale, viene creato un ramo. Ciò consente di eseguire correzioni di bug e creare una nuova versione senza dover rilasciare le funzionalità più recenti, possibilmente non terminate o non testate.

  • Tag : ogni volta che rilasci una versione (versione finale, release candidate (RC) e beta) fai un tag per questo. Questo ti dà una copia point-in-time del codice così com’era in quello stato, permettendoti di tornare indietro e riprodurre eventuali bug, se necessario, in una versione precedente, o di rilasciare nuovamente una versione precedente esattamente com’era. Rami e tag in SVN sono leggeri – sul server, non fa una copia completa dei file, solo un indicatore che dice “questi file sono stati copiati in questa revisione” che richiede solo pochi byte. Con questo in mente, non dovresti mai preoccuparti di creare un tag per qualsiasi codice rilasciato. Come ho detto prima, i tag vengono spesso omessi e, invece, un log delle modifiche o un altro documento chiarisce il numero di revisione al momento del rilascio.


Ad esempio, diciamo che inizi un nuovo progetto. Si inizia a lavorare in “trunk”, su ciò che verrà rilasciato come versione 1.0.

  • trunk / – versione di sviluppo, che presto sarà 1.0
  • rami / – vuoto

Una volta terminata la 1.0.0, si dirama il tronco in un nuovo ramo “1.0” e si crea un tag “1.0.0”. Ora lavoriamo su ciò che alla fine sarà 1.1 continua nel bagagliaio.

  • trunk / – versione di sviluppo, presto 1.1
  • branches / 1.0 – 1.0.0 versione di rilascio
  • tags / 1.0.0 – 1.0.0 versione di rilascio

Si incontrano alcuni bug nel codice e li si risolve nel trunk, quindi si uniscono le correzioni sul ramo 1.0. Puoi anche fare l’opposto e correggere i bug nel ramo 1.0 e quindi unirli nuovamente al trunk, ma in genere i progetti si attaccano alla fusione a senso unico solo per ridurre la possibilità di perdere qualcosa. A volte un bug può essere corretto solo in 1.0 perché è obsoleto in 1.1. Non ha molta importanza: vuoi solo assicurarti di non rilasciare 1.1 con gli stessi bug che sono stati corretti in 1.0.

  • trunk / – versione di sviluppo, presto 1.1
  • branches / 1.0 – rilascio imminente 1.0.1
  • tags / 1.0.0 – 1.0.0 versione di rilascio

Una volta trovati abbastanza bug (o forse un bug critico), decidi di fare una versione 1.0.1. Quindi fai un tag “1.0.1” dal ramo 1.0 e rilascia il codice. A questo punto, il trunk conterrà quello che sarà 1.1 e il ramo “1.0” contiene il codice 1.0.1. La prossima volta che rilascerai un aggiornamento a 1.0, sarebbe 1.0.2.

  • trunk / – versione di sviluppo, presto 1.1
  • branches / 1.0 – imminente versione 1.0.2
  • tags / 1.0.0 – 1.0.0 versione di rilascio
  • tags / 1.0.1 – 1.0.1 versione di rilascio

Alla fine sei quasi pronto per rilasciare 1.1, ma prima vuoi fare una beta. In questo caso, probabilmente esegui un ramo “1.1” e un tag “1.1beta1”. Ora, il lavoro su ciò che sarà 1.2 (o 2.0 forse) continua nel trunk, ma il lavoro su 1.1 continua nel ramo “1.1”.

  • trunk / – versione di sviluppo, che sarà presto 1.2
  • branches / 1.0 – imminente versione 1.0.2
  • branches / 1.1 – imminente versione 1.1.0
  • tags / 1.0.0 – 1.0.0 versione di rilascio
  • tags / 1.0.1 – 1.0.1 versione di rilascio
  • tags / 1.1beta1 – 1.1 beta 1 versione di rilascio

Una volta rilasciato 1.1 final, si esegue un tag “1.1” dal ramo “1.1”.

Puoi anche continuare a mantenere 1.0 se lo desideri, porting di correzioni di bug tra tutti e tre i rami (1.0, 1.1 e trunk). Il takeaway importante è che per ogni versione principale del software che si sta mantenendo, si dispone di un ramo che contiene l’ultima versione del codice per quella versione.


Un altro uso dei rami è per le funzionalità. Qui è dove si dirama il tronco (o uno dei rami di rilascio) e si lavora su una nuova funzione isolata. Una volta completata la funzione, la si unisce e si rimuove il ramo.

  • trunk / – versione di sviluppo, che sarà presto 1.2
  • branches / 1.1 – imminente versione 1.1.0
  • rami / ui-riscrittura – ramo della funzione sperimentale

L’idea di questo è quando si sta lavorando su qualcosa di dirompente (che potrebbe ostacolare o interferire con altre persone dal loro lavoro), qualcosa di sperimentale (che potrebbe anche non farcela), o forse solo qualcosa che richiede molto tempo (e temo che se si tratti di una versione 1.2 quando si è pronti per estrarre 1.2 dal trunk), è ansible farlo separatamente nel ramo. In genere, puoi tenerlo aggiornato con il trunk unendo continuamente le modifiche in esso, il che rende più facile re-integrarsi (unire di nuovo al trunk) quando hai finito.


Inoltre, lo schema di versioning che ho usato qui è solo uno dei tanti. Alcuni team eseguono correzioni di bug / manutenzione come 1.1, 1.2, ecc. E modifiche principali come 1.x, 2.x, ecc. L’uso qui è lo stesso, ma puoi chiamare il ramo “1” o “1” .x “invece di” 1.0 “o” 1.0.x “. (A parte, il versioning semantico è una buona guida su come fare i numeri di versione).

Oltre a ciò che Nick ha detto, puoi scoprire di più su Streamed Lines: Branching Patterns per Parallel Software Development

inserisci la descrizione dell'immagine qui

In questa figura main è il trunk, rel1-maint è un ramo e 1.0 è un tag.

In generale (vista agnostica dello strumento), un ramo è il meccanismo utilizzato per lo sviluppo parallelo. Un SCM può avere da 0 a n rami. Subversion ha 0.

  • Trunk è un ramo principale consigliato da Subversion , ma non sei obbligato a crearlo. Potresti chiamarlo “main” o “releases”, o non averne affatto!

  • Branch rappresenta uno sforzo di sviluppo. Non dovrebbe mai essere chiamato dopo una risorsa (come ‘vonc_branch’) ma dopo:

    • uno scopo “myProject_dev” o “myProject_Merge”
    • un perimetro di rilascio ‘myProjetc1.0_dev’or myProject2.3_Merge’ o ‘myProject6..2_Patch1’ …
  • Tag è un’istantanea di file per tornare facilmente a quello stato. Il problema è che tag e branch sono gli stessi in Subversion . E raccomanderei sicuramente l’approccio paranoico:

    puoi usare uno degli script di controllo di accesso forniti con Subversion per impedire a chiunque di fare qualsiasi cosa se non creare nuove copie nell’area dei tag.

Un tag è definitivo. Il suo contenuto non dovrebbe mai cambiare. MAI. Mai. Hai dimenticato una riga nella nota di rilascio? Crea un nuovo tag. Obsoleto o rimuovere quello vecchio.

Ora, leggo molto su “unire di nuovo tali e tali in tali e tali rami, quindi finalmente nel ramo del tronco”. Questo è chiamato stream di lavoro di fusione e qui non c’è nulla di obbligatorio . Non è perché hai un ramo di tronco che devi unire di nuovo qualsiasi cosa.

Per convenzione, il ramo del tronco può rappresentare lo stato attuale del tuo sviluppo, ma questo è per un semplice progetto sequenziale, cioè un progetto che ha:

  • no sviluppo “in anticipo” (per preparare la prossima versione successiva che implica cambiamenti tali da non essere compatibili con lo sviluppo attuale del “tronco”)
  • nessun enorme refactoring (per testare una nuova scelta tecnica)
  • nessuna manutenzione a lungo termine di una versione precedente

Perché con uno (o tutti) di questi scenari, si ottengono quattro “bauli”, quattro “sviluppi attuali” e non tutto ciò che si fa in questi sviluppi paralleli dovrà necessariamente essere riunito in “tronco”.

In SVN un tag e un ramo sono molto simili.

Tag = una porzione definita nel tempo, solitamente utilizzata per le versioni

Branch = anche una porzione definita nel tempo in cui lo sviluppo può continuare, solitamente utilizzato per le versioni principali come 1.0, 1.5, 2.0, ecc., Quindi quando si rilascia tag il ramo. Ciò consente di continuare a supportare una versione di produzione mentre si spostano in avanti con interruzioni nel bagagliaio

Trunk = spazio di lavoro per lo sviluppo, questo è il luogo in cui dovrebbe avvenire lo sviluppo e quindi le modifiche vengono rimosse dalle versioni del ramo.

Non hanno davvero alcun significato formale. Una cartella è una cartella in SVN. Sono un modo generalmente accettato di organizzare il tuo progetto.

  • Il tronco è dove mantieni la linea principale di sviluppo. La cartella delle diramazioni è dove potresti creare, bene, rami, che sono difficili da spiegare in un breve post.

  • Un ramo è una copia di un sottoinsieme del tuo progetto su cui lavori separatamente dal trunk. Forse è per esperimenti che potrebbero non andare da nessuna parte, o forse è per la prossima versione, che poi si unirà di nuovo nel bagagliaio quando diventerà stabile.

  • E la cartella tag è per la creazione di copie con tag del tuo repository, solitamente ai checkpoint di rilascio.

Ma come ho detto, per SVN, una cartella è una cartella. branch , trunk e tag sono solo una convenzione.

Sto usando la parola “copia” liberamente. SVN in realtà non fa copie complete di cose nel repository.

Il trunk è la linea di sviluppo che contiene il codice sorgente e le funzionalità più recenti. Dovrebbe avere le ultime correzioni di bug in esso così come le ultime funzionalità aggiunte al progetto.

I rami sono solitamente usati per fare qualcosa lontano dal tronco (o da altre linee di sviluppo) che altrimenti romperebbero la costruzione. Le nuove funzionalità sono spesso costruite in un ramo e quindi reinserite nel trunk. I rami contengono spesso codice che non è necessariamente approvato per la linea di sviluppo da cui è derivato. Ad esempio, un programmatore può provare un’ottimizzazione su qualcosa in una succursale e unirsi alla linea di sviluppo solo una volta che l’ottimizzazione è soddisfacente.

I tag sono istantanee del repository in un determinato momento. Su questi non dovrebbe verificarsi alcuno sviluppo. Sono spesso utilizzati per prendere una copia di ciò che è stato rilasciato a un client in modo da poter facilmente accedere a ciò che sta usando un client.

Ecco un link a un’ottima guida ai repository:

  • Source Control HOWTO

Vale anche la pena leggere gli articoli su Wikipedia.

Ora questo è il punto sullo sviluppo del software, non c’è una conoscenza coerente di nulla, tutti sembrano averlo fatto a modo loro, ma è perché è comunque una disciplina relativamente giovane.

Ecco il mio semplice modo semplice,

trunk – La directory trunk contiene il corpo di lavoro più aggiornato, approvato e unito. Contrariamente a quanto molti hanno confessato, il mio baule è solo per un lavoro pulito, pulito, approvato e non un’area di sviluppo, ma piuttosto un’area di rilascio.

Ad un certo punto nel tempo, quando il tronco sembra pronto per essere rilasciato, viene taggato e rilasciato.

rami – La directory dei rami contiene esperimenti e lavori in corso. Il lavoro sotto un ramo rimane lì finché non viene approvato per essere unito nel bagagliaio. Per me, questa è l’area in cui viene svolto tutto il lavoro.

Per esempio: posso avere un ramo di iterazione 5 per un quinto round di sviluppo sul prodotto, forse un ramo di prototipo 9 per un nono round di sperimentazione e così via.

tag : la directory dei tag contiene istantanee di rami approvati e versioni di trunk. Ogni volta che un ramo viene approvato per unire nel bagagliaio o viene creata una versione del trunk, viene creata un’istantanea del ramo approvato o del rilascio del tronco sotto i tag.

Suppongo che con i tag posso saltare avanti e indietro nel tempo a punti di interesse abbastanza facilmente.

La directory principale è la directory che probabilmente ti è più familiare, perché è usata per contenere le modifiche più recenti. La base di codice principale dovrebbe essere nel bagagliaio.

La directory dei rami serve a contenere i tuoi rami, qualunque essi siano.

La directory dei tag è fondamentalmente per il tagging di un certo insieme di file. Lo fai per cose come le versioni, dove vuoi che “1.0” siano questi file a queste revisioni e “1.1” siano questi file a queste revisioni. Di solito non modifichi i tag una volta creati. Per ulteriori informazioni sui tag, vedere il Capitolo 4. Branching e fusione (in Version Control with Subversion ).

Uno dei motivi per cui ognuno ha una definizione leggermente diversa è perché Subversion implementa il supporto zero per rami e tag. In sostanza, Subversion dice: abbiamo esaminato i rami e i tag completi in altri sistemi e non li abbiamo trovati utili, quindi non abbiamo implementato nulla. Basta fare una copia in una nuova directory con una convenzione di nome . Quindi ovviamente ognuno è libero di avere convenzioni leggermente diverse. Per capire la differenza tra un tag reale e una semplice convenzione di denominazione + copia, vedi la voce di Wikipedia Tag e rami di Subversion .

Ho trovato questo fantastico tutorial su SVN quando stavo cercando il sito web dell’autore del libro di ricette per la programmazione di applicazioni per la visione artificiale OpenCV 2 e ho pensato che dovevo condividerlo.

Ha un tutorial su come usare SVN e cosa significano le frasi ‘trunk’, ‘tag’ e ‘branch’.

Citato direttamente dal suo tutorial:

La versione corrente del tuo progetto software, su cui il tuo team sta attualmente lavorando, si trova di solito in una directory chiamata trunk . Con l’evolversi del progetto, lo sviluppatore aggiorna quella versione correggendo i bug, aggiungendo nuove funzionalità) e inviando le sue modifiche sotto quella directory.

In qualsiasi momento, è ansible congelare una versione e acquisire un’istantanea del software così com’è in questa fase dello sviluppo. Questo generalmente corrisponde alle versioni ufficiali del software, ad esempio quelle che consegnerai ai tuoi clienti. Queste istantanee si trovano sotto la directory dei tag del tuo progetto.

Infine, è spesso utile creare, a un certo punto, una nuova linea di sviluppo per il tuo software. Ciò accade, ad esempio, quando si desidera testare un’implementazione alternativa in cui è necessario modificare il software ma non si desidera inviare queste modifiche al progetto principale finché non si decide se si adotta la nuova soluzione. Il team principale può quindi continuare a lavorare sul progetto mentre altri sviluppatori lavorano sul prototipo. Metterei queste nuove linee di sviluppo del progetto in una directory chiamata branch .

Tag = una porzione definita nel tempo, solitamente utilizzata per le versioni

Penso che questo sia ciò che in genere significa “tag”. Ma in Subversion:

Non hanno davvero alcun significato formale. Una cartella è una cartella in SVN.

che trovo piuttosto confuso: un sistema di controllo di revisione che non sa nulla di rami o tag. Da un punto di vista dell’implementazione, penso che il modo di creare le “copie” di Subversion sia molto intelligente, ma dovrei sapere che è ciò che definirei un’astrazione che perde .

O forse ho usato CVS da troppo tempo.

Penso che parte della confusione derivi dalla differenza tra il concetto di tag e l’implementazione in SVN. Per SVN un tag è un ramo che è una copia. La modifica dei tag è considerata sbagliata e in effetti strumenti come TortoiseSVN ti avviseranno se tenti di modificare qualcosa con ../tags/ .. nel percorso.

Non sono proprio sicuro di cosa sia “tag”, ma branch è un concetto di controllo del codice sorgente abbastanza comune.

Fondamentalmente, un ramo è un modo per lavorare sulle modifiche al codice senza intaccare il tronco. Supponi di voler aggiungere una nuova funzionalità che sia abbastanza complicata. Vuoi essere in grado di controllare le modifiche mentre le fai, ma non vuoi che influenzi il tronco finché non hai finito con la funzione.

Innanzitutto devi creare un ramo. Questa è fondamentalmente una copia del tronco nel momento in cui hai creato il ramo. Dovresti fare tutto il tuo lavoro nel ramo. Eventuali modifiche apportate nel ramo non influiscono sul trunk, quindi il trunk è ancora utilizzabile, consentendo ad altri di continuare a lavorare lì (come fare correzioni di bug o piccoli miglioramenti). Una volta completata la funzione, reintegrerai il ramo nel bagagliaio. Questo sposterebbe tutte le tue modifiche dal ramo al tronco.

Ci sono un certo numero di modelli che le persone usano per i rami. Se si dispone di un prodotto con più versioni principali supportate contemporaneamente, di solito ciascuna versione sarebbe una succursale. Dove lavoro, abbiamo un ramo di controllo qualità e un ramo di produzione. Prima di rilasciare il nostro codice al QA, integriamo le modifiche al ramo QA, quindi distribuiamo da lì. Al momento del rilascio alla produzione, ci integriamo dal ramo QA al ramo Produzione, quindi sappiamo che il codice in esecuzione in produzione è identico a quello testato dal QA.

Ecco la voce di Wikipedia sui rami , poiché probabilmente spiegano le cose meglio di me. 🙂

Trunk è la cartella di base del codice dell’applicazione. È qui che lavori sulla tua prossima versione / rilascio.

Branch è una cartella che ti consente di scegliere un momento nel tempo e ti consente di percorrere un diverso percorso di sviluppo rispetto a quello di / Trunk. Un uso comune di Branch è quello di fornire al team di sviluppo l’accesso a un’istantanea corrente dell’applicazione come esistente nella produzione, ad es. / Branch / produzione manutenzione.

Questo concetto di “ramificazione” consente al tuo team di creare correzioni / miglioramenti alla produzione, senza influire sul lavoro in corso per la tua prossima versione, attualmente in corso in / Trunk. I rami possono anche essere mini-pezzi di funzionalità che, in team di grandi dimensioni, consentono agli sviluppatori di lavorare su atomicamente, e si fondono nuovamente in / Trunk in un punto futuro.

Tag è una cartella che ti consente di scattare istantanee della tua applicazione e di lavorare con quelle “build” particolari. Ciò consente flessibilità alla tua squadra, sia nei test che nel trovare le differenze tra le build. Troverai spesso una convenzione di denominazione seguita in / Branch, che si riferisce alle tue build, es. /Branch/2.0.0, /Branch/2.0.1, /Branch/3.1.0 e così via. La convenzione di denominazione spetta a te e al tuo team; tienilo coerente!

Trunk : dopo il completamento di ogni sprint in agile, viene prodotto un prodotto parzialmente scaricabile. Queste versioni sono mantenute nel bagagliaio.

Succursali : tutti i codici di sviluppo paralleli per ogni sprint in corso vengono mantenuti nelle filiali.

Tag : ogni volta che rilasciamo una versione beta del prodotto parzialmente utilizzabile, facciamo un tag per questo. Questo ci dà il codice che era disponibile in quel momento, permettendoci di tornare a quello stato se richiesto ad un certo punto durante lo sviluppo.

Per chi ha familiarità con GIT, il master in GIT è equivalente al trunk in SVN.

Branch e tag hanno la stessa terminologia sia in GIT che in SVN.