Perché dovrei preoccuparmi dei tag leggeri rispetto a quelli con annotazioni?


346

Sono passato da Subversion a Git come il mio VCS quotidiano l'anno scorso e sto ancora cercando di cogliere i punti più sottili di "Git-think".

Quello che mi ha infastidito di recente è il tag "leggero" rispetto ai tag annotati e firmati. Sembra universalmente accettato che i tag con annotazioni siano superiori ai tag leggeri per tutti gli usi reali, ma le spiegazioni che ho trovato per questo motivo sembrano sempre ridursi a "perché le migliori pratiche" o "perché sono diverse" . Sfortunatamente, questi sono argomenti molto insoddisfacenti senza sapere perché sono le migliori pratiche o come tali differenze sono rilevanti per il mio utilizzo di Git.

Quando sono passato per la prima volta a Git, i tag leggeri sembravano essere la cosa migliore dopo il pane a fette; Potrei semplicemente indicare un commit e dire "era 1.0". Ho difficoltà a capire come un tag potrebbe mai essere necessario essere più di questo, ma di certo non posso credere che gli esperti Git del mondo preferiscano arbitrariamente i tag annotati! Allora, di cosa si tratta?

(Punti bonus: perché mai dovrei aver bisogno di firmare un tag?)

MODIFICARE

Sono stato convinto con successo che i tag annotati siano una buona cosa: sapere chi è stato taggato e quando è importante! Come follow-up, qualche consiglio su buone annotazioni dei tag? Entrambi git tag -am "tagging 1.0" 1.0e cercando di riassumere il registro di commit dal momento che il tag precedente sembra perdere strategie.


Hai trovato una buona risposta per il tuo follow-up? Qualcosa di simile a? git log --pretty=oneline master..HEAD | git tag -a -F - $BRANCH.$BUILD_NUMBER
dalore,

Riassumendo il registro di commit dal momento che il tag precedente mi sembra un'ottima strategia per i messaggi tag.
Rooby,

Cordiali saluti (1.) Per elencare i tag LIGHTWEIGHT per data, vai qui . (2.) Per elencare i tag ANNOTATI per data, vai qui .
Trevor Boyd Smith,

Risposte:


272

Il grande vantaggio di un tag annotato è che sai chi l'ha creato. Proprio come con gli commit, a volte è bello sapere chi è stato. Se sei uno sviluppatore e vedi che v1.7.4 è stato taggato (dichiarato pronto) e non sei così sicuro, con chi parli? La persona il cui nome è nel tag annotato! (Se vivi in ​​un mondo diffidente, questo impedisce anche alle persone di cavarsela con le cose che non dovrebbero.) Se sei un consumatore, quel nome è un marchio di autorità: questo è Junio ​​Hamano che dice che questa versione di Git è qui rilasciato.

Anche gli altri metadati possono essere utili - a volte è bello sapere quando è stata rilasciata quella versione, non solo quando è stato eseguito il commit finale. E a volte il messaggio può anche essere utile. Forse aiuta a spiegare lo scopo di quel particolare tag. Forse il tag per un candidato di rilascio contiene un po 'di un elenco di stato / cose da fare.

Firmare i tag è praticamente come firmare qualsiasi altra cosa: fornisce un ulteriore livello di sicurezza per il paranoico. La maggior parte di noi non lo userà mai, ma se vuoi davvero verificare tutto prima di mettere quel software sul tuo computer, potresti volerlo.

Modificare:

Quanto a cosa scrivere in un'annotazione di tag, hai ragione: non c'è sempre molto da dire. Per un tag numero di versione, è implicitamente inteso che contrassegna quella versione e se sei soddisfatto dei log delle modifiche altrove, non è necessario inserirne uno. In questo caso, è davvero il tagger e la data che sono i più importanti. L'unica altra cosa che mi viene in mente è una sorta di timbro di approvazione da una suite di test. Dai un'occhiata ai tag di git.git: tutti dicono semplicemente qualcosa come "Git 1.7.3 rc1"; tutto ciò che ci interessa davvero è il nome di Junio ​​Hamano su di loro.

Tuttavia, per i tag meno ovviamente denominati, il messaggio potrebbe diventare molto più importante. Potrei immaginare di taggare una versione specifica per un singolo utente / client, un importante traguardo non versione o (come menzionato sopra) un candidato al rilascio con ulteriori informazioni. Il messaggio è quindi molto più utile.


4
solo per fare un confronto con SVN, poiché l'OP proviene da quel sistema: i metadati dei tag annotati equivalgono alla modifica SVN effettiva che fa il ramo tag, che in SVN ha il proprio autore e messaggio. E, potenzialmente, restrizioni separate su chi può creare un tag, distinto da chi può controllare le modifiche, una distinzione irrilevante se si sta semplicemente usando il sistema per le proprie cose.
Araqnid,

