Edit, 24 Nov 2016: jawaban ini tampaknya populer, jadi saya menambahkan catatan di sini. Jika Anda mengganti tag di server pusat, siapa pun yang memiliki tag lama — klon mana pun dari repositori server pusat yang sudah memiliki tag — dapat mempertahankan tag yang lama . Jadi, sementara ini memberi tahu Anda cara melakukannya, pastikan Anda ingin melakukannya. Anda akan perlu untuk mendapatkan semua orang yang sudah memiliki "salah" tag untuk menghapus mereka "tag yang salah" dan menggantinya dengan yang baru "tag yang tepat".
Pengujian di Git 2.10 / 2.11 menunjukkan bahwa mempertahankan tag lama adalah perilaku default untuk klien yang berjalan git fetch
, dan memperbarui adalah perilaku default untuk klien yang menjalankan git fetch --tags
.
(Jawaban asli berikut.)
Ketika Anda meminta tag push, git push --tags
mengirim (bersama dengan komit dan objek lain yang diperlukan dan pembaruan ref lainnya dari pengaturan push) ke remote permintaan pembaruan formulir . (Ya, ia mengirimkan banyak: salah satunya untuk setiap tag.)new-sha1 refs/tags/name
Permintaan pembaruan dimodifikasi oleh remote untuk menambahkan old-sha1
(atau sekali lagi, satu untuk setiap tag), kemudian dikirim ke kait pra-terima dan / atau perbarui (mana pun kait yang ada pada remote). Kait itu dapat memutuskan apakah akan mengizinkan atau menolak tag buat / hapus / perbarui.
The old-sha1
nilai adalah semua-nol "null" SHA-1 jika tag sedang dibuat. Ini new-sha1
adalah null SHA-1 jika tag sedang dihapus. Jika tidak, kedua nilai SHA-1 adalah nilai nyata dan valid.
Bahkan tanpa kait, ada semacam "kait bawaan" yang juga dijalankan: remote akan menolak untuk memindahkan tanda kecuali Anda menggunakan bendera "force" (meskipun "kait bawaan" selalu baik-baik saja dengan keduanya "tambah" dan "hapus"). Pesan penolakan yang Anda lihat berasal dari pengait bawaan ini. (Kebetulan, pengait bawaan yang sama ini juga menolak pembaruan cabang yang tidak maju cepat.) 1
Tapi — inilah salah satu kunci untuk memahami apa yang terjadi — git push
langkah tersebut tidak tahu apakah remote memiliki tag itu sekarang, dan jika demikian, apa nilai SHA-1 yang dimilikinya. Itu hanya mengatakan "inilah daftar lengkap tag saya, bersama dengan nilai SHA-1 mereka". Remote membandingkan nilainya dan jika ada tambahan dan / atau perubahan, jalankan hooks pada itu. (Untuk tag yang sama, tidak melakukan apa-apa. Untuk tag yang tidak Anda miliki, tag juga tidak berfungsi!)
Jika Anda menghapus tag secara lokal, maka push
, dorongan Anda tidak akan mentransfer tag. Remote menganggap tidak ada perubahan yang harus dilakukan.
Jika Anda menghapus tag secara lokal, kemudian membuatnya menunjuk ke tempat baru, lalu push
, push Anda mentransfer tag, dan remote melihat ini sebagai tag-perubahan dan menolak perubahan, kecuali itu push-paksa.
Dengan demikian, Anda memiliki dua opsi:
- lakukan push-paksa, atau
- hapus tag pada remote.
Yang terakhir adalah mungkin melalui git push
2 meskipun menghapus tag secara lokal dan push
ing tidak berpengaruh. Dengan asumsi nama remote adalah origin
, dan tag yang ingin Anda hapus adalah dev
:
git push origin :refs/tags/dev
Ini meminta remote untuk menghapus tag. Ada atau tidaknya tag dev
di repositori lokal Anda tidak relevan; jenis ini push
, dengan sebagai refspec, adalah dorongan penghapusan murni.:remoteref
Remote mungkin atau mungkin tidak mengizinkan penghapusan tag (tergantung pada kait tambahan yang ditambahkan). Jika memungkinkan penghapusan, maka tag akan hilang, dan yang kedua git push --tags
, ketika Anda memiliki dev
tag lokal yang menunjuk ke beberapa objek repo tag berkomitmen atau beranotasi, kirim dev
tag baru Anda . Pada remote, dev
sekarang akan menjadi tag yang baru dibuat, jadi remote mungkin akan memungkinkan push (sekali lagi ini tergantung pada kait tambahan yang ditambahkan).
Push-force lebih sederhana. Jika Anda ingin memastikan untuk tidak memperbarui apa-apa lain selain tag, hanya memberitahu git push
untuk mendorong hanya itu satu refspec:
git push --force origin refs/tags/dev:refs/tags/dev
(catatan: Anda tidak perlu --tags
jika Anda secara eksplisit mendorong hanya satu ref-spec tag).
1 Tentu saja, alasan kait bawaan ini adalah untuk membantu menegakkan perilaku yang diharapkan oleh pengguna lain dari repo jarak jauh yang sama: bahwa cabang tidak diputar ulang, dan tag tidak bergerak. Jika Anda mendorong-paksa, Anda harus memberi tahu pengguna lain bahwa Anda melakukan ini, sehingga mereka dapat memperbaikinya. Perhatikan bahwa "tag tidak bergerak sama sekali" baru diberlakukan oleh Git 1.8.2; versi sebelumnya akan memungkinkan tag untuk "bergerak maju" dalam grafik komit, seperti nama cabang. Lihat catatan rilis git 1.8.2 .
2 Ini sepele jika Anda bisa masuk di kendali jarak jauh. Buka saja repositori Git di sana dan jalankan git tag -d dev
. Perhatikan bahwa bagaimanapun juga — menghapus tag pada remote, atau menggunakan git push
untuk menghapusnya — ada periode waktu ketika siapa pun yang mengakses remote akan menemukan bahwa dev
tag tersebut hilang. (Mereka akan terus memiliki tag lama mereka sendiri , jika mereka sudah memilikinya, dan mereka bahkan mungkin mendorong kembali tag lama mereka sebelum Anda dapat mendorong yang baru.)