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

eed*_*eep 789 git git-tag

我在master分支上创建了一个标记,v0.1如下所示:

git tag -a v0.1
Run Code Online (Sandbox Code Playgroud)

但后来我意识到我需要将一些更改合并到master for release 0.1中,所以我做到了.但现在我的v0.1标签被卡住了(以调用便利贴的类比)错误的提交.我希望它停留在master上的最新提交中,但它仍然停留在master上的第二次最新提交.

如何将其移动到master上的最新提交?

Gre*_*ill 1104

使用-f选项git tag:

-f
--force

    Replace an existing tag with the given name (instead of failing)
Run Code Online (Sandbox Code Playgroud)

您可能希望-f-a强制创建带注释的标记而不是未注释的标记一起使用.

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

    git push origin :refs/tags/<tagname>
    
    Run Code Online (Sandbox Code Playgroud)
  2. 替换标记以引用最近的提交

    git tag -fa <tagname>
    
    Run Code Online (Sandbox Code Playgroud)
  3. 将标签推到远程原点

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

  • 在推送之前删除任何遥控器上的标签可能是一个好主意,通过这样做:`git push origin:refs/tag/<tagname>`然后执行`git tag -fa <tagname>`然后` git push origin master --tags`.否则,您可能会在远程的refs列表中添加奇怪的内容,并附加^和{}字符.感谢Dan在codebasehq.com指出这一点. (88认同)
  • @eedeep:小修正 - 而不是`:refs/tag/<tagname>`它应该是`:refs/tags/<tagname>`. (47认同)
  • 如果你已经推动了你的标签,你仍然可以通过强制推送`git push -f origin <tagname>来更新远程标签. (31认同)
  • 这里和文档中没有提到的是,如果没有给出新消息,这确实会移动标记消息. (10认同)
  • 这仅在您没有将代码从机器上推下时才有效.如果你有,那么最好的答案是"世界上有很多数字",因为它可能不值得麻烦. (7认同)
  • 如果标签引用可以快进到新的地方,你就不必使用强制推送。 (3认同)
  • 第一步的作用是什么?`git push origin :refs/tags/&lt;tagname&gt;` 如何删除任何内容?它不是只是将标签推到原点吗? (3认同)
  • 您是否尝试指定*两个*-a`和`-f`选项?这将使用另一个带注释的标记替换现有的带注释的标记,这是您想要的. (2认同)
  • 请注意,在#3`git push origin master --tags`将推送标签,_和`master`分支,如果你已在local_提交任何更改.如果您想要做的只是推送标签,只需使用`git push origin --tags`. (2认同)
  • 那些已经拉取这些标签的人的存储库会发生什么?他们是否会获得重复的标签,或者 git 会自动处理初始标签删除? (2认同)

小智 247

更确切地说,您必须强制添加标记,然后使用选项--tags和-f进行推送:

git tag -f -a <tagname>
git push -f --tags
Run Code Online (Sandbox Code Playgroud)

  • 该答案通过包含“-f”来推送标签来完成已接受的答案。 (4认同)
  • 如果您不想添加注释,请省略“-a”。 (4认同)

Viv*_*ive 147

总结你的遥控器是否被调用origin并且你正在master分支机构:

git tag -d <tagname>
git push origin :refs/tags/<tagname>
git tag <tagname> <commitId>
git push origin <tagname>
Run Code Online (Sandbox Code Playgroud)
  • 第1行删除本地环境中的标记.
  • 第2行删除远程环境中的标记.
  • 第3行将标记添加到不同的提交
  • 第4行将更改推送到遥控器

您还可以交换第4行以git push origin --tags使用本地更改中的标记推送所有更改.

基于@ stuart-golodetz,@ greg-hewgill,@ hedeep,@ ben-hocking答案,评论低于他们的答案,NateS评论低于我的答案.

  • 第 4 行用于将显式的*单个*更新标签推送到远程存储库,以防您不想更新所有标签,就像我不想的那样。 (2认同)

Stu*_*etz 86

删除它,git tag -d <tagname>然后在正确的提交上重新创建它.

  • 由于其简单性,这应该是公认的答案。也不要过度使用 -f 强制。 (4认同)
  • @eedeep:我认为Greg的回应实际上更好,这是公平的. (3认同)

Iva*_*van 35

我在使用Git时尽量避免一些事情.

  1. 使用内部知识,例如refs/tags.我尝试仅使用记录的Git命令,并避免使用需要了解.git目录内部内容的内容.(也就是说,我将Git视为Git用户,而不是Git开发人员.)

  2. 不需要时避免使用武力.

所以这是我在本地和远程更改标签的非暴力解决方案,而不知道Git内部.

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

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

github是示例远程名称,fix123示例标记名称和790a621265示例提交.


Nak*_*lon 18

我将离开这里,这个命令的另一种形式符合我的需要.
有一个v0.0.1.2我想要移动的标签.

$ git tag -f v0.0.1.2 63eff6a

Updated tag 'v0.0.1.2' (was 8078562)
Run Code Online (Sandbox Code Playgroud)

然后:

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

  • 这成功了,并且是最简单的答案。谢谢你! (4认同)

Sev*_*ian 14

本地删除:

git tag -d v0.1  
Run Code Online (Sandbox Code Playgroud)

在远程删除:

git push origin --delete v0.1
Run Code Online (Sandbox Code Playgroud)

然后在本地重新添加并push v0.1到最近的commit:

git tag -a v0.1
git push origin --tags
Run Code Online (Sandbox Code Playgroud)


Jua*_*bío 9

将一个标记移动到另一个提交的别名.

在您的示例中,要使用散列e2ea1639移动提交,请执行以下操作: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 message
tag-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 #"
Run Code Online (Sandbox Code Playgroud)


Але*_*гов 9

另一种方式:

在远程仓库中移动标签(如果需要,请用其他标签替换HEAD)。

$ git push --force origin HEAD:refs/tags/v0.0.1.2
Run Code Online (Sandbox Code Playgroud)

取回更改。

$ git fetch --tags
Run Code Online (Sandbox Code Playgroud)


Кон*_*лин 6

如果您使用 github 并希望更改提交以进行发布(例如您发现创建发布后没有提交)。您可以使用

git push origin :refs/tags/<tagname>
Run Code Online (Sandbox Code Playgroud)

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