Bagaimana cara mengedit pesan tag yang ada di git?

225

Kami memiliki beberapa tag beranotasi di repositori git kami. Tag yang lebih lama memiliki pesan palsu yang ingin kami perbarui dengan gaya baru kami.

% git tag -n1
v1.0 message
v1.1 message
v1.2 message
v2.0 Version 2.0 built on 15 October 2011.

Dalam contoh ini, kami ingin membuat pesan v1.x terlihat seperti pesan v2.0. Adakah yang tahu bagaimana kita akan melakukan ini?

Jared
sumber
2
Catatan: dengan Git 2.17 (Q2 2018), sederhana git tag -m "A message" --edit v1.0akan cukup. Lihat jawaban saya di bawah ini
VonC
@VonC Sudah mencobanya dan diterima fatal: tag 'v6.6.2' already existsmenggunakan 2.17.0.
Josh Habdas
1
Anda selalu dapat menghapus tag sebelumnya dan melakukannya lagi.
RoadRunner

Jawaban:

264

git tag <tag name> <tag name>^{} -f -m "<new message>"

Ini akan membuat tag baru dengan nama yang sama (dengan menimpa aslinya).

Andy
sumber
7
Apakah ini mempertahankan tanggal tag asli?
James M. Greene
16
Jawaban untuk pertanyaan komentar saya sendiri: Ya, itu memang mengubah tanggal. :(
James M. Greene
10
Lihat bagian "Pada Tag Backdating" di git tag --help.
dahlbyk
6
Perlu juga dicatat bahwa Anda juga dapat menambahkan beberapa pesan (mereka dipisahkan oleh baris baru - di GitHub)git tag <tag name> <tag name> -f -m "<new message>" -m "<new message>" -m "<new message>"
Blair McMillan
5
@ChrisMorley melihat jawaban saya di bawah ini stackoverflow.com/a/23532519/603949 - singkatnya, gunakan <tag name>^{}ketika Anda ingin menggantiold tag
Sungam
87

Untuk memperbarui pesan yang kompleks, cukup tentukan opsi tag beranotasi dengan -aatau opsi tag yang ditandatangani dengan -s:

git tag <tag name> <tag name>^{} -f -a

Ini akan membuka editor dengan isi pesan tag lama Anda .

Eric Hu
sumber
39

git tag <tag name> <tag name>^{} -f -a

Ini merupakan peningkatan: tanpa ^{}itu akan membuat objek tag baru yang mereferensikan objek tag lama, di mana keduanya akan memiliki nama tag yang sama.

<tag name>^{} akan menyelesaikan tag / referensi hingga menemukan hash komit pertama.

Sungam
sumber
4
@BrentFoust, yang hanya berfungsi saat kepala Anda berada di komit yang ditandai usage: git tag [-a|-s|-u <key-id>] [-f] [-m <msg>|-F <file>] <tagname> [<head>]
Sungam
33

TL; DR

Anda dapat melakukan ini dengan menghapus tag dan membuatnya kembali sambil mem-spoof tanggal dan pembuat:

> git tag -d <tag-name>
> [GIT_COMMITTER_DATE=<original-commit-date>] \
> [GIT_AUTHOR_NAME=<original-author-name>] \
> git tag <tag-name> [commit]

Seluruh cerita:

Membangun jawaban Sungram (awalnya diusulkan sebagai suntingan):

1. Jawaban yang diterima

Ini merupakan peningkatan dari jawaban Andy dan Eric Hu . Jawaban mereka akan membuat objek tag baru yang mereferensikan objek tag lama dan keduanya akan memiliki nama yang sama.

Untuk menggambarkan hal ini, pertimbangkan hal berikut:

> git tag tag1 tag1 -f -a  # accepted answer
> git rev-list --objects -g --no-walk --all
[ example output: ]
6bdcc347fca041a5138f89fdf5276b3ebf9095d5
260ab7928d986472895b8c55e54569b3f3cb9517 tag1
a5797673f610914a45ef7ac051e3ee831a6e7c25 tag1
f22d6308c3cd330a3b0d86b9bf05562faf6b6f17

> git show tag1
tag tag1
Tagger: [tagger]
Date:   [date of updated tag]
[Updated description]

tag tag1
Tagger: [tagger]
Date:   [date of original tag]
[Original description]

[tagged commit details]

2. Peningkatan Sungram

Menggunakan <tag name>^{}argumen kedua git tagsebagai gantinya akan menghapus semua tag sebelumnya dengan nama yang sama.

Pertimbangkan kelanjutan sesi terminal sebelumnya:

> git tag tag1 tag1^{} -f -a  # suggested improvement
> git rev-list --objects -g --no-walk --all
[ example output: ]
6bdcc347fca041a5138f89fdf5276b3ebf9095d5
75f02acacfd7d91d55b5bcfdfb1f00aebeed15e3 tag1
f22d6308c3cd330a3b0d86b9bf05562faf6b6f17 

> git show tag1
tag tag1
Tagger: [tagger]
Date:   [date of updated tag]
[Updated description]

[tagged commit details]

3. Simpan tanggal

Terakhir, jika Anda ingin menyimpan tanggal dari tag asli sebagai tanggal dari tag yang diperbarui, gunakan beberapa sihir awk (atau sejenisnya) atau cukup tempel tanggal yang Anda inginkan. Berikut ini adalah pengganti untuk contoh kedua (jika tidak, tanggal asli akan hilang karena ditimpa):

> GIT_COMMITTER_DATE="$(git show tag1 |                              # get info about the tag cascade including the date original of the original tag
> awk '{
>     if ($1 == "Date:") {
>         print substr($0, index($0,$3))
>     }
> }' |                                                               # extract all the dates from the info
> tail -2 | head -1)"                                               `# get the second to last date, as the last one is the commit date` \
> git tag tag1 tag1^{} -a -f                                         # finally, update the tag message, but save the date of the old one
>
> git rev-list --objects -g --no-walk --all
6bdcc347fca041a5138f89fdf5276b3ebf9095d5
e18c178f2a548b37799b100ab90ca785af1fede0 tag1
f22d6308c3cd330a3b0d86b9bf05562faf6b6f17
> git show tag1
tag tag1
Tagger: [tagger]
Date:   [date of original tag]
[Updated description]

