提前标记一个提交

时间:2014-09-15 13:16:07

标签: git github version versioning commit

我有一个只有一个分支(master)的存储库。我是我的回购的唯一贡献者。

我最近在本地添加了tag并推送到GitHub。在做了我最后一次必要的提交后,但现在我意识到我应该再做一次更改/提交。

所以我拥有的是:

commit 124
commit 125
commit 126 <-- tag v1.0
commit 127

我希望将v1.0标记移动到下一个提交,即:127,在本地和GitHub中。

我该怎么做?

3 个答案:

答案 0 :(得分:106)

你有没有去过一个读书俱乐部,成员并不都使用同一版本的“本周书”?这是一场噩梦吧?移动标签实际上会使您处于相同的状况。

如果您认为您的存储库是一本记录项目进度的书,您可以将标记视为章节标题

enter image description here

在分享之后将标签移动到另一个提交就像告诉所有的书友俱乐部好友一样

  

你知道吗,伙计们?到目前为止我们所使用的这本书的版本现在已经过时了,因为我已经完全下令第8章现在开始,而不是第126页,但是第128页。

不好。移动标记是历史重写的一种形式,您不应该重写已共享的历史记录。这是让你的合作者失望的最可靠方法。此外,你写了

  

我是我的回购[...]

的唯一贡献者

现在可能是这样,但如果除了你之外的其他人有权访问你的GitHub存储库(例如,如果它是公开的),他们中的一些人可能已经分叉或克隆它(尽管有一个way到如果你重写了历史,你就冒着惹恼他们的风险。


如果您100%确定要移动该标签,Git确实允许您这样做。在这里,您可以使用

git tag --force v1.0 <ID-of-commit-127>

然后你必须使用

强制推送该标签
git push --force --tags

但是,在继续之前,再三考虑 ......

附录(2018/09/26)

我觉得有必要重温我的答案......

多年来,有些人在评论中反对我的禁令,不要移动已发布的标签。当然,这条建议是背景而非普遍的;我不怀疑存在移动已发布标签的好案例。但是,我坚信,作为一般规则,移动已发布标签的决定应该刻意并且非常小心。

最近的一个例子浮现在脑海中。 Go 1.11为module system添加了实验性支持,该版本在很大程度上依赖于Git标记进行版本控制。在已发布的Go模块中移动标签(比如说在GitHub上)会产生灾难性的后果。

通过这样做,您将违反您(模块作者)与您的用户(依赖于您的模块的用户)之间建立的合同,因为您将否定Go模块系统打算提供的保证:

  

模块记录精确的依赖性要求并创建可重现的构建。

这是让人们生气的好方法。

这个例子可能足以说服你,至少在某些情况下,你不应该盲目地移动已发布的标签。我休息一下。

答案 1 :(得分:19)

通常不鼓励使用移动标签,因为它会因Git的高度分散性而导致问题。考虑:

  • 您在提交v1.0
  • 上推送标记abcd123
  • 你的好友,叫他弗雷德,拿起
  • Fred现在v1.0
  • 上有一个本地abcd123代码
  • 您将代码v1.0移至提交cccc222并推送
  • 可能发生以下情况:
    • Fred抓取,但服务器上的v1.0标记与其本地v1.0标记不匹配,因此Fred必须手动修复此冲突,即使他没有做什么导致它
    • Fred推送--tags选项以添加他创建的新标记some-tag;此推送被服务器拒绝,因为他的本地v1.0代码和服务器的v1.0代码不一致

有两个以上的开发人员,这会变得更复杂;如果即使一个人没有采取步骤更新他或她的本地标签,您也可以获得trouble down the line

如果您仍然确定要移动代码(可能这是一个开发人员项目,或者您确定没有人提取代码,或者您已做好准备与所有其他开发人员沟通,并确保他们更新他们的本地标签)你可以做这样的事情:

git tag -a -f v1.0 <new-commit-hash>
git push --tags --force

应鼓励其他开发人员删除其标记的本地副本并获取新标记:

git tag -d v1.0
git fetch --tags

答案 2 :(得分:-1)

您还可以删除标签然后重新创建,这不需要重写历史记录。
(否push --force

删除本地和远程

git tag -d <tag_name>
git push origin :refs/tags/<tag_name>

重新创建

git tag <tag_name>
git push --tags