Дата изменения тега git (или релиз GitHub на его основе)

Я добавляю Releases к моим проектам в GitHub, добавляя теги к различным коммитам в главном ветки.

В одном из моих проектов я не добавлял теги в коммиты в хронологическом порядке. (Я обнаружил очевидные коммиты и пометил их, а затем нашел менее очевидные, более старые коммиты и отметил их.)

Теперь GitHub показывает v1.0.1 как текущий, с v0.7.0, предшествующим ему, и v1.1.2, предшествующий этому.

Кажется, что используется дата создания тэга в качестве даты выпуска вместо фиксации, которая помечена. Как изменить мои теги так, чтобы их даты были такими же, как фиксация, которую они отмечают?

отображение релизов и дат между gitk и GitHub

Ответ 1

Резюме

Для каждого тега, который необходимо изменить:

  • Вернитесь назад к фиксации, представляющей тег
  • Удалить тег (локально и удаленно)
    • Это превратит ваш "выпуск" в GitHub в черновик, который позже можно удалить.
  • Повторно добавьте тег с одинаковым именем, используя магический вызов, который устанавливает дату в дату фиксации.
  • Нажимайте новые теги с фиксированными датами до GitHub.
  • Перейдите в GitHub, удалите все выпуски сейчас-проекта и заново создайте новые выпуски из новых тегов

В коде:

# 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

Подробнее

В соответствии с Как пометить в Git:

Если вы забыли пометить выпуск или версию bump, вы всегда можете пометить ее задним числом так:

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

И хотя это прекрасно подходит для использования, это приводит к тому, что ваши теги выводятся из хронологического порядка, которые могут завинчивать системы сборки, которые ищут "последний" тег. Но не бойтесь. Линус думал обо всем:

# 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 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"

Однако, если вы уже добавили тег, вы не можете использовать приведенное выше с помощью git tag -f existingtag, иначе git будет жаловаться при попытке слияния:

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.

Вместо этого вы должны локально удалить тег:

git tag -d 1.0.1

Удалите это удаление удаленно:

git push origin :refs/tags/1.0.1

В GitHub перезагружайте релизы - релиз теперь отмечен как "Черновик" - и удалите черновик.

Теперь добавьте обратный тег на основе вышеприведенных инструкций и, наконец, нажмите результирующий тег на GitHub:

git push --tags

а затем снова и снова добавьте информацию о выпуске GitHub.

Ответ 2

Здесь один лайнер, основанный на некоторых комментариях в другом ответе:

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

ПРЕДУПРЕЖДЕНИЕ: это приведет к удалению ваших тегов вверх по течению! Убедитесь, что вы знаете, что делаете, и ОПРЕДЕЛЕННО не делайте этого для публичного репозитория!!!

Чтобы сломать его...

# 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 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

Спасибо @Mr_and_Mrs_D за предложение использовать одно нажатие.