view tests/test-revset.t @ 15663:9036c7d106bf stable

largefiles: handle merges between normal files and largefiles (issue3084) The largefiles extension prevents users from adding a normal file named 'foo' if there is already a largefile with the same name. However, there was a loop-hole: when merging, it was possible to bring in a normal file named 'foo' while also having a '.hglf/foo' file. This patch fixes this by extending the manifest merge to deal with these kinds of conflicts. If there is a normal file 'foo' in the working copy, and the other parent brings in a '.hglf/foo' file, then the user will be prompted to keep the normal file or the largefile. Likewise for the symmetric case where a normal file is brought in via the second parent. The prompt looks like this: $ hg merge foo has been turned into a largefile use (l)argefile or keep as (n)ormal file? After the merge, either the '.hglf/foo' file or the 'foo' file will have been deleted. This would cause status to return output like: $ hg status M foo R foo To fix this, the lfiles_repo.status method is changed so that a removed normal file isn't shown if there is largefile with the same name, and vice versa for largefiles.
author Martin Geisler <mg@aragost.com>
date Fri, 09 Dec 2011 17:35:00 +0100
parents 41885892796e
children fc8c7a5ccc4a
line wrap: on
line source

  $ HGENCODING=utf-8
  $ export HGENCODING

  $ try() {
  >   hg debugrevspec --debug "$@"
  > }

  $ log() {
  >   hg log --template '{rev}\n' -r "$1"
  > }

  $ hg init repo
  $ cd repo

  $ echo a > a
  $ hg branch a
  marked working directory as branch a
  (branches are permanent and global, did you want a bookmark?)
  $ hg ci -Aqm0

  $ echo b > b
  $ hg branch b
  marked working directory as branch b
  (branches are permanent and global, did you want a bookmark?)
  $ hg ci -Aqm1

  $ rm a
  $ hg branch a-b-c-
  marked working directory as branch a-b-c-
  (branches are permanent and global, did you want a bookmark?)
  $ hg ci -Aqm2 -u Bob

  $ hg co 1
  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
  $ hg branch +a+b+c+
  marked working directory as branch +a+b+c+
  (branches are permanent and global, did you want a bookmark?)
  $ hg ci -Aqm3

  $ hg co 2  # interleave
  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
  $ echo bb > b
  $ hg branch -- -a-b-c-
  marked working directory as branch -a-b-c-
  (branches are permanent and global, did you want a bookmark?)
  $ hg ci -Aqm4 -d "May 12 2005"

  $ hg co 3
  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
  $ hg branch /a/b/c/
  marked working directory as branch /a/b/c/
  (branches are permanent and global, did you want a bookmark?)
  $ hg ci -Aqm"5 bug"

  $ hg merge 4
  1 files updated, 0 files merged, 1 files removed, 0 files unresolved
  (branch merge, don't forget to commit)
  $ hg branch _a_b_c_
  marked working directory as branch _a_b_c_
  (branches are permanent and global, did you want a bookmark?)
  $ hg ci -Aqm"6 issue619"

  $ hg branch .a.b.c.
  marked working directory as branch .a.b.c.
  (branches are permanent and global, did you want a bookmark?)
  $ hg ci -Aqm7

  $ hg branch all
  marked working directory as branch all
  (branches are permanent and global, did you want a bookmark?)
  $ hg ci --close-branch -Aqm8
  abort: can only close branch heads
  [255]

  $ hg co 4
  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
  $ hg branch é
  marked working directory as branch \xc3\xa9 (esc)
  (branches are permanent and global, did you want a bookmark?)
  $ hg ci -Aqm9

  $ hg tag -r6 1.0

  $ hg clone --quiet -U -r 7 . ../remote1
  $ hg clone --quiet -U -r 8 . ../remote2
  $ echo "[paths]" >> .hg/hgrc
  $ echo "default = ../remote1" >> .hg/hgrc

names that should work without quoting

  $ try a
  ('symbol', 'a')
  0
  $ try b-a
  ('minus', ('symbol', 'b'), ('symbol', 'a'))
  1
  $ try _a_b_c_
  ('symbol', '_a_b_c_')
  6
  $ try _a_b_c_-a
  ('minus', ('symbol', '_a_b_c_'), ('symbol', 'a'))
  6
  $ try .a.b.c.
  ('symbol', '.a.b.c.')
  7
  $ try .a.b.c.-a
  ('minus', ('symbol', '.a.b.c.'), ('symbol', 'a'))
  7
  $ try -- '-a-b-c-' # complains
  hg: parse error at 7: not a prefix: end
  [255]
  $ log -a-b-c- # succeeds with fallback
  4
  $ try -- -a-b-c--a # complains
  ('minus', ('minus', ('minus', ('negate', ('symbol', 'a')), ('symbol', 'b')), ('symbol', 'c')), ('negate', ('symbol', 'a')))
  abort: unknown revision '-a'!
  [255]
  $ try é
  ('symbol', '\xc3\xa9')
  9

quoting needed

  $ try '"-a-b-c-"-a'
  ('minus', ('string', '-a-b-c-'), ('symbol', 'a'))
  4

  $ log '1 or 2'
  1
  2
  $ log '1|2'
  1
  2
  $ log '1 and 2'
  $ log '1&2'
  $ try '1&2|3' # precedence - and is higher
  ('or', ('and', ('symbol', '1'), ('symbol', '2')), ('symbol', '3'))
  3
  $ try '1|2&3'
  ('or', ('symbol', '1'), ('and', ('symbol', '2'), ('symbol', '3')))
  1
  $ try '1&2&3' # associativity
  ('and', ('and', ('symbol', '1'), ('symbol', '2')), ('symbol', '3'))
  $ try '1|(2|3)'
  ('or', ('symbol', '1'), ('group', ('or', ('symbol', '2'), ('symbol', '3'))))
  1
  2
  3
  $ log '1.0' # tag
  6
  $ log 'a' # branch
  0
  $ log '2785f51ee'
  0
  $ log 'date(2005)'
  4
  $ log 'date(this is a test)'
  hg: parse error at 10: unexpected token: symbol
  [255]
  $ log 'date()'
  hg: parse error: date requires a string
  [255]
  $ log 'date'
  hg: parse error: can't use date here
  [255]
  $ log 'date('
  hg: parse error at 5: not a prefix: end
  [255]
  $ log 'date(tip)'
  abort: invalid date: 'tip'
  [255]
  $ log '"date"'
  abort: unknown revision 'date'!
  [255]
  $ log 'date(2005) and 1::'
  4

  $ log 'ancestor(1)'
  hg: parse error: ancestor requires two arguments
  [255]
  $ log 'ancestor(4,5)'
  1
  $ log 'ancestor(4,5) and 4'
  $ log 'ancestors(5)'
  0
  1
  3
  5
  $ log 'author(bob)'
  2
  $ log 'branch(é)'
  8
  9
  $ log 'children(ancestor(4,5))'
  2
  3
  $ log 'closed()'
  $ log 'contains(a)'
  0
  1
  3
  5
  $ log 'desc(B)'
  5
  $ log 'descendants(2 or 3)'
  2
  3
  4
  5
  6
  7
  8
  9
  $ log 'file(b)'
  1
  4
  $ log 'follow()'
  0
  1
  2
  4
  8
  9
  $ log 'grep("issue\d+")'
  6
  $ try 'grep("(")' # invalid regular expression
  ('func', ('symbol', 'grep'), ('string', '('))
  hg: parse error: invalid match pattern: unbalanced parenthesis
  [255]
  $ try 'grep("\bissue\d+")'
  ('func', ('symbol', 'grep'), ('string', '\x08issue\\d+'))
  $ try 'grep(r"\bissue\d+")'
  ('func', ('symbol', 'grep'), ('string', '\\bissue\\d+'))
  6
  $ try 'grep(r"\")'
  hg: parse error at 7: unterminated string
  [255]
  $ log 'head()'
  0
  1
  2
  3
  4
  5
  6
  7
  9
  $ log 'heads(6::)'
  7
  $ log 'keyword(issue)'
  6
  $ log 'limit(head(), 1)'
  0
  $ log 'max(contains(a))'
  5
  $ log 'min(contains(a))'
  0
  $ log 'merge()'
  6
  $ log 'modifies(b)'
  4
  $ log 'id(5)'
  2
  $ log 'outgoing()'
  8
  9
  $ log 'outgoing("../remote1")'
  8
  9
  $ log 'outgoing("../remote2")'
  3
  5
  6
  7
  9
  $ log 'p1(merge())'
  5
  $ log 'p2(merge())'
  4
  $ log 'parents(merge())'
  4
  5
  $ log 'removes(a)'
  2
  6
  $ log 'roots(all())'
  0
  $ log 'reverse(2 or 3 or 4 or 5)'
  5
  4
  3
  2
  $ log 'rev(5)'
  5
  $ log 'sort(limit(reverse(all()), 3))'
  7
  8
  9
  $ log 'sort(2 or 3 or 4 or 5, date)'
  2
  3
  5
  4
  $ log 'tagged()'
  6
  $ log 'tag()'
  6
  $ log 'tag(1.0)'
  6
  $ log 'tag(tip)'
  9
  $ log 'tag(unknown)'
  abort: tag 'unknown' does not exist
  [255]
  $ log 'branch(unknown)'
  abort: unknown revision 'unknown'!
  [255]
  $ log 'user(bob)'
  2

  $ log '4::8'
  4
  8
  $ log '4:8'
  4
  5
  6
  7
  8

  $ log 'sort(!merge() & (modifies(b) | user(bob) | keyword(bug) | keyword(issue) & 1::9), "-date")'
  4
  2
  5

  $ log 'not 0 and 0:2'
  1
  2
  $ log 'not 1 and 0:2'
  0
  2
  $ log 'not 2 and 0:2'
  0
  1
  $ log '(1 and 2)::'
  $ log '(1 and 2):'
  $ log '(1 and 2):3'
  $ log 'sort(head(), -rev)'
  9
  7
  6
  5
  4
  3
  2
  1
  0
  $ log '4::8 - 8'
  4

issue2437

  $ log '3 and p1(5)'
  3
  $ log '4 and p2(6)'
  4
  $ log '1 and parents(:2)'
  1
  $ log '2 and children(1:)'
  2
  $ log 'roots(all()) or roots(all())'
  0
  $ log 'heads(branch(é)) or heads(branch(é))'
  9
  $ log 'ancestors(8) and (heads(branch("-a-b-c-")) or heads(branch(é)))'
  4

issue2654: report a parse error if the revset was not completely parsed

  $ log '1 OR 2'
  hg: parse error at 2: invalid token
  [255]

or operator should preserve ordering:
  $ log 'reverse(2::4) or tip'
  4
  2
  9

parentrevspec

  $ log 'merge()^0'
  6
  $ log 'merge()^'
  5
  $ log 'merge()^1'
  5
  $ log 'merge()^2'
  4
  $ log 'merge()^^'
  3
  $ log 'merge()^1^'
  3
  $ log 'merge()^^^'
  1

  $ log 'merge()~0'
  6
  $ log 'merge()~1'
  5
  $ log 'merge()~2'
  3
  $ log 'merge()~2^1'
  1
  $ log 'merge()~3'
  1

  $ log '(-3:tip)^'
  4
  6
  8

  $ log 'tip^foo'
  hg: parse error: ^ expects a number 0, 1, or 2
  [255]

aliases:

  $ echo '[revsetalias]' >> .hg/hgrc
  $ echo 'm = merge()' >> .hg/hgrc
  $ echo 'd($1) = reverse(sort($1, date))' >> .hg/hgrc
  $ echo 'rs(ARG1, ARG2) = reverse(sort(ARG1, ARG2))' >> .hg/hgrc
  $ echo 'rs4(ARG1, ARGA, ARGB, ARG2) = reverse(sort(ARG1, ARG2))' >> .hg/hgrc

  $ try m
  ('symbol', 'm')
  ('func', ('symbol', 'merge'), None)
  6
  $ try 'd(2:5)'
  ('func', ('symbol', 'd'), ('range', ('symbol', '2'), ('symbol', '5')))
  ('func', ('symbol', 'reverse'), ('func', ('symbol', 'sort'), ('list', ('range', ('symbol', '2'), ('symbol', '5')), ('symbol', 'date'))))
  4
  5
  3
  2
  $ try 'rs(2 or 3, date)'
  ('func', ('symbol', 'rs'), ('list', ('or', ('symbol', '2'), ('symbol', '3')), ('symbol', 'date')))
  ('func', ('symbol', 'reverse'), ('func', ('symbol', 'sort'), ('list', ('or', ('symbol', '2'), ('symbol', '3')), ('symbol', 'date'))))
  3
  2
  $ try 'rs()'
  ('func', ('symbol', 'rs'), None)
  hg: parse error: invalid number of arguments: 0
  [255]
  $ try 'rs(2)'
  ('func', ('symbol', 'rs'), ('symbol', '2'))
  hg: parse error: invalid number of arguments: 1
  [255]
  $ try 'rs(2, data, 7)'
  ('func', ('symbol', 'rs'), ('list', ('list', ('symbol', '2'), ('symbol', 'data')), ('symbol', '7')))
  hg: parse error: invalid number of arguments: 3
  [255]
  $ try 'rs4(2 or 3, x, x, date)'
  ('func', ('symbol', 'rs4'), ('list', ('list', ('list', ('or', ('symbol', '2'), ('symbol', '3')), ('symbol', 'x')), ('symbol', 'x')), ('symbol', 'date')))
  ('func', ('symbol', 'reverse'), ('func', ('symbol', 'sort'), ('list', ('or', ('symbol', '2'), ('symbol', '3')), ('symbol', 'date'))))
  3
  2

issue2549 - correct optimizations

  $ log 'limit(1 or 2 or 3, 2) and not 2'
  1
  $ log 'max(1 or 2) and not 2'
  $ log 'min(1 or 2) and not 1'
  $ log 'last(1 or 2, 1) and not 2'