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.0
dan mencoba meringkas log komit karena tag sebelumnya terasa seperti kehilangan strategi.
git log --pretty=oneline master..HEAD | git tag -a -F - $BRANCH.$BUILD_NUMBER
Jawaban:
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.
sumber
git help log
sekarang meringkas ini sebagai: "Tag beranotasi dimaksudkan untuk rilis sementara tag ringan dimaksudkan untuk label objek pribadi atau sementara."git tag -a -m 'my message' my-tag; git show my-tag
Pandangan pribadi saya, yang sedikit berbeda tentang topik itu:
sumber
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.
sumber
git push --follow-tags
adalah perintah lain yang memperlakukan kedua berbeda: stackoverflow.com/a/26438076/895245git describe
. Saya menggunakannya dalam sistem integrasi berkesinambungan dan beberapa kali string versi bukan yang saya harapkan.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.
sumber
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 describe
tanpa opsi baris perintah hanya melihat tag beranotasiman git-tag
mengatakan:Perbedaan internal
kedua tag ringan dan beranotasi adalah file di bawahnya
.git/refs/tags
yang berisi SHA-1untuk tag ringan, SHA-1 menunjuk langsung ke komit:
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.
berisi SHA dari objek tag beranotasi:
dan kemudian kita bisa mendapatkan kontennya dengan:
output sampel:
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
Tentukan apakah tag dianotasi:
Output
commit
untuk yang ringan,tag
untuk yang beranotasi.Daftar hanya tag ringan: Bagaimana saya bisa mendaftar semua tag ringan?
sumber
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
sumber
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.
sumber
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.
sumber
Bagi saya perbedaan penting adalah tag ringan tidak memiliki timestamp. Katakanlah Anda menambahkan beberapa tag ringan:
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:
Anda selalu bisa mendapatkan timestamp dari setiap tag dan "git mendeskripsikan" pasti akan mengembalikan "v3" yang merupakan tag yang terakhir ditambahkan.
sumber