Note:
This page is primarily intended for developers of Mercurial.
Revset null/wdir Plan
How to handle null and wdir() in revset?
Contents
1. Status of revset functions
A list of revset functions and operators sorted by category.
(TODO: add current/expected behavior of wdir())
works as expected
not determined, but seems correct
not determined, but seems wrong or unsure
wrong
1.1. Set
- common set operation or intersection with computed set
should have no problem with null and wdir()
but several functions use None (= wdir()) for different meanings
Predicate |
null |
not x |
|
|
|
x and y |
|
x or y |
|
x - y |
|
all() |
|
bundle() |
|
first(set, [n]), limit(...) |
|
|
|
hidden() |
|
last(set, [n]) |
|
|
|
outgoing([path]) |
|
remote([id [,path]]) |
|
reverse(set) |
|
1.2. Ancestor / Descendant
operation that interacts with DAG or revlog
wdir() can't live in it
null sometimes goes wrong because p2() = null
Predicate |
null |
x::y |
|
x^n, x^ |
|
x^ |
|
x~n |
|
ancestor(*changeset) |
|
|
|
|
|
ancestors(set) |
|
branchpoint() |
|
children(set) |
|
descendants(set) |
|
follow() |
|
follow(file) |
|
heads(set) |
|
|
|
merge() |
|
only(set, [set]) |
|
p1([set]) |
|
|
|
p2([set]) |
|
parents([set]) |
|
|
|
roots(set) |
|
1.3. Arithmetic
- integer comparison, increment or decrement
null should work, but wdir() can't because of None
Predicate |
null |
x:y |
|
max(set) |
|
|
|
min(set) |
|
|
|
sort(set[, [-]key...]) key=rev |
|
1.4. Changectx attribute
filter by ctx attributes
should have no problem with null and wdir()
Predicate |
null |
author(string), user(string) |
|
closed() |
|
converted([id]) |
|
date(interval) |
|
desc(string) |
|
destination([set]) |
|
extra(label, [value]) |
|
grep(regex) |
|
keyword(string) |
|
matching(revision [, field]) |
|
origin([set]) |
|
sort(set[, [-]key...]) key!=rev |
|
1.5. File status / manifest
filter by match, etc.
should have no problem with null and wdir()
Predicate |
null |
adds(pattern) |
|
contains(pattern) |
|
file(pattern) |
|
modifies(pattern) |
|
removes(pattern) |
|
subrepo([pattern]) |
|
1.6. Misc revision data
- filter by miscellaneous data that requires a real revision
tend to crash by wdir()
Predicate |
null |
bisect(string) |
|
bookmark([name]) |
|
branch(string) |
|
branch(set) |
|
bumped() |
|
divergent() |
|
draft() |
|
extinct() |
|
filelog(pattern) |
|
head() |
|
named(namespace) |
|
obsolete() |
|
public() |
|
secret() |
|
tag([name]) |
|
unstable() |
|
1.7. Trivial identifier / wrapper
Predicate |
null |
id(string) |
|
present(set) |
|
rev(number) |
|
2. Status of commands
finished
partially implemented
not yet finished
(TODO: commands that should reject wdir(), subrepo, largefiles?)
Command |
Default |
wdir |
annotate |
p1 |
|
archive |
p1 |
|
cat |
p1 |
|
diff |
p1:wdir |
|
export |
p1 |
|
files |
wdir |
|
grep |
tip:0 |
|
identify |
wdir |
|
locate |
wdir |
|
log |
tip:0 |
|
parents |
wdir |
|
status |
wdir |
|
See also 0e41f110e69e
3. Expected behavior
General guidelines (from 4691)
null should not appear in the general case
- We need a simple and consitent rules for it to appear
- It must not be an implementation hell revset side
- It should be simple enough to support it when writing revset in extension
We want similar rules for wdir()
marmoute:
null should not survive combination (and) with anything.
1) The following include null in the result - "null" - "null + 2" - "null::" (probably) - "::null" (probably) 2) the following does not includes it - "null and (::2)" - "null and date(-9001)" - "null and all()" (replaces null by any of the variant in (1)) "all()" could maybe take and argument to accept null.
yuja:
null should work just like other revisions once appeared
- "null and (:2)" -> () # because :2 = 0:2 - "null and (::2)" -> (null,) - "null and date(-100000)" -> (null,) - "null and all()" -> () # if all() = 0:tip or (null) # if all() = everything in sets (like "and true") - "wdir() and draft()" -> (wdir,)
4. Possible use cases
(TODO: I don't have good example in mind)
hg log -Gr ":wdir() and branch(name)" to show DAG of the specified branch including working directory
hg log -r "wdir():0 and modifies(pattern)"
5. Possible implementation
how null and wdir() appear in set:
fullreposet allows us to populate a set containing null and wdir() only if specified (d2de20e1451f, backed out by e16456831516)
this magic should be disabled once fullreposet is evaluated
.filter() -> spanset().filter()
None is itchy:
map None to len(repo) or INT_MAX
always integer in set: repo[len(repo)] -> wctx, but wctx.rev() -> None
- use integer representation only in revset: wrap result by a proxy set
that converts between None and len(repo)
len(repo)
will allow us to handle wdir as contiguous revision
but it is likely to hide bugs
INT_MAX
is constant, which will cause less bugs
but it can't appear in spanset, will require more special cases
- changelog, rbc, etc.
null should be handled in the same way as regular revisions because changelog knows it.
but wdir() isn't. what should we do?
https://selenic.com/pipermail/mercurial-devel/2015-July/071768.html
ff... hash:
have to exist in base-16 trie (nodetree) so that short ff... hash can be resolved correctly.
but nodetree uses INT_MAX for nullrev.
6. See also
http://www.selenic.com/pipermail/mercurial-devel/2015-May/069744.html
https://selenic.com/pipermail/mercurial-devel/2015-June/071263.html