Mengapa saya harus peduli dengan tag yang ringan dan beranotasi?


346

Saya beralih dari Subversion ke Git sebagai VCS saya sehari-hari tahun lalu dan saya masih berusaha memahami poin-poin penting dari "Git-think".

Salah satu yang menggangguku akhir-akhir ini adalah tag "ringan" vs. tag beranotasi vs. bertanda. Tampaknya diterima secara universal bahwa tag beranotasi lebih unggul daripada tag ringan untuk semua kegunaan nyata, tetapi penjelasan yang saya temukan untuk alasan itulah mengapa tampaknya selalu mengarah ke "karena praktik terbaik" atau "karena mereka berbeda" . Sayangnya, itu adalah argumen yang sangat tidak memuaskan tanpa mengetahui mengapa itu praktik terbaik atau bagaimana perbedaan itu relevan dengan penggunaan Git saya.

Ketika saya pertama kali beralih ke Git, tag ringan tampaknya menjadi yang terbaik sejak memotong roti; Saya hanya bisa menunjuk komit dan mengatakan "itu 1.0". Saya mengalami masalah dalam memahami bagaimana sebuah tag perlu lebih dari itu, tetapi saya jelas tidak percaya bahwa para pakar Git di dunia lebih suka tag beranotasi secara sewenang-wenang! Jadi apa semua keriuhan tentang?

(Poin bonus: Mengapa saya harus menandatangani tag?)

EDIT

Saya telah berhasil meyakinkan bahwa tag beranotasi adalah Hal yang Bagus - mengetahui siapa yang menandai dan kapan penting! Sebagai tindak lanjut, saran tentang anotasi tag yang bagus? Keduanya git tag -am "tagging 1.0" 1.0dan mencoba meringkas log komit karena tag sebelumnya terasa seperti kehilangan strategi.


Apakah Anda menemukan jawaban yang baik untuk tindak lanjut Anda? Sesuatu seperti? git log --pretty=oneline master..HEAD | git tag -a -F - $BRANCH.$BUILD_NUMBER
dalore

Meringkas log komit sejak tag sebelumnya bagi saya seperti strategi yang sangat baik untuk pesan tag.
rooby

FYI (1.) Untuk daftar tag LIGHTWEIGHT berdasarkan tanggal, buka di sini . (2.) Untuk daftar tag ANNOTATED berdasarkan tanggal, buka di sini .
Trevor Boyd Smith

Jawaban:


272

Nilai tambah besar dari tag beranotasi adalah Anda tahu siapa yang membuatnya. Seperti halnya komitmen, terkadang senang mengetahui siapa yang melakukannya. Jika Anda seorang pengembang dan Anda melihat bahwa v1.7.4 telah ditandai (dinyatakan siap) dan Anda tidak begitu yakin, dengan siapa Anda berbicara? Orang yang namanya ada dalam tag beranotasi! (Jika Anda hidup di dunia yang tidak percaya, ini juga membuat orang tidak lolos dengan menandai hal-hal yang seharusnya tidak mereka lakukan.) Jika Anda seorang konsumen, nama itu adalah cap otoritas: itulah Junio ​​Hamano yang mengatakan versi git ini dengan ini dilepaskan.

Metadata lain juga bisa membantu - kadang-kadang senang mengetahui kapan versi itu dirilis, bukan hanya ketika komit terakhir dibuat. Dan terkadang pesan itu bahkan bisa bermanfaat. Mungkin ini membantu menjelaskan tujuan dari tag khusus itu. Mungkin tag untuk kandidat rilis berisi sedikit daftar status / yang harus dilakukan.

Menandatangani tag hampir sama dengan menandatangani apa pun - tag ini memberikan satu tingkat keamanan lebih untuk paranoid. Sebagian besar dari kita tidak akan pernah menggunakannya, tetapi jika Anda benar-benar ingin memverifikasi semuanya sebelum Anda meletakkan perangkat lunak itu di komputer Anda, Anda mungkin menginginkannya.

Edit:

