首页 文章

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

提问于
浏览
651

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

git tag -a v0.1

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

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

9 回答

  • 103

    如果要移动带注释的标记,仅更改目标提交但保留注释消息和其他元数据使用:

    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 <tag-to-move> <target>

    上述功能是通过引用teerapap/git-move-annotated-tag.sh开发的 .

  • 0

    使用 -f 选项git tag

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

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

    示例

    • 在推送之前删除任何遥控器上的标签
    git push origin :refs/tags/<tagname>
    
    • 替换标记以引用最近的提交
    git tag -fa <tagname>
    
    • 将标签推到远程原点
    git push origin master --tags
    
  • 904

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

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

    总结你的遥控器是否被称为 origin 并且你正在使用 master 分支:

    git tag -d <tagname>
    git push origin :refs/tags/<tagname>
    git tag <tagname> <commitId>
    git push origin <tagname>
    
    • 第1行删除本地环境中的标记 .

    • 第2行删除远程环境中的标记 .

    • 第3行将标记添加到不同的提交

    • 第4行将更改推送到遥控器

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

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

  • 4

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

  • 6

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

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

    然后:

    $ git push --tags --force
    
  • 2

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

    在您的示例中,要使用散列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 #"
    
  • 5

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

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

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

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

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

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

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

  • 80

    另一种方式:

    在远程仓库中移动标签 . (如果需要,将HEAD替换为任何其他标签 . )

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

    获取更改 .

    $ git fetch --tags
    

相关问题