更改git标签的日期(或基于它的GitHub发布)

Phr*_*ogz 89 tags git github

我通过在Main分支的各个提交中添加标签,将Releases添加到GitHub上的项目中.

在我的一个项目中,我没有按时间顺序将标记添加到提交中.(我发现了明显的提交并标记了它们,然后我发现不那么明显,较旧的提交并标记它们.)

现在GitHub将 v1.0.1 显示为当前版本,其前面是v0.7.0,之前 v1.1.2 .

它似乎使用标记创建时的日期作为发布日期而不是标记的提交.如何编辑我的标签,使其日期与标记的提交相同?

gitk和GitHub之间的版本和日期的映射

Phr*_*ogz 109

警告:这不会保留带注释标签的标签消息.

摘要

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

  1. 回到代表标记的提交
  2. 删除标签(本地和远程)
    • 这会将您在GitHub上的"发布"转换为草稿,您可以稍后删除它.
  3. 使用魔术调用重新添加同名的标记,该调用将其日期设置为提交日期.
  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
Run Code Online (Sandbox Code Playgroud)

细节

根据如何在Git中标记:

如果您忘记标记版本或版本凹凸,您可以始终追溯标记它,如下所示:

git checkout SHA1_OF_PAST_COMMIT
git tag -m"Retroactively tagging version 1.5" v1.5
Run Code Online (Sandbox Code Playgroud)

虽然这是完全可用的,但它可以使您的标签不按时间顺序排列,这可以与寻找"最新"标签的构建系统相混淆.但不要害怕.莱纳斯想到了一切:

# 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"
Run Code Online (Sandbox Code Playgroud)

但是,如果您已经添加了标记,则无法使用上述内容,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.
Run Code Online (Sandbox Code Playgroud)

相反,您必须在本地删除标记:

git tag -d 1.0.1
Run Code Online (Sandbox Code Playgroud)

远程推送该删除:

git push origin :refs/tags/1.0.1
Run Code Online (Sandbox Code Playgroud)

在GitHub上,重新加载版本 - 该版本现已标记为"草稿" - 并删除草稿.

现在,根据上面的说明添加回溯标记,最后将生成的标记推送到GitHub:

git push --tags
Run Code Online (Sandbox Code Playgroud)

然后再次重新添加GitHub发布信息.

  • 您应该能够在不签出标签的情况下完成所有这些操作.这是对你的单线程的修改,对我来说要快得多:`git tag -l | 同时读取-r标签; 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; 完成&& git push --tags` (10认同)
  • @Mr_and_Mrs_D很好的建议和一个将此操作限制为一次的好方法.考虑到这一点,我认为生成的(未经测试的)单行将是`git tag -l | 同时读取-r标签; 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; 完成&& git push --tags --force` (3认同)
  • 这是一个bash脚本,它删除并重新添加git repo中的每个标记:`git tag -l | 同时读取-r标签; 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"\`; 完成; git push --tags` (2认同)
  • 使用`git tag -af`使得`-d`成为不必要而且你留在本地所以你可以检查一切都没问题 - 然后你可以`git push --tags -f` (2认同)
  • 这适用于PowerShell的git shell,但你必须以不同的方式设置环境变量,并在两行上执行:`$ env:GIT_COMMITTER_DATE ="Thu Nov 11 12:21:57 2010 -0800"`和`git tag - 0.9.33 -m"追溯标记版本0.9.33"` (2认同)

vmr*_*rob 17

这是基于其他答案中的一些评论的单行:

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
Run Code Online (Sandbox Code Playgroud)

警告:这将破坏您的上游标签,并且不会保留带注释标签的消息!确保你知道你正在做什么,并且确定不要为公共存储库做这个!

打破它...

# 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
Run Code Online (Sandbox Code Playgroud)

感谢@Mr_and_Mrs_D建议使用单次推送.


wei*_*i14 6

在其他答案的基础上,这是一种保留标签消息第一行的方法

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
Run Code Online (Sandbox Code Playgroud)

负责保存消息的位是:

COMMIT_MSG=$(git tag -l --format='%(contents)' $tag | head -n1)
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

参考: