In che modo un tag è diverso da un ramo in Git? Quale dovrei usare qui?

Sto avendo qualche difficoltà a capire come usare tag contro rami in git .

Ho appena spostato la versione corrente del nostro codice da cvs a git , e ora lavorerò su un sottoinsieme di quel codice per una particolare caratteristica. Anche altri sviluppatori lavoreranno su questo, ma non tutti gli sviluppatori del nostro gruppo si prenderanno cura di questa funzione. Dovrei creare un ramo o un tag? In quali situazioni dovrei usare l’una rispetto all’altra?

Un tag rappresenta una versione di un particolare ramo in un momento nel tempo. Un ramo rappresenta un thread di sviluppo separato che può essere eseguito in concomitanza con altri sforzi di sviluppo sulla stessa base di codice. Le modifiche a un ramo possono alla fine essere riunite in un altro ramo per unificarle.

Di solito tagghi una particolare versione in modo da poterla ricreare, ad esempio, questa è la versione che abbiamo spedito a XYZ Corp. Una branca è più una strategia per fornire aggiornamenti in corso su una particolare versione del codice mentre si continua a fare lo sviluppo su di esso. Farai un ramo della versione consegnata, prosegui lo sviluppo sulla linea principale, ma fai correzioni di bug al ramo che rappresenta la versione consegnata. Alla fine, unirai queste correzioni di bug alla linea principale. Spesso userete sia branching che tagging insieme. Avrai vari tag che possono essere applicati sia alla linea principale che alle sue diramazioni contrassegnando particolari versioni (quelle consegnate ai clienti, ad esempio) lungo ciascun ramo che potresti voler ricreare – per consegna, diagnosi di bug, ecc.

In realtà è più complicato di così – o complicato come vuoi farlo – ma questi esempi dovrebbero darti un’idea delle differenze.

Dal punto di vista teorico :

  • i tag sono nomi simbolici per una determinata revisione . Puntano sempre allo stesso object (di solito: alla stessa revisione); non cambiano.
  • i rami sono nomi simbolici per la linea di sviluppo . Nuovi commit vengono creati in cima al ramo. Il puntatore del ramo avanza naturalmente, indicando commit più recenti e più recenti.

Dal punto di vista tecnico :

  • i tag risiedono in refs/tags/ namespace e possono puntare a taggare gli oggetti ( tag annotati e opzionalmente firmati GPG) o direttamente sull’object commit (tag leggero meno utilizzato per i nomi locali) o, in casi molto rari, anche su oggetti tree o oggetti blob (ad es. firma GPG).
  • i rami risiedono in refs/heads/ namespace e possono puntare solo agli oggetti commit . Il puntatore HEAD deve fare riferimento a un ramo (riferimento simbolico) o direttamente a un commit (HEAD distaccato o ramo senza nome).
  • i rami di localizzazione remota risiedono in refs/remotes// namespace e seguono le filiali ordinarie nel repository .

Vedi anche la pagina di manuale di Gitglossary :

ramo

Un “ramo” è una linea triggers di sviluppo. Il commit più recente su un ramo è indicato come la punta di quel ramo. La punta del ramo è referenziata da una testa di ramo, che si sposta in avanti mentre lo sviluppo addizionale viene eseguito sul ramo. Un singolo repository git può tracciare un numero arbitrario di rami, ma il tuo albero di lavoro è associato a uno solo di essi (il ramo “corrente” o “ritirato”) e HEAD punta a quel ramo.

etichetta

Un riferimento che punta a un tag o ad un object commit. A differenza di una testa, un tag non viene modificato da un commit. I tag (non gli oggetti tag) sono memorizzati in $GIT_DIR/refs/tags/ . […]. Un tag viene in genere utilizzato per contrassegnare un punto particolare nella catena di ascendenza del commit.

tag object

Un object contenente un ref che punta a un altro object, che può contenere un messaggio proprio come un object commit. Può anche contenere una firma (PGP), nel qual caso viene chiamato “object tag firmato”.

Se pensi al tuo repository come a un libro che racconta i progressi del tuo progetto …

filiali

Puoi pensare a un ramo come a uno di quei segnalibri appiccicosi:

inserisci la descrizione dell'immagine qui

Un repository nuovo di zecca ne ha solo uno (chiamato master ), che passa automaticamente all’ultima pagina (think commit ) che hai scritto. Tuttavia, sei libero di creare e utilizzare più segnalibri, al fine di contrassegnare altri punti di interesse nel libro, in modo da poterli tornare rapidamente.

Inoltre, puoi sempre spostare un particolare segnalibro su un’altra pagina del libro (usando git-reset , ad esempio); i punti di interesse variano in genere nel tempo.

