快速介绍:在Mercurial中,有两种不同的方式来指代更改。
首先,有节点ID哈希。它是全局,功能像 git
提交哈希。它由40个十六进制数字组成。
其次,有本地修订号。这是一个十进制数字,从0开始并计数。与节点哈希不同,这是本地的,这意味着相同的更改集可以在两个不同的存储库中具有不同的本地修订号。这取决于每个存储库中存在哪些其他更改,并且取决于每个回购收到其更改的顺序。
可以将修订数字指定为Mercurial作为本地修订号,完整的40位哈希或“短形式标识符”。后者给出了哈希的独特前缀;也就是说,如果只有一个完整的哈希从给定的字符串开始,则匹配更改的字符串。
我发现在某些情况下,给定的十进制数字,在某些情况下,即使没有任何修订,例如 hg log
带有 -r
switch)也将匹配一些修订版给定号码的本地修订足够多,可以匹配本地修订号。
这是我偶然遇到这样的情况后构建的一个示例:
test$ hg --version
Mercurial Distributed SCM (version 6.1)
(see https://mercurial-scm.org for more information)
Copyright (C) 2005-2022 Olivia Mackall and others
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
test$ hg init
test$ touch a
test$ hg add a
test$ hg ci -d "1970-01-01 00:00:00 +0000" -u testuser -m a
test$ touch b
test$ hg add b
test$ hg ci -d "1970-01-01 00:00:00 +0000" -u testuser -m b
test$ hg log
changeset: 1:952880b76ae5
tag: tip
user: testuser
date: Thu Jan 01 00:00:00 1970 +0000
summary: b
changeset: 0:d61f66df66f9
user: testuser
date: Thu Jan 01 00:00:00 1970 +0000
summary: a
test$ hg log -r 2
abort: unknown revision '2'
test$ hg log -r 9
changeset: 1:952880b76ae5
tag: tip
user: testuser
date: Thu Jan 01 00:00:00 1970 +0000
summary: b
test$
显而易见, hg log -r 9
匹配更改集,即使没有太多更改以匹配 9 < /代码>作为本地修订号。
问题:为什么?此外,我们如何避免匹配不存在的本地修订号码?
Quick intro: In Mercurial there are two different ways to numerically refer to a changeset.
First, there's the node ID hash. It is global and functions like a git
commit hash. It consists of 40 hexadecimal digits.
Second, there's the local revision number. It is a decimal number that starts at 0 and counts up. Unlike the node hash, this is local, meaning the same changeset can have different local revision numbers in two different repos. This depends on what other changesets are present in each repo and depends even on the order each repo received their changesets.
A revision can be specified numerically to Mercurial as a local revision number, a full 40-digit hash, or "a short-form identifier". The latter gives a unique prefix of a hash; that is, if only one full hash starts with the given string then the string matches that changeset.
I found that in certain cases, Mercurial commands (such as hg log
with an -r
switch), given plain decimal numbers, will match some revision even though there aren't enough local revisions for the given number to match as a local revision number.
Here's an example I constructed after coming across such a case by chance:
test$ hg --version
Mercurial Distributed SCM (version 6.1)
(see https://mercurial-scm.org for more information)
Copyright (C) 2005-2022 Olivia Mackall and others
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
test$ hg init
test$ touch a
test$ hg add a
test$ hg ci -d "1970-01-01 00:00:00 +0000" -u testuser -m a
test$ touch b
test$ hg add b
test$ hg ci -d "1970-01-01 00:00:00 +0000" -u testuser -m b
test$ hg log
changeset: 1:952880b76ae5
tag: tip
user: testuser
date: Thu Jan 01 00:00:00 1970 +0000
summary: b
changeset: 0:d61f66df66f9
user: testuser
date: Thu Jan 01 00:00:00 1970 +0000
summary: a
test$ hg log -r 2
abort: unknown revision '2'
test$ hg log -r 9
changeset: 1:952880b76ae5
tag: tip
user: testuser
date: Thu Jan 01 00:00:00 1970 +0000
summary: b
test$
As is evident, hg log -r 9
matches a changeset even though there aren't that many changesets to match the 9
as a local revision number.
The question: Why is this? Additionally, how can we avoid matching a nonexistent local revision number?
发布评论
评论(1)
这是由于Mercurial解析了修订指定符。这是 Olivia Mackall如何解释它 2014:
也就是说,如果
Hg log -r 9
与任何本地修订号不匹配(因为存储库中的10个更改少于十个更改),则Mercurial Next将与一个恰好以一个节点匹配9
。为了避免这种歧义, Hg log -r'Rev(9)'仅匹配本地修订号,
hg log -r'ID(9)'
仅匹配前缀或完整的哈希。在RevSets的文档中
和:
不幸的是,此页面和修订版的帮助页面从6.1版开始,明确指出可以匹配的数字之间的模棱两可,即本地修订号或节点哈希前缀。我引用的2014年邮件列表线程确实包含建议以澄清这一点,但似乎没有任何内容。
此外,这是 a changeet消息以及如何影响我的脚本的操作:
This is due to how Mercurial parses revision specifiers. Here's how Olivia Mackall explains it in a mail from 2014:
That is, if
hg log -r 9
doesn't match any local revision number (because there are less than ten changesets in the repo), Mercurial next will match a node hash that happens to start with a9
.To avoid this ambiguity, she responded that one should use
hg log -r 'rev(9)'
to match only local revision numbers, andhg log -r 'id(9)'
to match only prefixes or full hashes.In the documentation on revsets, these predicates are listed as:
And:
Unfortunately, both this page and the help page on revisions do not (as of version 6.1) explicitly point out the ambiguity between numbers that can match either as local revision numbers or node hash prefixes. The 2014 mailing list thread I quoted does contain suggestions to clarify this but it appears nothing came off it.
Additionally, here is a changeset message in which I explained the entire affair and how it came to affect the operation of a script of mine: