【问题标题】:How to get the tag changeset after you clone or pull to a tag using mercurial?使用 mercurial 克隆或拉取标签后如何获取标签变更集?
【发布时间】:2011-04-15 19:32:22
【问题描述】:

作为明确的指南aptly points out(搜索“标签和克隆”):

当您运行 hg clone -r foo 以克隆标记为 foo 的存储库时,新的 克隆将不包含任何比标签所指的版本更新的版本, 包括创建标签的版本。结果是你会 在新版本中准确获取项目历史的正确子集 存储库,但不是您可能期望的标签

这意味着您的新克隆中的hg tags 不显示foo 标记。如果你在添加foo 标签之前克隆了同样的事情,你做了hg pull -r foo

(题外话:标签是我在 hg 中唯一不太了解的东西。我知道将它放入变更集中有优势(例如合并),但将元数据与源代码混合总是感觉很奇怪.)

很明显,我要求的是一种自动化方式,而不是作为单独的手动步骤来拉取标签变更集。

我知道我可以在 incoming 挂钩中检查这种情况(因此它适用于克隆和拉取),或者包装 clonepull

但是有更好/更简单的方法吗?


UPDATE hg bug tracker 已经有this issue

【问题讨论】:

  • 引入变更集的标签必须是我真正不喜欢 Mercurial 的少数几件事之一

标签: mercurial clone


【解决方案1】:

有一个后克隆挂钩。它被称为post-clone(hgrc 联机帮助页显示post-ANYCOMMANDpre-ANYCOMMAND 存在)尽管正如您指出的那样,您也可以使用*changegroupupdate 钩子,因为克隆同时使用这两个功能(除非您抑制更新为-U)。

如果您只需要它以供参考,那么只需添加一个--localtag 以便您拥有名称而不是额外的变更集怎么样。类似的东西

hg clone -r tagname URL
hg tag --local tagname

您可以轻松地将其构建到 shell 别名中。

除此之外,不一定保证有一种方法可以拥有修订版 X 和标记修订版 X 的修订版,而没有其他您不想要的修订版,因为标签可能在其他工作完成后应用。当然,您可以始终更新到“X”并在您的工作目录中添加后续变更集,但它们仍会在您的存储库中。

老实说,一旦我发现当你克隆到一个标签时标签名称不会很长,我承认一开始我很困惑,我觉得没有必要随身携带带有标签的变更集。

【讨论】:

  • 感谢post-clone 钩子。我从问题中删除了“并且因为没有postclone hook”。我不太喜欢本地标签,因为我肯定会在一段时间后引入标签变更集。同样没有标签变更集,我可以自己提交标签,然后我必须合并标签。
  • 是的,它并不完美,但如果不提取您可能还不想要的其他变更集(所有那些在工作和标记 cset 之间的变更集),就无法做到这一点。至少标签无缝合并,本地的不能冲突或被推送。
  • 如果标签变更集是标签的唯一孩子,我只会拉取标签变更集。 @Richard 的回答让我想到了使用预克隆和预拉钩来检查案例并将克隆/拉版本更改为标签变更集。会回帖。
【解决方案2】:

您想要一个带有 bash 和嵌入式 Perl 脚本的巨大 hack?嗯,就是这样……

#!/bin/bash
if [[ "$1" == "" || "$2" == "" || "$3" == "" ]]; then
  echo 'hgclonetag <src> <tgt> <tag>'
  exit 1;
fi

REV=`hg log -R $1 --rev $3: --limit=2 | perl -F: -lane 'if (/:([\dA-Fa-f]+)$/) {print $F[2] if defined($flag);$flag=1;}'`
hg clone --rev $REV $1 $2

这会调用hg log 命令来提取第一个与标签相关的修订之后的修订号,然后克隆到该修订。

目前这不适用于远程仓库:不幸的是,-R 开关仅适用于本地仓库。

【讨论】:

  • 如果你没有明确地包含像“giant”、“hack”这样的 git-tish 词,我肯定会接受的(哎呀,我是不是冒犯了 Linus 勋爵?远程雷电聚集.. .)、“bash”和“perl”。我希望有一个小巧、优雅、基于 hg 的 python 解决方案 :) +1。
  • 应该可以直接使用os.system 和一些正则表达式匹配来Pythonize。不错的评论:自己 +1!
  • 当您标记旧版本时,这将不起作用...如果我这样做hg tag -r 100 foo,那么我可能正在创建版本 1000。所以获取版本 101 不会引入标签。
【解决方案3】:

是的,它可以通过后克隆/拉钩来完成,但有几个骗子。

首先,它仅适用于本地 repo,因为您无法获取远程 repo 中的标签列表。

其次,处理克隆/拉取参数和选项并非易事。 (对于克隆,我需要获取目标 repo,-r-u-U。对于拉,我需要 -r-u。)我尝试使用 fancyopts,但它无法处理全局选项,它们在调度中被处理掉。我设法破解 dispatch 只给我一个命令的 args 和 opts,但感觉和看起来都很丑。

使用命令包装器将消除第二个问题。

我希望有一天 hg 会添加一个选项来克隆和拉动以干净地完成它。

【讨论】:

  • 如果你使用钩子,你不能检查$HG_URL变量的值。
  • 我也需要 pats 和 opts,但您提到 $HG_URL 帮助我从 man hgrc 发现所有 pre/post 挂钩都获得 $HG_PATS 和 $HG_OPTS。
【解决方案4】:

我想得越多,我就越相信正确的答案是克隆所有内容并更新到标签,这可以一步完成:

hg clone http://host/path#tagname

这会为您提供一切,然后将hg update 设置为标记名,从而将您的工作目录设置为正确的版本。鉴于 delta 压缩不一定要大得多,如果是,您可以从以前的本地克隆中自动克隆大部分。

【讨论】:

  • 谢谢,我不知道我也可以使用#。但是问题是,正如我的问题所述,克隆中没有标签变更集,所以我不知道克隆在哪个标签上。
  • 嗯?看起来你知道这个名字,那个名字是foo。所以你可以做hg clone http://host/path#foo。如果你真的不知道标签的名称,你应该克隆所有东西然后更新——在你的 repo 中有额外的 revs 而不是你的工作目录没有害处。
  • 对不起,我的意思是“在哪个标签 the 克隆是”,因为克隆没有 foo 标签变更集。当然,我在克隆之后就知道了,但过了一会儿就知道了(我的短期记忆很糟糕)。正如您所说,进行完整克隆然后更新是一个明显的解决方案,无论如何我总是这样做。只是clone parent#foo语义在没有得到标签变更集的情况下感觉有点奇怪。
猜你喜欢
  • 1970-01-01
  • 2013-05-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-04
相关资源
最近更新 更多