Ubah tanggal git tag (atau GitHub Rilis berdasarkan itu)

96

Saya menambahkan Rilis ke proyek saya di GitHub dengan menambahkan tag ke berbagai komit di cabang Utama.

Dalam salah satu proyek saya, saya tidak menambahkan tag ke komit dalam urutan kronologis. (Saya menemukan komitmen yang jelas dan menandainya, lalu saya menemukan komitmen yang kurang jelas, yang lebih lama , dan menandainya.)

Sekarang GitHub menunjukkan v1.0.1 lancar, dengan v0.7.0 mendahuluinya, dan v1.1.2 sebelumnya yang .

Tampaknya menggunakan tanggal pada pembuatan tag sebagai tanggal Rilis alih-alih komit yang sedang diberi tag. Bagaimana saya bisa mengedit tag saya sehingga tanggalnya sama dengan komit yang mereka tandai?

pemetaan rilis dan tanggal antara gitk dan GitHub

Phrogz
sumber

Jawaban:

119

PERINGATAN: Ini tidak akan menyimpan pesan tag untuk tag beranotasi.

Ringkasan

Untuk setiap tag yang perlu diubah:

  1. Kembali ke masa lalu untuk komit yang mewakili tag
  2. Hapus tag (secara lokal dan jarak jauh)
    • Ini akan mengubah "Rilis" Anda di GitHub menjadi Draf yang nantinya dapat Anda hapus.
  3. Tambahkan kembali tag dengan nama yang sama menggunakan doa ajaib yang menyetel tanggalnya ke tanggal komit.
  4. Dorong tag baru dengan tanggal tetap kembali ke GitHub.
  5. Buka GitHub, hapus rilis draf sekarang, dan buat ulang rilis baru dari tag baru

Dalam kode:

# Fixing tag named '1.0.1'
git checkout 1.0.1               # Go to the associated commit
git tag -d 1.0.1                 # Locally delete the tag
git push origin :refs/tags/1.0.1 # Push this deletion up to GitHub

# Create the tag, with a date derived from the current head
GIT_COMMITTER_DATE="$(git show --format=%aD | head -1)" git tag -a 1.0.1 -m"v1.0.1"

git push --tags                  # Send the fixed tags to GitHub

Detail

Menurut Cara Menandai di Git :

Jika Anda lupa memberi tag pada rilis atau versi benjolan, Anda selalu dapat menandainya secara retroaktif seperti ini:

git checkout SHA1_OF_PAST_COMMIT
git tag -m"Retroactively tagging version 1.5" v1.5

Dan sementara itu sangat berguna, itu memiliki efek menempatkan tag Anda keluar dari urutan kronologis yang dapat mengacaukan sistem build yang mencari tag "terbaru". Tapi jangan takut. Linus memikirkan segalanya:

# This moves you to the point in history where the commit exists
git checkout SHA1_OF_PAST_COMMIT

# This command gives you the datetime of the commit you're standing on
git show --format=%aD  | head -1

# And this temporarily sets git tag's clock back to the date you copy/pasted in from above
GIT_COMMITTER_DATE="Thu Nov 11 12:21:57 2010 -0800" git tag -a 0.9.33 -m"Retroactively tagging version 0.9.33"

# Combining the two...
GIT_COMMITTER_DATE="$(git show --format=%aD  | head -1)" git tag -a 0.9.33 -m"Retroactively tagging version 0.9.33"

Namun, jika Anda telah menambahkan tag, Anda tidak dapat menggunakan yang di atas dengan git tag -f existingtagatau git akan mengeluh ketika Anda mencoba untuk menggabungkan:

Rammy:docubot phrogz$ git push --tags
To [email protected]:Phrogz/docubot.git
 ! [rejected]        1.0.1 -> 1.0.1 (already exists)
error: failed to push some refs to '[email protected]:Phrogz/docubot.git'
hint: Updates were rejected because the tag already exists in the remote.

Sebaliknya, Anda harus menghapus tag secara lokal:

git tag -d 1.0.1

Dorong penghapusan itu dari jarak jauh:

git push origin :refs/tags/1.0.1

Di GitHub, muat ulang Rilis — rilis tersebut sekarang telah ditandai sebagai "Draf" —dan hapus draf tersebut.

Sekarang, tambahkan tag mundur berdasarkan petunjuk di atas, dan terakhir dorong tag yang dihasilkan ke GitHub:

git push --tags

lalu buka dan tambahkan kembali informasi Rilis GitHub.