[tagged commit details]

Referensi:

4. DIY

Atau untuk memperbarui tag, Anda bisa menghapusnya dan membuatnya lagi. Ternyata memperbarui hanya menambahkan tag baru dan membuatnya menunjuk ke yang lama, atau secara alternatif, hanya menghapus yang lama dan membuat yang baru untuk menunjuk ke komit yang sama pula.

Anda dapat mencapai ini dengan menerbitkan:

> git tag -d <tag-name>
> [GIT_COMMITTER_DATE=<original-commit-date>] \
> [GIT_AUTHOR_NAME=<original-author-name>] \
> git tag <tag-name> [commit]

Ini [optional]adalah bidang opsional; <required>adalah bidang wajib diisi. Tentu saja, Anda dapat menambahkan bendera apa pun setelah git tagperintah yang biasanya Anda lakukan.

stanm
sumber
3
Terima kasih telah menunjukkan bahwa "Jawaban mereka akan membuat objek tag baru"!
cwhsu
Mengutip Andreas Schwab : The tagger is controlled by the committer info. (...) GIT_COMMITTER_{NAME,EMAIL}. A tagger isn't really an author.
Ivan Vučica
11

Solusi @Andy

git tag <tag-name> <tag-name> -f -a

adalah salah . Setelah itu, dengan

git show

perintah, kita akan melihat tumpukan tag dengan nama yang sama.

Itu menambahkan tag baru dengan nama tag yang sama dan pesan baru di komit <tag-name>. Tapi itu tidak menghapus tag lama. Ini adalah kasus khusus dari perintah ini:

git tag [<commit> | <old-tag>] <tag-name>

Tapi <old-tag>sama saja dengan <tag-name>.


Solusi yang benar sederhana, hanya perbarui tag yang OK.

git tag <tag-name> -f -a

Ingat, hanya SATU di sini.

Jika kita ingin mengganti tag, yang bukan HEAD, kita perlu <commit>argumen tambahan .