Mengenai apa yang harus ditulis dalam anotasi tag, Anda benar - tidak selalu ada gunanya untuk dikatakan. Untuk tag nomor versi, secara implisit dipahami bahwa ini menandai versi itu, dan jika Anda senang dengan changelog Anda di tempat lain, tidak perlu menempatkannya di sana. Dalam hal ini, sebenarnya tagger dan tanggallah yang paling penting. Satu-satunya hal lain yang dapat saya pikirkan adalah semacam cap persetujuan dari test suite. Lihatlah tag git.git: mereka semua hanya mengatakan sesuatu seperti "Git 1.7.3 rc1"; yang benar-benar kami pedulikan adalah nama Junio ​​Hamano pada mereka.

Namun, untuk tag yang kurang jelas namanya, pesan bisa menjadi jauh lebih penting. Saya bisa membayangkan menandai versi tujuan khusus untuk satu pengguna / klien, beberapa tonggak penting non-versi, atau (seperti yang disebutkan di atas) kandidat rilis dengan informasi tambahan. Pesannya kemudian jauh lebih bermanfaat.


4
hanya untuk membandingkan dengan SVN, karena OP berasal dari sistem itu: metadata tag beranotasi sama dengan perubahan SVN aktual membuat cabang tag, yang dalam SVN memiliki penulis dan pesannya sendiri. Dan, berpotensi, pisahkan pembatasan siapa yang dapat membuat tag, berbeda dari siapa yang dapat memeriksa perubahan - perbedaan yang tidak relevan jika Anda hanya menggunakan sistem untuk barang-barang Anda sendiri.
araqnid

10
Ah-ha! Sepertinya pemahaman saya di sini terhalang oleh kenyataan bahwa semua proyek Git saya sejauh ini telah solo. Saya tidak pernah perlu tahu siapa yang harus disalahkan atas sesuatu (selalu saya!), Jadi saya tidak memperhatikan bahwa tag ringan tidak melacak tagger.
Ben Blank

5
git help logsekarang meringkas ini sebagai: "Tag beranotasi dimaksudkan untuk rilis sementara tag ringan dimaksudkan untuk label objek pribadi atau sementara."
Jon Gjengset

1
@javabrett Sementara itu menjadi bagian yang baik dari jawaban untuk "apa perbedaan antara tag beranotasi dan ringan", pertanyaan di sini adalah mengapa orang ingin menyimpan informasi tambahan dan dengan demikian menggunakan tag beranotasi. (Dan saya tidak berpikir saya bisa serius mengatakan "itu menciptakan gumpalan" adalah kerugian - Anda melakukan apa yang perlu Anda lakukan untuk menyimpan informasi yang ingin Anda simpan, dan jika itu adalah informasi penting, itu akan memerlukan gumpalan. )
Cascabel

1
@ Chris ya, seperti jawabannya, "Tanda tambah besar dari anotasi adalah Anda tahu siapa yang membuatnya." Anda selalu dapat mencoba sendiri hal-hal untuk mengetahuinya:git tag -a -m 'my message' my-tag; git show my-tag
Cascabel

64

Pandangan pribadi saya, yang sedikit berbeda tentang topik itu:

  • Tag beranotasi adalah tag yang dimaksudkan untuk diterbitkan untuk pengembang lain, kemungkinan besar versi baru (yang juga harus ditandatangani). Tidak hanya untuk melihat siapa yang ditandai dan kapan ditandai, tetapi juga mengapa (biasanya changelog).
  • Ringan lebih sesuai untuk penggunaan pribadi, itu berarti menandai komitmen khusus untuk dapat menemukannya lagi. Mungkin untuk meninjau mereka, periksa untuk menguji sesuatu atau apa pun.

4
Hal ini juga disebutkan pada pria git-tag: "tag Beranotasi dimaksudkan untuk rilis sementara tag ringan dimaksudkan untuk label objek pribadi atau sementara.": Stackoverflow.com/a/35059291/895245
Ciro Santilli郝海东冠状病六四事件法轮功

28

