要更新我们软件中的版本号,脚本会执行以下操作:
$ hg update v3.3
(sed+awk magic to edit version numbers in code base)
$ hg commit -m"Create v3.3.50"
$ hg tag v3.3.50
$ hg push
abort: push creates new remote head 101b0ff402c6 on branch 'v3.3'!
(pull and merge or see "hg help push" for details about pushing new heads)
$ hg pull --branch v3.3 --rebase
...
adding file changes
added 1 changesets with 1 changes to 1 files (+1 heads)
$ hg push
...
added 2 changesets with 4 changes to 4 files
但是在提交之后,标记似乎不存在于目标存储库中:
$ hg tags | grep v3.3.50
$
令人困惑的是,标签位于.hgtags文件中:
$ grep v3.3.50 .hgtags
e7d6c19f8dd86cdad4cb41f543d09dbe5d30405e v3.3.50
并且在修订历史中:
$ hg log -b v3.3
changeset: 7067:701358ca0f4b
branch: v3.3
user: Joe User <juser@example.com>
date: Wed Nov 11 12:41:15 2015 -0800
summary: Added tag v3.3.50 for changeset e7d6c19f8dd8
changeset: 7066:19aafdd33263
branch: v3.3
user: Joe User <juser@example.com>
date: Wed Nov 11 12:41:15 2015 -0800
summary: Create v3.3.50
hg commit / tag / push
序列按预期工作,但添加rebase似乎至少部分删除了标记。标签是否需要对rebase命令进行一些特殊处理?
Mercurial版本是2.9.2,有问题的系统正在运行最新版本的Ubuntu。
答案 0 :(得分:4)
这可能是一种疏忽或有意的设计,而且很难分辨出它是什么(更多内容如下)。
你可以通过更新到分支的头部并通过以下方式重新修复它来修复它:
hg tag -f -r REVID TAGNAME
能够更改或删除标签是intended design,所以这不是什么古怪的。但是,原始标记提交将保持不变。
如果您想明确指出这是标签更新,请使用
hg tag -f -e -r REVID TAGNAME
允许您编辑标记提交消息,表明它是原始标记的更新。
如果您已安装了evolve,则可以避免查找原始版本并使用:
hg tag --hidden -f -r 'successors(TAGNAME)' TAGNAME
此处,successors(...)
revset函数描述了标记为TAGNAME
的原始修订版所针对的修订版。
如果您已经进化或使用hg histedit
(并且您的重定历史记录不包含自标记以来的合并),您也可以(原则上)更改原始标记提交,但我建议不要这样做,因为它可能有点挑剔(你基本上必须手动编辑.hgtags
并更新提交消息)。
如果您希望这样做,最简单的方法就是:
hg update --hidden -r 'successors(TAGNAME)'
edit .hgtags # update tag information
hg commit --amend # update commit message
hg evolve -a # propagate changes
这与histedit有点复杂:
hg histedit -r REVID # REVID = tag commit
# In the histedit editor, change "pick" to "edit" for the tag commit,
# then write the file and leave the editor.
edit .hgtags # update tag information
hg commit # provide new commit message
hg histedit --continue # rebuild rest of history
这两种方法都依赖于hg tag
只进行改变.hgtags
的正常提交并自动生成提交消息的事实。 Mercurial只依赖.hgtags
中的信息而不检查任何元数据。我还建议事先制作一个本地克隆的存储库,以防万一你弄错了,不知道如何从中恢复。
同样,我认为这不是必要的(甚至不是一个好主意),但最终决定权归你所有。
那么,这是一个bug还是设计?在rebase期间自动移动标签的一个问题是原始版本通常会保留(hg rebase --keep
或只是简单的rebase with evolve),在这种情况下,不清楚是否要移动标记或不。它也没有解决hg graft
的类似问题。所以,它可能是。
答案 1 :(得分:2)
'\s*\r?\n'
文件中的标记由变更集哈希标识标识。重新设置变更集会更改散列,因为在计算散列时会包含有关其父级的数据。
在您的示例输出中,“创建v3.3.50”变更集的散列值为“19aafdd33263” - 这与标记文件和标记变更集中引用的.hgtags
不同。
请注意,您可以重新添加添加标记的变更集,因为标记的变更集哈希不会更改。
答案 2 :(得分:0)
我们最近也遇到了这个问题,并试图为它提供复杂的解决方案,包括历史操作和更新提交消息等。最后我们意识到,重新定义一个未刷新的变更集是错误的,因为我们正在将指向出库的唯一快照的东西移动到一个新的快照,这是不一样的,因为rebase做了什么,所以我们最终得到了以下规则并相应地更改了我们的脚本:
永远不要标记未按下的变更集
即。在我们的构建脚本中,我们现在pull
,测试,增加版本,commit
,pull --rebase
,如果需要, push
并记住哈希,然后{{如果需要,再次那个哈希,tag
,commit
(现在没有任何东西可以再被破坏),最后pull --rebase
对&进行了更改#34; .hgtags&#34;
我为Mercurial打开了一个功能请求,以更好的方式解决这个问题: https://bz.mercurial-scm.org/show_bug.cgi?id=5352