Change date of git tag (or GitHub Release based on it)

我通过在 Main 分支中的各种提交中添加标记,将 释放添加到我在 GitHub 上的项目中。

在我的一个项目中,我没有按照时间顺序向提交添加标记。(我发现显而易见的提交并标记了它们,然后我发现不那么显而易见的是,更老提交并标记了它们。)

现在,GitHub 正在显示 v1.0.1作为 current,前面是 v0.7.0,后面是 v1.1.2。

它似乎使用标记创建的日期作为发布日期,而不是被标记的提交日期。我怎样才能编辑我的标签,使它们的日期与它们正在标记的提交相同?

mapping of releases and dates between gitk and GitHub

14074 次浏览

警告: 这将为带注释的标记保留标记消息。

摘要

对于需要更改的每个标记:

  1. 回到表示标记的提交时间
  2. 删除标记(本地和远程)
    • 这将把你在 GitHub 上的“发布”变成一个草稿,以后你可以删除它。
  3. Re-add the same-named tag using a magic invocation that sets its date to the date of the commit.
  4. 将具有固定日期的新标记推回到 GitHub。
  5. 转到 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 中标记:

如果你忘记标记一个发布或者版本升级,你可以像这样追溯标记它:

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

但是,如果您已经添加了标记,则不能在 git tag -f existingtag中使用上面的代码,否则在尝试合并时 git 将发出抱怨:

Rammy:docubot phrogz$ git push --tags
To git@github.com:Phrogz/docubot.git
! [rejected]        1.0.1 -> 1.0.1 (already exists)
error: failed to push some refs to 'git@github.com: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

On GitHub, reload Releases—the release has now been marked as a "Draft"—and remove the draft.

现在,根据上面的说明添加回溯标记,并最终将结果标记推送到 GitHub:

git push --tags

然后再次添加 GitHub 发布信息。

下面是基于另一个答案中的一些评论的俏皮话:

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

感谢@Mr _ and _ Mrs _ D 建议使用单推。

Building on the other answers, here's a way that 威尔 preserve the first line of the tag message

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

负责保存消息的位是:

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

head -n1将采用旧提交消息的第一行。您可以修改它为 -n2-n3等,以获得两个或三行代替。

如果只想为一个标记更改日期/时间,可以通过下面的方法分解一行程序,在 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

References:

似乎在 git 的新版本中(在2.33.0上测试过) ,当您使用 git tag时,新标记的日期将被设置为提交的日期。

So, you can remove the tag and recreate it without setting the environment variables and it will work too.

$ tag_commit=$(git show-ref v0.1.0 | cut -d' ' -f1)
$ git tag -d v1.0.0  # Remove tag locally
$ git push --delete origin v1.0.0  # Remove tag on remote
$ git tag v1.0.0 "$tag_commit"
$ git push --tags

但是,这不允许您指定消息。一旦您指定了,当前日期将被使用。