10
Ah-ah! Sembra che la mia comprensione qui sia stata ostacolata dal fatto che tutti i miei progetti Git finora sono stati solo. Non ho mai avuto bisogno di sapere a chi dare la colpa per qualcosa (sono sempre io!), Quindi non avevo notato che i tag leggeri non tracciano il tagger.
Ben Blank,

5
git help logriassume ora come segue: "I tag annotati sono pensati per il rilascio mentre i tag leggeri sono pensati per le etichette di oggetti privati ​​o temporanei".
Jon Gjengset,

1
@javabrett Anche se questa è una buona parte della risposta a "quali sono le differenze tra i tag annotati e leggeri", la domanda qui era specificamente perché le persone vogliono archiviare informazioni extra e quindi utilizzare i tag annotati. (E non credo di poter dire seriamente che "crea un blob" è un aspetto negativo: fai quello che devi fare per archiviare le informazioni che vuoi conservare e, se si tratta di informazioni significative, richiederà un blob. )
Cascabel,

1
@Chris sì, come dice la risposta, "Il grande vantaggio di un tag annotato è che sai chi l'ha creato." Puoi sempre provare tu stesso le cose per scoprirlo:git tag -a -m 'my message' my-tag; git show my-tag
Cascabel,

64

La mia opinione personale, leggermente diversa su questo argomento:

  • I tag annotati sono quei tag pensati per essere pubblicati per altri sviluppatori, molto probabilmente nuove versioni (che dovrebbero anche essere firmate). Non solo per vedere chi ha taggato e quando è stato taggato, ma anche perché (di solito un log delle modifiche).
  • I pesi leggeri sono più appropriati per l'uso privato, ciò significa che è necessario contrassegnare impegni speciali per poterli ritrovare. Possa essere rivederli, controllarli per testare qualcosa o qualunque cosa.

4
Questo è menzionato anche sull'uomo git-tag: "tag annotati sono pensati per il rilascio, mentre i tag leggeri sono pensati per etichette degli oggetti privati o temporanei.": Stackoverflow.com/a/35059291/895245
Ciro Santilli郝海东冠状病六四事件法轮功

28

Per impostazione predefinita, Git considera i tag annotati solo come base per comandi come git describe. Pensa ai tag annotati come cartelli che hanno un significato duraturo per te stesso e gli altri, mentre i tag leggeri sono più simili ai segnalibri che puoi trovare in un secondo momento. Pertanto, vale la pena utilizzare i tag annotati come riferimento, mentre i tag leggeri non dovrebbero esserlo.

La firma di un tag è una garanzia dell'identità del firmatario. Permette agli utenti di verificare, ad esempio, che il codice del kernel Linux che hanno raccolto sia lo stesso codice che Linus Torvalds ha effettivamente rilasciato. La firma può anche essere un'affermazione che il firmatario garantisce la qualità e l'integrità del software a quel commit.


1
git push --follow-tagsè un altro comando che tratta entrambi in modo diverso: stackoverflow.com/a/26438076/895245
Ciro Santilli郝海东冠状病六四事件法轮功

1
Grazie per il suggerimento git describe. Lo uso nel sistema di integrazione continua e un paio di volte la stringa di versione non era quella che mi aspettavo.
jjmontes,

9

La firma di un tag è un modo semplice per affermare l'autenticità di una versione.

Ciò è particolarmente utile in un DVCS perché chiunque può clonare il repository e modificare la cronologia (ad es. Tramite git-filter-branch). Se un tag è firmato, la firma non sopravviverà a un'operazione git-filter-branch, quindi se hai una politica secondo cui ogni versione è taggata e firmata da un committer, è possibile rilevare un tag di versione falso nel repository.

Se non fosse per la firma, non vedrei nemmeno molto senso nei tag annotati.


1
In realtà, per questo potrebbe essere utile avere una firma che segni solo l'albero commesso, non la sua intera storia (non mi importa se qualcuno ha manomesso la storia, voglio solo essere sicuro di avere il codice giusto).
Paŭlo Ebermann,

9

Spingi i tag con annotazioni, mantieni il locale leggero

Alcuni comportamenti Git si differenziano tra loro in modo che questa raccomandazione sia utile, ad esempio:

  • i tag annotati possono contenere un messaggio, un creatore e una data diversi dal commit a cui puntano. Quindi potresti usarli per descrivere una versione senza effettuare un commit della versione.

    I tag leggeri non hanno queste informazioni extra e non ne hanno bisogno, poiché le utilizzerai solo per svilupparle.

  • git push --follow-tags invierà solo tag con annotazioni
  • git describe senza opzioni della riga di comando vede solo tag con annotazioni

man git-tag dice:

I tag con annotazioni sono pensati per il rilascio mentre i tag leggeri sono pensati per etichette di oggetti private o temporanee.