tag

Puoi pensare ai tag come intestazioni di capitoli .

segnalibri

Può contenere un titolo (pensare tag annotati ) o meno. Un tag è simile ma diverso da un ramo, in quanto segna un punto di interesse storico nel libro. Per mantenere il suo aspetto storico, una volta che hai condiviso un tag (cioè lo hai trasferito su un telecomando condiviso), non dovresti spostarlo in un altro punto del libro.

Quello che devi realizzare, derivando da CVS, è che non crei più directory quando crei un ramo.
Niente più “sticky tag” (che può essere applicato a un solo file) o “tag di ramo”.
Branch e tag sono due oggetti diversi in Git, e si applicano sempre a tutti i pronti contro termine.

Non vorresti più (con SVN questa volta) strutturare esplicitamente il tuo repository con:

 branches myFirstBranch myProject mySubDirs mySecondBranch ... tags myFirstTag myProject mySubDirs mySecondTag ... 

Questa struttura deriva dal fatto che CVS è un sistema di revisione e non un sistema di versioni (vedi Controllo del codice sorgente e Controllo di revisione? ).
Ciò significa che i rami vengono emulati tramite tag per CVS, copie di directory per SVN.

La tua domanda ha senso se sei abituato a pagare un tag e iniziare a lavorarci .
Quale non dovresti;)
Un tag dovrebbe rappresentare un contenuto immutabile , utilizzato solo per accedervi con la garanzia di ottenere lo stesso contenuto ogni volta.

In Git, la cronologia delle revisioni è una serie di commit, che formano un grafico.
Un ramo è un percorso di quel grafico

 x--x--x--x--x # one branch \ --y----y # another branch 1.1 ^ | # a tag pointing to a commit 
  • Se esegui il checkout di un tag, dovrai creare un ramo per iniziare a lavorare da esso.
  • Se esegui il checkout di un ramo, vedrai direttamente l’ultimo commit (“HEAD”) di quel ramo.

Vedi la risposta di Jakub Narębski per tutti i dettagli tecnici, ma francamente, a questo punto, non hai bisogno (ancora) di tutti i dettagli;)

Il punto principale è: un tag è un semplice puntatore a un commit, non sarai mai in grado di modificare il suo contenuto. Hai bisogno di un ramo.


Nel tuo caso, ogni sviluppatore che lavora su una funzione specifica:

  • dovrebbe creare la propria filiale nei rispettivi repository
  • traccia i rami dai repository dei loro colleghi (quello che lavora sulla stessa funzione)
  • tirare / spingere per condividere il tuo lavoro con i tuoi colleghi.

Invece di tracciare direttamente le filiali dei tuoi colleghi, puoi tracciare solo il ramo di un repository centrale “ufficiale” al quale ognuno spinge il proprio lavoro per integrare e condividere il lavoro di tutti per questa particolare funzionalità.

I rami sono fatti di legno e crescono dal tronco dell’albero. I tag sono fatti di carta (derivata dal legno) e si appendono come ornamenti natalizi da vari punti dell’albero.

Il tuo progetto è l’albero e il tuo elemento che verrà aggiunto al progetto crescerà su un ramo. La risposta è un ramo.

Sembra che il modo migliore per spiegare sia che i tag fungano da rami di sola lettura. Puoi usare un ramo come tag, ma potresti inavvertitamente aggiornarlo con nuovi commit. I tag sono garantiti per puntare allo stesso commit finchè esistono.

Git Parable spiega come viene creato un tipico DVCS e perché i loro creatori hanno fatto quello che hanno fatto. Inoltre, potresti dare un’occhiata a Git for Computer Scientist ; Spiega cosa fa ogni tipo di object in Git, inclusi rami e tag.

I tag possono essere firmati o non firmati ; i rami non sono mai firmati.

I tag firmati non possono mai spostarsi perché sono vincolati crittograficamente (con una firma) a un particolare commit. I tag non firmati non sono vincolati ed è ansible spostarli (ma i tag in movimento non sono un caso d’uso normale).

I rami non possono solo passare a un commit diverso, ma dovrebbero farlo. Dovresti usare una filiale per il tuo progetto di sviluppo locale. Non ha senso impegnare il lavoro in un repository Git “su un tag”.

Un tag viene utilizzato per contrassegnare una versione, in particolare fa riferimento a un punto nel tempo su un ramo. Un ramo viene in genere utilizzato per aggiungere funzionalità a un progetto.

semplice:

Si prevede che i tag puntino sempre alla stessa versione di un progetto, mentre si prevede che le teste avanzino man mano che lo sviluppo procede.

Git Manuale dell’utente

Trunk : 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.