Phrogz
sumber
2
Berikut skrip bash yang menghapus dan menambahkan kembali setiap tag di git repo:git tag -l | while read -r tag; do `git checkout $tag && git tag -d $tag && git push origin :refs/tags/$tag && GIT_COMMITTER_DATE="$(git show --format=%aD | head -1)" git tag -a $tag -m"$tag"`; done; git push --tags
Phrogz
11
Anda harus dapat melakukan semua hal itu tanpa memeriksa tag. Berikut modifikasi satu baris Anda yang jauh lebih cepat bagi saya:git tag -l | while read -r tag ; do COMMIT_HASH=$(git rev-list -1 $tag) && git tag -d $tag && git push origin :refs/tags/$tag && GIT_COMMITTER_DATE="$(git show $COMMIT_HASH --format=%aD | head -1)" git tag -a $tag -m"$tag" $COMMIT_HASH ; done && git push --tags
vmrob
2
menggunakan git tag -afmembuat yang -dtidak diperlukan dan Anda tetap lokal sehingga Anda dapat memeriksa bahwa semuanya baik-baik saja - maka Anda bisagit push --tags -f
Mr_and_Mrs_D
3
@Mr_and_Mrs_D Saran bagus dan cara yang baik untuk membatasi operasi ini ke satu dorongan. Dengan pemikiran itu, saya pikir satu-liner yang dihasilkan (belum teruji) adalahgit tag -l | while read -r tag ; do COMMIT_HASH=$(git rev-list -1 $tag) && GIT_COMMITTER_DATE="$(git show $COMMIT_HASH --format=%aD | head -1)" git tag -a -f $tag -m"$tag" $COMMIT_HASH ; done && git push --tags --force
vmrob
2
Ini berfungsi di git shell untuk PowerShell, tetapi Anda harus menyetel variabel lingkungan secara berbeda, dan melakukannya pada dua baris: $env:GIT_COMMITTER_DATE="Thu Nov 11 12:21:57 2010 -0800"dangit tag -a 0.9.33 -m"Retroactively tagging version 0.9.33"
roncli
18

Berikut kalimat satu baris berdasarkan beberapa komentar di jawaban lain:

git tag -l | while read -r tag ; do COMMIT_HASH=$(git rev-list -1 $tag) && GIT_COMMITTER_DATE="$(git show $COMMIT_HASH --format=%aD | head -1)" git tag -a -f $tag -m"$tag" $COMMIT_HASH ; done && git push --tags --force

PERINGATAN: ini akan menghentikan tag upstream Anda dan tidak akan menyimpan pesan untuk tag beranotasi! Pastikan bahwa Anda tahu apa yang Anda lakukan dan JELAS jangan lakukan ini untuk repositori publik !!!

Untuk memecahnya ...

# Loop over tags
git tag -l | while read -r tag
do

    # get the commit hash of the current tag
    COMMIT_HASH=$(git rev-list -1 $tag)

    # get the commit date of the tag and create a new tag using
    # the tag's name and message. By specifying the environment
    # environment variable GIT_COMMITTER_DATE before this is
    # run, we override the default tag date. Note that if you
    # specify the variable on a different line, it will apply to
    # the current environment. This isn't desired as probably
    # don't want your future tags to also have that past date.
    # Of course, when you close your shell, the variable will no
    # longer persist.
    GIT_COMMITTER_DATE="$(git show $COMMIT_HASH --format=%aD | head -1)" git tag -a -f $tag -m"$tag" $COMMIT_HASH


done

# Force push tags and overwrite ones on the server with the same name
git push --tags --force

Terima kasih kepada @Mr_and_Mrs_D atas saran untuk menggunakan satu dorongan.

vmrob
sumber
3

Berdasarkan jawaban lain, berikut adalah cara yang akan mempertahankan baris pertama pesan tag

git tag -l | while read -r tag ; do COMMIT_HASH=$(git rev-list -1 $tag) COMMIT_MSG=$(git tag -l --format='%(contents)' $tag | head -n1) && GIT_COMMITTER_DATE="$(git show $COMMIT_HASH --format=%aD | head -1)" git tag -a -f $tag -m"$COMMIT_MSG" $COMMIT_HASH ; done
git tag -l -n1           #check by listing all tags with first line of message
git push --tags --force  #push edited tags up to remote

Sedikit yang bertanggung jawab untuk menjaga pesan adalah:

COMMIT_MSG=$(git tag -l --format='%(contents)' $tag | head -n1)

head -n1akan mengambil baris pertama dari pesan komit lama. Anda dapat memodifikasinya menjadi -n2atau -n3dll untuk mendapatkan dua atau tiga baris sebagai gantinya.

Jika Anda ingin mengubah tanggal / waktu hanya untuk satu tag, berikut adalah cara Anda memecah satu baris untuk melakukannya di bash shell:

tag=v0.1.0
COMMIT_HASH=$(git rev-list -1 $tag)
COMMIT_MSG=$(git tag -l --format='%(contents)' $tag | head -n1)
COMMIT_DATE=$(git show $COMMIT_HASH --format=%aD | head -1)
GIT_COMMITTER_DATE=$COMMIT_DATE git tag -s -a -f $tag -m"$COMMIT_MSG" $COMMIT_HASH

Referensi:

weiji14
sumber
Ini bagus, terima kasih. Dalam perintah untuk mengubah satu tag, ada sebuah -sflag yang tidak ada di satu-liner, jadi saya mendapatkannya error: gpg failed to sign the datakarena saya belum mengatur sign up untuk git. Kesalahan itu membuat saya sedikit bingung.
wch