Tag di Git: cara memakai git tag dan memberi versi pada rilis
git tag menempelkan label tetap pada commit tertentu, biasanya untuk menandai rilis, misalnya v1.2.0. Tag beranotasi dibuat dengan git tag -a v1.2.0 -m "pesan", dan dikirim ke server secara terpisah dengan git push origin v1.2.0 atau git push --tags.
git tag adalah label bernama yang menempel pada commit tertentu. Berbeda dengan branch, tag tidak bergerak ketika ada commit baru: v1.2.0 akan tetap menunjuk ke snapshot kode yang sama setahun kemudian. Karena itu tag dipakai untuk rilis, dan sistem CI/CD sering memicu build dan publikasi tepat saat tag muncul.
Tag ringan dan tag beranotasi
Ada dua jenis tag di Git, dan perbedaannya penting.
| Ringan (lightweight) | Beranotasi (annotated) | |
|---|---|---|
| Pembuatan | git tag v1.0.0 | git tag -a v1.0.0 -m "..." |
| Apa itu | hanya penunjuk ke commit | objek tersendiri di basis data Git |
| Penulis, tanggal, pesan | tidak ada | ada |
| Tanda tangan GPG/SSH | tidak ada | bisa (-s) |
Dikenali git describe secara default | tidak | ya |
| Kapan dipakai | penanda pribadi yang sementara | rilis dan semua yang dipublikasikan |
Untuk rilis, gunakan tag beranotasi: di dalamnya tercatat siapa dan kapan versi itu dirilis, serta tag itu bisa ditandatangani.
Cara membuat tag
Pada commit saat ini
git tag -a v1.2.0 -m "Rilis 1.2.0: ekspor laporan, perbaikan timeout API"
Tanpa -m, Git akan membuka editor untuk pesan, cocok jika Anda ingin menulis daftar perubahan.
Pada commit lama
Lupa memberi tag saat rilis? Tidak masalah, tag bisa dipasang pada commit mana pun:
git log --oneline -5
# 7be41d0 feat: ekspor laporan
# 1c02e8f fix: timeout permintaan
git tag -a v1.1.0 1c02e8f -m "Rilis 1.1.0"
Tag yang ditandatangani
git tag -s v1.2.0 -m "Rilis 1.2.0"
git tag -v v1.2.0 # periksa tanda tangannya
Diperlukan kunci GPG yang sudah diatur (atau SSH jika gpg.format=ssh). GitHub dan GitLab menampilkan tag seperti ini dengan tanda terverifikasi.
Cara melihat tag
git tag # semua tag, urut abjad
git tag -l "v1.*" # dengan pola
git tag -n # beserta baris pertama pesannya
git tag --sort=-v:refname # diurutkan menurut versi, yang terbaru di atas
git show v1.2.0 # data tag dan commit-nya
git describe --tags # tag terdekat: v1.2.0-3-g7be41d0
Perhatikan pengurutan: secara default v1.10.0 akan muncul sebelum v1.9.0, karena string dibandingkan karakter demi karakter. Kunci --sort=v:refname mengurutkan sebagai versi.
Keluaran git describe dibaca begini: tiga commit setelah tag v1.2.0, dan commit saat ini adalah 7be41d0 (huruf g berarti git). Ini sumber nomor versi yang praktis untuk build di antara rilis.
Cara mengirim tag ke server
git push biasa tidak mengirim tag. Inilah penyebab umum pertanyaan «kenapa tag saya tidak ada di GitHub».
git push origin v1.2.0 # satu tag
git push --tags # semua tag lokal
git push --follow-tags # commit + tag beranotasi yang menunjuk ke commit tersebut
--follow-tags lebih aman daripada --tags: ia tidak mengirim tag ringan yang Anda buat untuk diri sendiri. Agar selalu aktif secara default: git config --global push.followTags true.
Untuk mengambil tag dari server: git fetch --tags. git fetch biasa juga membawa tag yang menunjuk ke commit yang diunduh.
Cara menghapus atau memindahkan tag
Menghapus
git tag -d v1.2.0 # secara lokal
git push origin --delete v1.2.0 # di server
# sintaks lama: git push origin :refs/tags/v1.2.0
Memindahkan tag ke commit lain
git tag -a -f v1.2.0 <hash-baru> -m "Rilis 1.2.0"
git push origin -f v1.2.0
Secara teknis ini mungkin, tetapi pada proyek publik tag yang sudah dipublikasikan sebaiknya tidak dipindahkan. Orang yang sudah mengunduh tag itu tidak akan otomatis mendapatkan versi barunya: Git tidak menimpa tag lokal yang sudah ada saat fetch tanpa --force. Hasilnya, «v1.2.0» berisi kode yang berbeda untuk orang yang berbeda. Lebih baik rilis v1.2.1.
Cara mengetahui commit apa saja yang masuk rilis
Tag sangat berguna sebagai batas rentang untuk semua perintah pembacaan riwayat:
git log v1.1.0..v1.2.0 --oneline # commit di antara dua rilis
git diff v1.1.0 v1.2.0 --stat # berkas apa saja yang berubah
git tag --contains 1c02e8f # tag mana saja yang memuat commit ini
git merge-base --is-ancestor 1c02e8f v1.2.0 && echo "ada di rilis"
Dua perintah terakhir menjawab pertanyaan yang sering muncul di tim pemeliharaan: «apakah perbaikan ini sudah sampai ke pengguna?» Jika perbaikan hanya ada di main dan rilis sudah dibuat sebelumnya, git tag --contains akan menampilkan daftar kosong, dan jelas bahwa tag baru diperlukan.
Trik lain: mengunduh kode dari versi tertentu tanpa riwayat dengan git archive --format=zip -o app-1.2.0.zip v1.2.0. Cara ini dipakai untuk membuat arsip yang diserahkan kepada klien atau untuk build di lingkungan terisolasi.
Cara berpindah ke versi berdasarkan tag
git switch --detach v1.1.0
# HEAD is now at 1c02e8f fix: timeout permintaan
Anda akan berada dalam keadaan detached HEAD: boleh melihat dan membangun kode, tetapi commit baru tidak menjadi milik branch mana pun. Jika ingin memperbaiki versi lama, buat branch dari tag:
git switch -c hotfix/1.1.x v1.1.0
# perbaikan, commit
git tag -a v1.1.1 -m "Perbaikan keamanan"
git push origin hotfix/1.1.x --follow-tags
Penomoran rilis: SemVer
Skema nama tag yang paling umum adalah Semantic Versioning: MAJOR.MINOR.PATCH.
- MAJOR naik untuk perubahan API yang tidak kompatibel:
1.4.2 → 2.0.0. - MINOR untuk fitur baru yang tetap kompatibel:
1.4.2 → 1.5.0. - PATCH untuk perbaikan bug:
1.4.2 → 1.4.3. - Pra-rilis diberi akhiran:
2.0.0-beta.1,2.0.0-rc.1.
Awalan v (v1.4.2) adalah konvensi umum untuk nama tag; SemVer sendiri tidak mewajibkannya. Yang penting, pilih satu format dan konsisten, karena skrip yang mencari rilis terakhir akan rusak jika formatnya tercampur.
Tag dalam proses rilis
Proses tipikal dalam tim:
- Perubahan digabung ke main, tes hijau.
- CHANGELOG dan nomor versi di berkas proyek diperbarui, jika disimpan di sana.
- Pasang tag beranotasi:
git tag -a v1.5.0 -m "Rilis 1.5.0". git push origin main --follow-tags.- CI melihat tag baru, membangun artefak, dan mempublikasikan rilis; di GitHub dan GitLab, dari tag dibuat halaman Release dengan deskripsi dan berkas.
Dengan cara ini, setiap versi di produksi bisa dihubungkan secara tepat dengan kodenya: tag di nama build, lalu git show untuk melihat apa yang masuk. Dan git log v1.4.0..v1.5.0 --oneline memberikan daftar perubahan antara dua rilis untuk catatan rilis.
Catatan rilis dari tag
Jika pesan commit jelas, tag mengubah riwayat menjadi daftar perubahan yang siap pakai. Rilis terakhir dan sebelumnya bisa ditemukan tanpa mencari manual:
LAST=$(git describe --tags --abbrev=0)
PREV=$(git describe --tags --abbrev=0 "$LAST^")
git log "$PREV..$LAST" --no-merges --pretty=format:"- %s (%h)"
# - feat: ekspor laporan (7be41d0)
# - fix: timeout permintaan (1c02e8f)
Jika tim menulis commit sesuai Conventional Commits (feat:, fix:, feat!:), nomor versi berikutnya bisa dihitung otomatis: fix menaikkan PATCH, feat menaikkan MINOR, dan tanda seru atau BREAKING CHANGE menaikkan MAJOR. Alat rilis otomatis yang populer bekerja dengan prinsip ini: mereka sendiri membuat tag dan menulis CHANGELOG.
Tag dan CI/CD
Pipeline biasanya membedakan dua peristiwa: push ke branch dan kemunculan tag. Pada branch dijalankan tes dan build lingkungan uji, sedangkan pada tag dilakukan publikasi. Di GitHub Actions, konfigurasinya seperti ini:
on:
push:
tags:
- "v*.*.*"
Di GitLab CI, peran serupa dimainkan oleh variabel CI_COMMIT_TAG dan aturan rules: - if: $CI_COMMIT_TAG. Nama tag di dalam pipeline menjadi nomor versi image Docker atau paket, jadi formatnya harus ketat dan dapat diprediksi.
Ini juga alasan lain untuk tidak memindahkan tag: jika pipeline sudah mempublikasikan paket 1.2.0 ke registry, publikasi ulang dengan nomor yang sama biasanya dilarang, dan pengguna yang sudah memakai image bertag 1.2.0 akan tetap memakai versi lama.
Aturan penamaan tag
Nama tag mengikuti aturan yang sama dengan nama branch: tanpa spasi, tanpa karakter ~ ^ : ? * [, dan tanpa dua titik berurutan. Garis miring diperbolehkan, sehingga di monorepo muncul tag seperti api/v1.2.0 dan web/v3.0.1, satu rangkaian versi untuk setiap paket. Untuk memeriksa nama sebelumnya, gunakan git check-ref-format "refs/tags/v1.2.0": jika ada kesalahan, perintah ini mengembalikan kode non-nol.
Melindungi tag
Di repositori tim, tag rilis sebaiknya dilindungi. GitHub dan GitLab memungkinkan pelarangan pembuatan, penulisan ulang, dan penghapusan tag berdasarkan pola (misalnya v*) bagi semua orang kecuali pemelihara. Dengan begitu, git push --tags yang keliru dari komputer orang lain tidak akan merilis versi yang tidak direncanakan, dan git push origin --delete yang salah tidak menghapus riwayat versi.
Kesalahan yang sering terjadi
- Tag tidak ada di server. Lupa menjalankan
git push origin <tag>atau--follow-tags. - Tag dengan nama yang sama dengan branch. Git memberi peringatan
refname is ambiguous; gunakan awalanvuntuk tag dan nama yang berbeda. - Tag pada keadaan yang belum di-commit. Tag menempel pada commit, bukan pada berkas; perubahan yang belum di-commit tidak akan masuk rilis.
- Tag ringan untuk rilis. Tidak ada penulis, tanggal, maupun pesan, dan
git describetidak melihatnya secara default.
Ringkasan
git tag menetapkan titik tetap dalam riwayat. Untuk rilis, buat tag beranotasi dengan git tag -a, beri nama menurut SemVer, dan kirim ke server secara eksplisit dengan git push origin <tag> atau --follow-tags. Tag yang sudah dipublikasikan sebaiknya tidak dipindahkan; terbitkan versi baru. Tag bersama rebase, stash, dan cherry-pick dibahas dengan praktik dalam kursus Git.
Pertanyaan umum
Apa bedanya tag dengan branch?
Branch bergeser otomatis pada setiap commit baru, sedangkan tag selamanya menunjuk ke commit yang sama.
Bisakah dua tag diberikan pada satu commit?
Bisa, jumlah tag pada satu commit tidak dibatasi, misalnya v2.0.0 dan latest-stable.
Apakah tag ikut terhapus ketika branch dihapus?
Tidak. Tag tidak terikat pada branch, dan commit yang diberi tag tetap bisa diakses meskipun branch-nya sudah dihapus.
Bagaimana cara mengetahui commit ini masuk ke rilis yang mana?
Jalankan git tag --contains <hash>. Perintah ini menampilkan semua tag yang riwayatnya memuat commit tersebut.
Bagaimana cara mendapatkan tag terakhir di dalam skrip?
Gunakan git describe --tags --abbrev=0. Perintah ini menampilkan nama tag terdekat tanpa akhiran hash.
Topik ini dibahas mendalam dengan praktik di kursus “Git dari Nol hingga Pengembang Percaya Diri”.
Ke kursus