首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么git允许远程标记移动,或者为什么不能使用git-标记进行原子测试和设置?

为什么git允许远程标记移动,或者为什么不能使用git-标记进行原子测试和设置?
EN

Stack Overflow用户
提问于 2009-07-23 04:47:50
回答 1查看 5.6K关注 0票数 5

我遇到了一个问题,两个类似的进程在同一个存储库的不同克隆中并行运行(通常在不同的计算机上)。每次进程运行时,它都会从远程获取最新的标记,然后根据所看到的标记推断出唯一的编号。

例如,如果远程上存在这些标记: 1.0 1.1 1.2 1.3,那么一个进程将选择1.4作为下一个数字。

在进程开始之前,它将创建一个新标记并将其推回远程:

代码语言:javascript
运行
复制
$ git tag 1.4 HEAD
$ git push origin tag 1.4

的想法是,这是一种原子选择数字的方法。另一个进程,如果它同时查看,也可能决定使用1.4,但是在推送它的标记时,它应该发现1.4已经存在,然后选择1.5 (然后再试一次)。

我希望我能把git标签推送当作原子。

不幸的是,由于一些奇怪的原因,git允许远程标签在某些情况下移动!

例如,假设标记1.4已放在源/母版上并按下了。另一个进程希望将标记1.4放在原点/母版^上,这将涉及向后移动标记。Git将以“非快速转发”错误拒绝此操作:

进程A:

代码语言:javascript
运行
复制
$ git tag 1.4 origin/master
$ git push origin tag 1.4
Total 0 (delta 0), reused 0 (delta 0)
To /repo1
 * [new tag]         1.4 -> 1.4

进程B:

代码语言:javascript
运行
复制
$ git tag 1.4 origin/master^
$ git push origin tag 1.4
To /repo1
 ! [rejected]        1.4 -> 1.4 (non-fast forward)
error: failed to push some refs to '/repo1'

好的,很好,进程B可以用这个来尝试1.5。

但考虑一下这种情况:

进程A:

代码语言:javascript
运行
复制
$ git tag 1.4 origin/master
$ git push origin tag 1.4
Total 0 (delta 0), reused 0 (delta 0)
To /repo1
 * [new tag]         1.4 -> 1.4

进程B:

代码语言:javascript
运行
复制
$ git tag 1.4 origin/master
$ git push origin tag 1.4
Everything up-to-date

噢。遗憾的是,git并没有指出这个标签已经存在于遥控器上。实际上,在-v中是这样的:

代码语言:javascript
运行
复制
$ git push origin tag 1.4 -v
Pushing to /repo1
To /repo1
 = [up to date]      1.4 -> 1.4
Everything up-to-date

好的,所以我可以做一些stderr重定向,搜索“= ",这将允许进程B确定1.4已经在使用。

但这有点傻。更糟的是:

进程A:

代码语言:javascript
运行
复制
$ git push origin tag 1.4
Total 0 (delta 0), reused 0 (delta 0)
To /repo1
 * [new tag]         1.4 -> 1.4

进程B:

代码语言:javascript
运行
复制
$ git push origin tag 1.4
Total 0 (delta 0), reused 0 (delta 0)
To /repo1
   fd0e09e..c6cdac9  1.4 -> 1.4

Argg!什么?吉特刚刚移动遥控器标签,没有警告!

因此,在我看来,git中的远程标记是根本失效的--它们不应该在没有明确请求的情况下“移动”。更重要的是,他们应该在默认情况下拒绝采取行动。

此外,git-tag命令应该提供一种对标记进行原子测试和设置的方法。

但是显然没有。运行git先取并不会有帮助,因为仍然存在冲突窗口,即使有冲突,在三种场景中的一种情况下,标记只是移动!

这里发生什么事情?

还有别的方法来测试和设置标签吗?

如果没有,人们如何在自动构建环境中分配和保留构建号?如何可靠地检测两个进程无意中获取了相同的版本号?

使用git 1.6.1.2。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2009-07-23 07:33:13

我认为,如果使用真正的标记对象而不是轻量级标记(更多地设计为本地标签),那么您的标签策略将是最好的。

您可以通过指定一个-a (或-m/-F)、-s-u选项(git help tag)来创建标记对象。

尝试您的示例,但将-m "1.4 tag"添加到git tag的每次调用中。标记对象不能指导其他标记对象的后代,因此您想要在上面失败的每一个推送都会失败。

票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1169659

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档