Differenze interne

  • sia i tag leggeri che quelli con annotazioni sono un file .git/refs/tagscontenente un SHA-1

  • per tag leggeri, SHA-1 punta direttamente a un commit:

    git tag light
    cat .git/refs/tags/light
    

    stampa lo stesso di HEAD SHA-1.

    Quindi non c'è da stupirsi che non possano contenere altri metadati.

  • i tag annotati puntano a un oggetto tag nel database degli oggetti.

    git tag -as -m msg annot
    cat .git/refs/tags/annot
    

    contiene lo SHA dell'oggetto tag annotato:

    c1d7720e99f9dd1d1c8aee625fd6ce09b3a81fef
    

    e quindi possiamo ottenere il suo contenuto con:

    git cat-file -p c1d7720e99f9dd1d1c8aee625fd6ce09b3a81fef
    

    uscita campione:

    object 4284c41353e51a07e4ed4192ad2e9eaada9c059f
    type commit
    tag annot
    tagger Ciro Santilli <your@mail.com> 1411478848 +0200
    
    msg
    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v1.4.11 (GNU/Linux)
    
    <YOUR PGP SIGNATURE>
    -----END PGP SIGNAT
    

    Ed è così che contiene metadati extra. Come possiamo vedere dall'output, i campi dei metadati sono:

    Un'analisi più dettagliata del formato è presente in: Qual è il formato di un oggetto tag git e come calcolare il suo SHA?

bonus


6

Ho trovato l'unico buon uso dei tag leggeri: creare una versione di GitHub in retrospettiva.

Abbiamo rilasciato il nostro software e abbiamo avuto i commit necessari, semplicemente non ci siamo preoccupati di mantenere la sezione 'Release' su GitHub. E quando abbiamo prestato un po 'di attenzione, ci siamo resi conto che avremmo voluto aggiungere anche alcune versioni precedenti, con le vecchie date di rilascio corrette per loro.

Se dovessimo solo creare un tag annotato su un vecchio commit, GitHub prenderebbe la data per il rilascio dall'oggetto tag. Al contrario, quando abbiamo creato un tag leggero per questo vecchio commit, la versione ha iniziato a mostrare la data (vecchia) corretta. Guida di Source @ GitHub, "Informazioni sulle versioni"

Sembra anche possibile specificare la data desiderata per un commit annotato, ma non mi sembra così semplice: https://www.kernel.org/pub/software/scm/git/docs/git-tag. html # _on_backdating_tags


Anche se oggi ho scoperto che GitHub ha smesso di onorare le date dei tag per me (sia per i tag leggeri che per quelli annullati). Ignora semplicemente la data durante la pubblicazione della versione e ricorda invece la data e l'ora in cui ho premuto il pulsante "Pubblica" per la versione.
evilkos,

Sì, mi sono anche imbattuto in questo casino su GitHub e sui tag annotati. Non ho capito perché l'hanno implementato in questo modo ..
YakovL

1

Nel mio ufficio inseriremo l'indirizzo della pagina Web di rilascio nel corpo del tag. La pagina Web della versione dettaglia tutte le diverse nuove funzionalità e correzioni dall'ultima versione. Il management non guarderà nel repository git per scoprire quali cambiamenti sono avvenuti ed è bello avere un elenco conciso di ciò che è in quella versione.


0

I tag con annotazioni memorizzano metadati extra come nome dell'autore, note di rilascio, tag-message e data come oggetti completi nel database Git. Tutti questi dati sono importanti per una versione pubblica del tuo progetto.

tag git -a v1.0.0

I tag leggeri sono il modo più semplice per aggiungere un tag al tuo repository git perché memorizzano solo l'hash del commit a cui si riferiscono. Possono agire come "segnalibri" per un commit, in quanto tali, sono ottimi per uso privato.

tag git v1.0.0

Puoi ordinare, elencare, eliminare, mostrare e modificare vecchi tag. Tutte queste funzioni ti aiuteranno a identificare specifiche versioni di rilascio del tuo codice. Ho trovato questo articolo che potrebbe aiutarti a farti un'idea di cosa possono fare i tag.


0

Per me la differenza importante è che il tag leggero non ha il timestamp. Supponiamo che tu abbia aggiunto diversi tag leggeri:

git tag v1
git tag v2
git tag v3

e poi, forse più tardi, vuoi ottenere l'ultimo tag leggero aggiunto. Non c'è modo di farlo. Né "git descript" né "git tag" non ti daranno cronologicamente l'ultimo tag leggero. "git tag -l" può restituirli tutti o ordinarli in ordine lex, ma non per data / ora. "git descritto --tags" restituirà "v1" che non è sicuramente il tag aggiunto per ultimo.

D'altra parte, se aggiungi tag annotati:

git tag v1 -m v1
git tag v2 -m v1
git tag v3 -m v1

puoi sempre ottenere il timestamp di ogni tag e "git descritto" restituirà sicuramente "v3" che è davvero l'ultimo tag aggiunto.


Devi usare -a per essere annotato.
Alex,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.