如何将git分支上的标记移动到不同的提交?

我在主分支上创建了一个名为v0.1的标签,如下所示:

git tag -a v0.1

但后来我意识到,在0.1版的master中还需要合并一些更改,所以我就这么做了。但是现在我的v0.1标签粘在了错误的提交上(引用便利贴的比喻)。我希望它卡在主节点上的最近提交上,但它却卡在主节点上的第二个最近提交上。

我如何移动它到最近提交的主?

476089 次浏览

使用git tag -d <tagname>删除它,然后在正确的提交中重新创建它。

使用-f选项# 1:

-f--force
Replace an existing tag with the given name (instead of failing)

您可能希望将-f-a结合使用,以强制创建一个带注释的标记,而不是无注释的标记。

例子

  1. 在你推之前删除任何遥控器上的标签

    git push origin :refs/tags/<tagname>
  2. 替换标签引用最近的提交

    git tag -fa <tagname>
  3. 将标签推到远端原点

    git push origin master --tags

更准确地说,你必须强制添加标签,然后用option——tags和-f push:

git tag -f -a <tagname>git push -f --tags

总结一下,如果你的遥控器被称为origin,你正在master分支上工作:

git tag -d <tagname>                  # delete the old tag locallygit push origin :refs/tags/<tagname>  # delete the old tag remotelygit tag <tagname> <commitId>          # make a new tag locallygit push origin <tagname>             # push the new local tag to the remote

描述:

  • 第1行删除本地env中的标记。
  • 第2行删除远程环境中的标记。
  • 第3行将标记添加到不同的提交
  • 第4行将更改推到远程

您还可以将第4行更改为git push origin --tags,以将所有本地标记更改/更新推到远程repo。

上面的答案是基于@eedeep的问题内容,以及斯图尔特Golodetz格雷格Hewgill和@ben-hocking的答案,以及他们答案下面的评论,以及@NateS在我的答案下面的原始评论。

将一个标记移动到不同的提交。

在您的示例中,使用散列e2ea1639移动提交do: git tagm v0.1 e2ea1639

对于推送标签,使用git tagmp v0.1 e2ea1639

两个别名保持您原始的日期和消息。如果你使用git tag -d,你就丢失了原始信息。

将它们保存在.gitconfig文件中

# Return date of tag. (To use in another alias)tag-date = "!git show $1 | awk '{ if ($1 == \"Date:\") { print substr($0, index($0,$3)) }}' | tail -2 | head -1 #"
# Show tag messagetag-message = "!git show $1 | awk -v capture=0 '{ if(capture) message=message\"\\n\"$0}; BEGIN {message=\"\"}; { if ($1 == \"Date:\" && length(message)==0 ) {capture=1}; if ($1 == \"commit\" ) {capture=0}  }; END { print message }' | sed '$ d' | cat -s #"
### Move tag. Use: git tagm <tagname> <newcommit>tagm = "!GIT_TAG_MESSAGE=$(git tag-message $1) && GIT_COMMITTER_DATE=$(git tag-date $1) && git tag-message $1 && git tag -d $1 && git tag -a $1 $2 -m \"$GIT_TAG_MESSAGE\" #"
### Move pushed tag. Use: git tagmp <tagname> <newcommit>tagmp = "!git tagm $1 $2 && git push --delete origin $1 && git push origin $1 #"

我将在这里留下适合我需要的另一种形式的命令有一个标签v0.0.1.2,我想移动

$ git tag -f v0.0.1.2 63eff6a
Updated tag 'v0.0.1.2' (was 8078562)

然后:

$ git push --tags --force

还有一种方法:

移动标签在远程回购。(如有需要,请更换HEAD。)

$ git push --force origin HEAD:refs/tags/v0.0.1.2

取回更改。

$ git fetch --tags

如果你想移动一个带注释的标签,只改变目标提交,但保留注释消息和其他元数据使用:

moveTag() {local tagName=$1# Support passing branch/tag names (not just full commit hashes)local newTarget=$(git rev-parse $2^{commit})
git cat-file -p refs/tags/$tagName |sed "1 s/^object .*$/object $newTarget/g" |git hash-object -w --stdin -t tag |xargs -I {} git update-ref refs/tags/$tagName {}}

使用方法:moveTag <& lt; target>

上面的函数是通过引用teerapap / git-move-annotated-tag.sh开发的。

在使用Git时,我试图避免一些事情。

  1. 使用内部知识,例如refs/tags。我尝试只使用文档中的Git命令,避免使用需要了解. Git目录内部内容的东西。(也就是说,我把Git当作一个Git用户,而不是Git开发人员。)

  2. 不需要时使用武力。

  3. 过分的事情。(按压一个分支和/或许多标签,以获得我想要的标签。)

因此,这里是我在本地和远程更改标记的非暴力解决方案,而不需要了解Git内部结构。

当软件修复最终出现问题,需要更新/重新发布时,我会使用它。

git tag -d fix123                # delete the old local taggit push github :fix123          # delete the old remote tag (use for each affected remote)git tag fix123 790a621265        # create a new local taggit push github fix123           # push new tag to remote    (use for each affected remote)

github是一个示例远程名称,fix123是一个示例标记名称,790a621265是一个示例提交。

如果你使用github并且想要更改发布(例如你发现创建发布后不提交smth)。你可以使用

git push origin :refs/tags/<tagname>

在这个命令之后,github删除你的标签,你的发布将成为草稿。这意味着您可以重新创建释放并选择提交。您的文件和您的消息将被保存。

本地删除:

git tag -d v0.1

远程移除:

git push origin --delete v0.1

然后在本地重新添加,并将v0.1推送到最近的提交:

git tag -a v0.1git push origin --tags

如果期望的最终结果是更新远程上已经存在的标签的内容:

  1. # 0
  2. 提交您的更改
  3. # 0
  4. # 0