Secara default, Git hanya melihat tag beranotasi sebagai garis dasar untuk perintah seperti git describe. Pikirkan tag beranotasi sebagai rambu-rambu yang memiliki makna abadi untuk diri sendiri dan orang lain, sementara tag ringan lebih seperti penanda untuk nanti ditemukan sendiri. Oleh karena itu, tag beranotasi layak digunakan sebagai referensi, sedangkan tag ringan seharusnya tidak.

Menandatangani tag adalah jaminan identitas penandatangan. Ini memungkinkan pengguna memverifikasi, misalnya, bahwa kode kernel Linux yang mereka ambil adalah kode yang sama dengan yang dirilis Linus Torvalds. Tanda tangan juga dapat menjadi pernyataan bahwa penandatangan menjamin kualitas dan integritas perangkat lunak pada komitmen tersebut.


1
git push --follow-tagsadalah perintah lain yang memperlakukan kedua berbeda: stackoverflow.com/a/26438076/895245
Ciro Santilli郝海东冠状病六四事件法轮功

1
Terima kasih atas petunjuknya git describe. Saya menggunakannya dalam sistem integrasi berkesinambungan dan beberapa kali string versi bukan yang saya harapkan.
jjmontes

9

Menandatangani tag adalah cara mudah untuk menegaskan keaslian suatu rilis.

Ini sangat berguna dalam DVCS karena siapa pun dapat mengkloning repositori dan memodifikasi histori (mis. Via git-filter-branch). Jika sebuah tag ditandatangani, tanda tangan tidak akan bertahan dari operasi cabang git-filter-filter, jadi jika Anda memiliki kebijakan bahwa setiap rilis ditandai dan ditandatangani oleh pengangkut, mungkin untuk mendeteksi tag rilis palsu dalam repositori.

Jika bukan karena penandatanganan, saya juga tidak akan melihat gunanya tag beranotasi.


1
Sebenarnya, untuk ini bisa berguna untuk memiliki tanda tangan yang hanya menandatangani pohon yang berkomitmen, bukan seluruh sejarahnya (saya tidak peduli apakah ada orang yang mengubah sejarah, saya hanya ingin memastikan saya memiliki kode yang benar).
Paŭlo Ebermann

9

Dorong tag beranotasi, pertahankan lokal yang ringan

Perilaku Git tertentu memang membedakannya dengan cara-cara yang berguna untuk rekomendasi ini, misalnya:

  • tag beranotasi dapat berisi pesan, pembuat, dan tanggal yang berbeda dari komit yang mereka tuju. Jadi Anda bisa menggunakannya untuk menjelaskan rilis tanpa membuat komit rilis.

    Tag ringan tidak memiliki informasi tambahan itu, dan tidak memerlukannya, karena Anda hanya akan menggunakannya sendiri untuk dikembangkan.

  • git push --follow-tag hanya akan mendorong tag beranotasi
  • git describe tanpa opsi baris perintah hanya melihat tag beranotasi

man git-tag mengatakan:

Tag beranotasi dimaksudkan untuk rilis sementara tag ringan dimaksudkan untuk label objek pribadi atau sementara.

Perbedaan internal

  • kedua tag ringan dan beranotasi adalah file di bawahnya .git/refs/tagsyang berisi SHA-1

  • untuk tag ringan, SHA-1 menunjuk langsung ke komit:

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

    mencetak sama dengan HEA's SHA-1.

    Jadi tidak heran mereka tidak dapat mengandung metadata lainnya.

  • tag beranotasi mengarah ke objek tag dalam database objek.

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

    berisi SHA dari objek tag beranotasi:

    c1d7720e99f9dd1d1c8aee625fd6ce09b3a81fef
    

    dan kemudian kita bisa mendapatkan kontennya dengan:

    git cat-file -p c1d7720e99f9dd1d1c8aee625fd6ce09b3a81fef
    

    output sampel:

    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
    

    Dan ini caranya mengandung metadata tambahan. Seperti yang bisa kita lihat dari output, bidang metadata adalah:

    Analisis yang lebih terperinci dari format ini ada di: Apa format objek tag git dan bagaimana cara menghitung SHA-nya?

Bonus


6

Saya telah menemukan satu gunanya yang baik untuk tag ringan - membuat rilis di GitHub secara retrospektif.

Kami memang merilis perangkat lunak kami dan kami memiliki komitmen yang diperlukan, kami hanya tidak repot-repot mempertahankan bagian 'Rilis' di GitHub. Dan ketika kami memberikan sedikit perhatian, kami menyadari bahwa kami juga ingin menambahkan beberapa rilis sebelumnya, dengan tanggal rilis yang benar untuk mereka.

Jika kita hanya akan membuat tag beranotasi pada komit lama, GitHub akan mengambil tanggal untuk rilis dari objek tag. Sebaliknya, ketika kami telah membuat tag ringan untuk komit lama ini, rilis mulai menunjukkan tanggal (lama) yang benar. Sumber bantuan @ GitHub, 'Tentang rilis'

Tampaknya mungkin juga untuk menentukan tanggal yang Anda inginkan untuk komit beranotasi, tetapi tidak terlihat sesederhana itu bagi saya: https://www.kernel.org/pub/software/scm/git/docs/git-tag. html # _on_backdating_tags


Meskipun hari ini saya mengetahui bahwa GitHub berhenti menghormati tanggal tag untuk saya (untuk tag yang ringan dan beranotasi). Itu hanya mengabaikan tanggal ketika menerbitkan rilis dan bukannya mengingat tanggal dan waktu ketika saya menekan tombol "Terbitkan" untuk rilis.
evilkos

Ya, saya juga menemukan kekacauan ini tentang GitHub dan tag beranotasi. Saya tidak mengerti mengapa mereka menerapkannya dengan cara ini ..
YakovL

1

Di kantor saya, kami akan memasukkan alamat halaman web rilis di badan tag. Halaman web rilis merinci semua fitur dan perbaikan baru yang berbeda sejak rilis terakhir. Manajemen tidak akan mencari di git repo untuk mencari tahu perubahan apa yang terjadi, dan senang memiliki daftar ringkas tentang apa yang ada di rilis itu.


0

Tag beranotasi menyimpan metadata tambahan seperti nama penulis, catatan rilis, pesan tag, dan tanggal sebagai objek penuh dalam database Git. Semua data ini penting untuk rilis publik proyek Anda.

tag git -a v1.0.0

Tag ringan adalah cara paling sederhana untuk menambahkan tag ke repositori git Anda karena mereka hanya menyimpan hash dari commit yang mereka rujuk. Mereka dapat bertindak seperti "bookmark" ke sebuah komit, karena itu, mereka bagus untuk penggunaan pribadi.

tag git v1.0.0

Anda dapat mengurutkan, mendaftar, menghapus, menampilkan, dan mengedit tag lama. Semua fungsi ini akan membantu Anda mengidentifikasi versi rilis spesifik kode Anda. Saya menemukan artikel ini yang dapat membantu Anda mendapatkan ide yang lebih baik tentang tag apa yang dapat dilakukan.


0

Bagi saya perbedaan penting adalah tag ringan tidak memiliki timestamp. Katakanlah Anda menambahkan beberapa tag ringan:

git tag v1
git tag v2
git tag v3

dan kemudian, mungkin nanti, Anda ingin mendapatkan tag ringan terakhir yang ditambahkan. Tidak ada cara untuk melakukannya. Baik "git gambarkan" atau "git tag" tidak akan memberi Anda tag ringan terakhir secara kronologis. "git tag -l" dapat mengembalikan semuanya atau mengurutkannya dalam urutan lex, tetapi tidak berdasarkan tanggal / waktu. "git menggambarkan --tags" akan mengembalikan "v1" yang jelas bukan tag yang terakhir ditambahkan.

Dari sisi lain, jika Anda menambahkan tag beranotasi:

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

Anda selalu bisa mendapatkan timestamp dari setiap tag dan "git mendeskripsikan" pasti akan mengembalikan "v3" yang merupakan tag yang terakhir ditambahkan.


Anda harus menggunakan -a agar bisa dijelaskan.
Alex
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.