提前标记一个提交

Gab*_*iel 60 versioning git commit version github

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

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

所以我拥有的是:

commit 124
commit 125
commit 126 <-- tag v1.0
commit 127
Run Code Online (Sandbox Code Playgroud)

我想将v1.0标记移动到下一个提交,即:127,本地和GitHub.

我怎样才能做到这一点?

jub*_*0bs 131

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

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

在此输入图像描述

共享后将标签移动到不同的提交就像告诉所有的书友俱乐部好友一样

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

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

我是我的回购的唯一贡献者[...]

这可能是现在的情况,但如果除了你以外的其他人有权访问你的GitHub存储库(例如,如果它是公共的),他们中的一些人可能已经分叉或克隆它(虽然有一种方法可以找到),并且你运行如果你重写历史,就有可能惹恼他们.


如果你100%确定你想要移动那个标签,Git确实允许你这样做.在这里,你可以使用

git tag --force v1.0 <ID-of-commit-127>
Run Code Online (Sandbox Code Playgroud)

然后你将不得不强制推动该标签,使用

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

但是,在继续之前要三思而后行 ......

附录(2018/09/26)

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

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

最近的一个例子浮现在脑海中.Go 1.11为模块系统增加了实验支持,该模块系统严重依赖Git标签进行版本控制.在Go模块中移动已发布的标签(比如说在GitHub上)会产生灾难性的后果.

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

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

这是一个让人失望的可靠方法.

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

  • 我是那种只关心工具是什么*有用*的人,而不是它的意思. (17认同)
  • 这是一个过于宽泛的概括.想象一个包装系统,它抓取一大堆项目的快照并创建一组它们.项目作者可以使用移动标记来传达他们建议包含的修订版本.覆盖历史的分支比'git fetch --tags'更令人头痛.现在,这个用例有些缺失的是git可以保留标签的历史记录,即同一个名称的后来标签可能会影响以前的版本,但所有这些标签在历史记录中仍然可见. (10认同)
  • +1我特别喜欢读书俱乐部的比喻. (5认同)
  • @AttilaLendvai当然,但是什么工具意味着条件对它有用:) (2认同)
  • 哈哈!"泪水池" - 这本书必须是关于Git的书,对吧!? (2认同)
  • 这个答案描述了使用标签的一种方式以及在使用标签时移动标签的方式,这种方式会导致问题。但它错过了 git 中标签的一般效用。您可以随意制作一个名为“FAV”而不是“1.1.2”的标签。相同的提交,两个标签。移动 FAV 很有意义。移动 1.1.2 不会。在更深层次上了解您正在做什么,以及您正在使用的工具在更深层次上做什么。然后,您可以从这样的答案中获取有用的部分(移动标签的 git 命令是什么?)并丢弃其余部分(其他所有内容。) (2认同)

Chr*_*ris 21

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

  • v1.0在提交时推送标签abcd123
  • 你的伙伴,称他为弗雷德,取材
  • 弗雷德现在有一个本地v1.0标签abcd123
  • 您将标记移动v1.0到提交cccc222和推送
  • 可能发生以下情况:
    • Fred抓取,但v1.0服务器上的标签与他的本地v1.0标签不匹配,所以Fred必须手动修复这个冲突,即使他没有做任何事情导致它
    • Fred推出了--tags添加some-tag他创建的新标签的选项; 这个推送被服务器拒绝,因为他的本地v1.0标签和服务器的v1.0标签不一致

有两个以上的开发人员,这变得更加复杂; 如果即使一个人没有采取步骤来更新他或她的本地标签,你也可能会遇到麻烦.

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

git tag -a -f v1.0 <new-commit-hash>
git push --tags --force
Run Code Online (Sandbox Code Playgroud)

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

git tag -d v1.0
git fetch --tags
Run Code Online (Sandbox Code Playgroud)


Jon*_*rty 6

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

删除本地和远程

git tag -d <tag_name>
git push origin :refs/tags/<tag_name>
Run Code Online (Sandbox Code Playgroud)

重新创建

git tag <tag_name>
git push --tags
Run Code Online (Sandbox Code Playgroud)

  • 对于已经将标记提交拉到其本地机器(或分叉远程)的任何人,它仍然会导致冲突。您的答案实际上与之前给出的答案相同。移动或删除标签确实会改变历史,因为标签本质上是提交号的“别名”。您已更改标记引用的提交编号。更糟糕的是,正如其他更详细的答案所指出的那样,其他人的本地仓库中的标签现在引用了与您的本地仓库不同的提交,以及更改后的远程仓库。这会导致冲突和混乱。 (2认同)