git tag <commit> <tag-name> -f -a
liuyang1
sumber
IYA! Kamu benar. Terima kasih telah menunjukkan itu. Setelah menulis ulang tag yang dianotasi beberapa kali, saya memeriksa tag saya git show <tag>dan melihat semua edisi sebelumnya.
Manoel Vilela
Masalahnya adalah: jika saya perlu memperbarui beberapa tag yang tidak HEAD, melewati ekstra <commit>, tag yang dibuka kosong. Saya berharap tag lama hanya diedit. Apakah ada jalannya?
Manoel Vilela
Harap dicatat bahwa solusi Andy telah diperbarui sejak Anda menjawab. Mungkin akan menyenangkan untuk memulai jawaban Anda dengan pesan yang mengatakan bahwa itu sudah diperbaiki? Juga mungkinkah bahwa perintah Anda git tag <commit> <tag-name> -f -atelah <commit> dan <tag-name> terbalik? Ini terlihat seperti ini ketika membandingkan dengan jawaban dan dokumen lain, tapi saya bukan ahli.
Jacob Akkerboom
7

kami ingin membuat pesan v1.x terlihat seperti pesan v2.0

Dengan Git 2.17 (Q2 2018), akan ada alternatif untuk membuat tag baru dengan git tag <tag name> <tag name> -f -m "<new message>", " git tag" mempelajari opsi eksplisit " --edit" yang memungkinkan pesan yang diberikan melalui " -m" dan " -F" diedit lebih lanjut.

Lihat komit 9eed6e4 (06 Feb 2018) oleh Nicolas Morey-Chaisemartin ( nmorey) .
(Digabung oleh Junio ​​C Hamano - gitster- di commit 05d290e , 06 Mar 2018)

tag: tambahkan --editopsi

Tambahkan --editopsi yang memungkinkan Anda memodifikasi pesan yang disediakan oleh -matau -F, dengan cara yang sama git commit --edit.

VONC
sumber
4
Bisakah Anda memberikan contoh yang koheren dengan menggunakan --editalamat OP?
Josh Habdas
@JoshHabdas sebenarnya, Anda perlu menambahkan opsi -f: --edit hanya memungkinkan pesan untuk diedit lebih lanjut.
VonC
Terima kasih. Jadi jika -fbendera ditambahkan juga maka --editakan mengedit pesan dan memodifikasi stempel waktu, kan?
Josh Habdas
@ JoshHabdas Itulah idenya, ya.
VonC
4

Anda harus menandai lagi, menggunakan -fbendera gaya.

git tag v1.0 -f -m "actual message"
manojlds
sumber
3
Solusi ini mengandaikan bahwa git head saat ini ada di versi 1.0. Ini dapat mengacaukan segalanya jika tidak, karena mengubah revisi yang terkait dengan versi 1.0. Solusi Andy menghindari jebakan ini.
Eric O Lebigot
4

Menggunakan jawaban di atas, ini adalah alias untuk saya satu-liner .gitconfig. Mengganti tag yang ada dan mempertahankan tanggal komit.

[alias]
    tm = "!sh -c 'f() { export GIT_COMMITTER_DATE=$(git log -1 --format=%ci $0); git tag -f -a $0 $0^{}; }; f '"

Perbaikan?

h0tw1r3
sumber
1
Juga membuat penulis: tag-amend = "!sh -c 'f() { name=$(git log -1 --format=%an $0); email=$(git log -1 --format=%ae $0); date=$(git log -1 --format=%ci $0); GIT_AUTHOR_NAME=\"${name}\" GIT_COMMITTER _NAME=\"${name}\" GIT_AUTHOR_EMAIL=\"${email}\" GIT_COMMITTER_EMAIL=\"${email}\" GIT_AUTHOR_DATE=\"${date}\" GIT_COMMITTER_DATE=\"${date}\" git tag -f -a $0 $0^{}; }; f '"
minterior
1
Baru saja mencoba ini. Alih-alih memberikan tag pengganti informasi penulis dan tanggal dari tag itu sendiri, tag ini menggunakan info dari komit yang ditunjuk tag. Ini tidak selalu sama dan, pada kenyataannya, tidak sama untuk kasus kami sebagian besar waktu. Kami memiliki infrastruktur multi-repo dan menggunakan tag beranotasi dalam repo 'inti' untuk merekam info tentang push yang menjangkau beberapa repo. Jadi, pada intinya, komit yang diarahkan mungkin bahkan bukan bagian dari dorongan nyata. Info dalam tag beranotasi harus mencerminkan dorongan nyata dalam repo lain.
Penyamak
0

Jika Anda menggunakan GUI seperti smartgit saja

  1. buat tag yang sama lagi di posisi yang sama dengan pesan baru
  2. pilih "timpa tag yang ada"
  3. dorong paksa tag ke repositori hulu
rubo77
sumber