D2593: state: add logic to parse the state file in old way if cbor fails

2018-03-24 Thread martinvonz (Martin von Zweigbergk)
martinvonz added a comment.


  In https://phab.mercurial-scm.org/D2593#44291, @indygreg wrote:
  
  > Not sure where to record this comment in this series. So I'll pick this 
commit.
  >
  > I think we want an explicit version header in the state files so clients 
know when they may be reading a file in an old format. For example, if I start 
a merge in one terminal window, I sometimes move to another terminal window to 
resolve parts of it. The multiple windows may be running different Mercurial 
versions. For example, sometimes one of the shells has a virtualenv activated 
and that virtualenv is running an older Mercurial. We don't want the older 
Mercurial trampling on state needed by the new Mercurial.
  
  
  Also, it doesn't seem like CBOR defines any magic bytes to start the 
top-level object with, so it's not obvious to me that an old state file (e.g. 
on containing just a nodeid) could not be parsed as a valid CBOR file. Perhaps 
cmdstate should help with that? We could make it always add a first item that's 
just "CBOR" or something (it seem very unlikely that we'd have that in an old 
state file), and we could fail when reading a state file that doesn't have 
that. Or would could require any new state files to have a new name than the 
old ones?

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D2593

To: pulkit, #hg-reviewers
Cc: martinvonz, indygreg, durin42, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D2594: graft: move logic to read current graft state file in state.py

2018-03-24 Thread martinvonz (Martin von Zweigbergk)
martinvonz added inline comments.

INLINE COMMENTS

> state.py:117-120
> +@readoldstatefile('graftstate')
> +def oldgraftstate(fp):
> +nodes = fp.read().splitlines()
> +return {'nodes': nodes}

Shouldn't this code be in commands.py? I don't think we should centralize the 
code for parsing all old formats in state.py. That will not happen with 
third-party extensions anyway, of course.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D2594

To: pulkit, #hg-reviewers
Cc: martinvonz, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D2593: state: add logic to parse the state file in old way if cbor fails

2018-03-24 Thread martinvonz (Martin von Zweigbergk)
martinvonz added a comment.




INLINE COMMENTS

> durin42 wrote in state.py:84
> Probably treat not-a-dict as corrupt and fall back to the other format?

How about not requiring it to be a dict? I imagine practically all callers will 
want to pass a dict, but why does this class have to enforce it? I think the  
API would be simpler if it was an opaque object. In the simple case of graft, 
the state is simply a list of nodes. However, for more complex states, we could 
have nested structures. I don't see why cmdstate should be involved in lookups 
into the top-level structure. The difference is subtle, but here's an example:

  # With dict-aware cmdstate
  cmdstate = ...
  cmdstate.load()
  version = cmdstate['version']
  for car in cmdstate['cars']:
 for wheel in car['wheels']:
 # whatever
  
  # With agnostic cmdstate
  cmdstate = ...
  parking = cmdstate.load()
  version = parking['version']
  for car in parking['cars']:
 for wheel in car['wheels']:
 # whatever

> state.py:82
> +with self._repo.vfs(self.fname, 'rb') as fp:
> +ret = cbor.load(fp)
> +if not isinstance(ret, dict):

bad ident

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D2593

To: pulkit, #hg-reviewers
Cc: martinvonz, indygreg, durin42, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D2592: state: add registrar to register function to read old state files

2018-03-24 Thread martinvonz (Martin von Zweigbergk)
martinvonz added inline comments.

INLINE COMMENTS

> state.py:104
> +should return a dict of data stored in state file."""
> +assert path not in oldstatefilefns
> +oldstatefilefns[path] = func

I think we're used ProgrammingError elsewhere for this kind of thing

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D2592

To: pulkit, #hg-reviewers
Cc: martinvonz, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D2591: state: import the file to write state files from evolve extension

2018-03-24 Thread martinvonz (Martin von Zweigbergk)
martinvonz added a comment.


  > This patch moves the file which is used to write state files easily in a 
good way using the cbor format.
  
  Is "moves the file" referring to "import from the evolve extension"? It would 
also be good to be more concrete about what "easily in a good way" means. I get 
the feeling that there's a not-so-good way you have in mind that you want to 
prevent.

INLINE COMMENTS

> state.py:61
> +def load(self):
> +"""load the existing evolvestate file into the class object"""
> +op = self._read()

drop "evolve" here and a few other places

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D2591

To: pulkit, #hg-reviewers
Cc: martinvonz, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


mercurial@37063: 8 new changesets

2018-03-24 Thread Mercurial Commits
8 new changesets in mercurial:

https://www.mercurial-scm.org/repo/hg/rev/861e9d37e56e
changeset:   37056:861e9d37e56e
user:Gregory Szorc 
date:Wed Mar 14 14:01:16 2018 -0700
summary: wireproto: buffer output frames when in half duplex mode

https://www.mercurial-scm.org/repo/hg/rev/2ec1fb9de638
changeset:   37057:2ec1fb9de638
user:Gregory Szorc 
date:Wed Mar 14 16:51:34 2018 -0700
summary: wireproto: add request IDs to frames

https://www.mercurial-scm.org/repo/hg/rev/c5e9c3b47366
changeset:   37058:c5e9c3b47366
user:Gregory Szorc 
date:Wed Mar 14 16:53:30 2018 -0700
summary: wireproto: support for receiving multiple requests

https://www.mercurial-scm.org/repo/hg/rev/bbea991635d0
changeset:   37059:bbea991635d0
user:Gregory Szorc 
date:Mon Mar 19 16:55:07 2018 -0700
summary: wireproto: service multiple command requests per HTTP request

https://www.mercurial-scm.org/repo/hg/rev/0a6c5cc09a88
changeset:   37060:0a6c5cc09a88
user:Gregory Szorc 
date:Wed Mar 14 22:19:00 2018 -0700
summary: wireproto: define human output side channel frame

https://www.mercurial-scm.org/repo/hg/rev/884a0c1604ad
changeset:   37061:884a0c1604ad
user:Gregory Szorc 
date:Thu Mar 15 16:03:14 2018 -0700
summary: wireproto: define attr-based classes for representing frames

https://www.mercurial-scm.org/repo/hg/rev/fe4c944f95bb
changeset:   37062:fe4c944f95bb
user:Gregory Szorc 
date:Thu Mar 15 16:09:58 2018 -0700
summary: wireproto: use named arguments when passing around frame data

https://www.mercurial-scm.org/repo/hg/rev/39304dd63589
changeset:   37063:39304dd63589
bookmark:@
tag: tip
user:Gregory Szorc 
date:Thu Mar 15 18:05:49 2018 -0700
summary: wireproto: explicitly track which requests are active

-- 
Repository URL: https://www.mercurial-scm.org/repo/hg
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 7 of 7] templater: factor out unwrapastype() from evalastype()

2018-03-24 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1521805435 -32400
#  Fri Mar 23 20:43:55 2018 +0900
# Node ID bcfa34ae805b92d3c9d32c8bed19c6432ba44120
# Parent  b5bdcfbf663e1fa1d7c2004a0ef6b3172cc8eff9
templater: factor out unwrapastype() from evalastype()

So ParseError of unwrapastype() can be caught reliably.

diff --git a/mercurial/templatefuncs.py b/mercurial/templatefuncs.py
--- a/mercurial/templatefuncs.py
+++ b/mercurial/templatefuncs.py
@@ -34,7 +34,6 @@ evalboolean = templateutil.evalboolean
 evalinteger = templateutil.evalinteger
 evalstring = templateutil.evalstring
 evalstringliteral = templateutil.evalstringliteral
-evalastype = templateutil.evalastype
 
 # dict of template built-in functions
 funcs = {}
@@ -261,9 +260,10 @@ def ifcontains(context, mapping, args):
 raise error.ParseError(_("ifcontains expects three or four arguments"))
 
 haystack = evalfuncarg(context, mapping, args[1])
+keytype = getattr(haystack, 'keytype', None)
 try:
-needle = evalastype(context, mapping, args[0],
-getattr(haystack, 'keytype', None) or bytes)
+needle = evalrawexp(context, mapping, args[0])
+needle = templateutil.unwrapastype(needle, keytype or bytes)
 found = (needle in haystack)
 except error.ParseError:
 found = False
diff --git a/mercurial/templateutil.py b/mercurial/templateutil.py
--- a/mercurial/templateutil.py
+++ b/mercurial/templateutil.py
@@ -77,7 +77,8 @@ class mappable(object):
 - "{manifest.rev}"
 
 Unlike a hybrid, this does not simulate the behavior of the underling
-value. Use unwrapvalue() or unwraphybrid() to obtain the inner object.
+value. Use unwrapvalue(), unwrapastype(), or unwraphybrid() to obtain
+the inner object.
 """
 
 def __init__(self, gen, key, value, makemap):
@@ -340,18 +341,18 @@ def evalstringliteral(context, mapping, 
 thing = func(context, mapping, data)
 return stringify(thing)
 
-_evalfuncbytype = {
-bytes: evalstring,
-int: evalinteger,
+_unwrapfuncbytype = {
+bytes: stringify,
+int: unwrapinteger,
 }
 
-def evalastype(context, mapping, arg, typ):
-"""Evaluate given argument and coerce its type"""
+def unwrapastype(thing, typ):
+"""Move the inner value object out of the wrapper and coerce its type"""
 try:
-f = _evalfuncbytype[typ]
+f = _unwrapfuncbytype[typ]
 except KeyError:
 raise error.ProgrammingError('invalid type specified: %r' % typ)
-return f(context, mapping, arg)
+return f(thing)
 
 def runinteger(context, mapping, data):
 return int(data)
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 7] templateutil: reimplement stringify() using flatten()

2018-03-24 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1521284660 -32400
#  Sat Mar 17 20:04:20 2018 +0900
# Node ID 60e473afb171c9c2fae598bdacd6880c1ac41ebf
# Parent  e9ae0d2c60b7a4c623f4065559f155733a290096
templateutil: reimplement stringify() using flatten()

diff --git a/mercurial/templateutil.py b/mercurial/templateutil.py
--- a/mercurial/templateutil.py
+++ b/mercurial/templateutil.py
@@ -263,18 +263,9 @@ def flatten(thing):
 
 def stringify(thing):
 """Turn values into bytes by converting into text and concatenating them"""
-thing = unwraphybrid(thing)
-if util.safehasattr(thing, '__iter__') and not isinstance(thing, bytes):
-if isinstance(thing, str):
-# This is only reachable on Python 3 (otherwise
-# isinstance(thing, bytes) would have been true), and is
-# here to prevent infinite recursion bugs on Python 3.
-raise error.ProgrammingError(
-'stringify got unexpected unicode string: %r' % thing)
-return "".join([stringify(t) for t in thing if t is not None])
-if thing is None:
-return ""
-return pycompat.bytestr(thing)
+if isinstance(thing, bytes):
+return thing  # retain localstr to be round-tripped
+return b''.join(flatten(thing))
 
 def findsymbolicname(arg):
 """Find symbolic name for the given compiled expression; returns None
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 4 of 7] templater: drop bool support from evalastype()

2018-03-24 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1521804235 -32400
#  Fri Mar 23 20:23:55 2018 +0900
# Node ID 8b71d63fb9cc8c635fab41b872b8db6d5279a58a
# Parent  63e4b6939689ee90bb27cd6522903bf44c349952
templater: drop bool support from evalastype()

Future patches will split evalastype() into two functions, evalrawexp()
and unwrapastype(), so we can catch the exception of type conversion.

  # evaluating function may bubble up inner ParseError
  thing = evalrawexp(context, mapping, arg)
  try:
  return unwrapastype(context, thing)
  except ParseError:
  # add hint and reraise

However, evalboolean() can't be factored out in this way since it has to
process boolean-like symbols as non keyword. Fortunately, it's unlikely
that we'll need a general type converter supporting bool, so this patch
drops it from the table.

diff --git a/mercurial/templateutil.py b/mercurial/templateutil.py
--- a/mercurial/templateutil.py
+++ b/mercurial/templateutil.py
@@ -333,7 +333,6 @@ def evalstringliteral(context, mapping, 
 return stringify(thing)
 
 _evalfuncbytype = {
-bool: evalboolean,
 bytes: evalstring,
 int: evalinteger,
 }
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 1 of 7] templateutil: move flatten() from templater

2018-03-24 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1521284454 -32400
#  Sat Mar 17 20:00:54 2018 +0900
# Node ID e9ae0d2c60b7a4c623f4065559f155733a290096
# Parent  65d54e54ddbe7617f5434d9bf0add18318b4fa3d
templateutil: move flatten() from templater

It's the same kind of utility as stringify().

diff --git a/mercurial/templater.py b/mercurial/templater.py
--- a/mercurial/templater.py
+++ b/mercurial/templater.py
@@ -527,33 +527,6 @@ def expandaliases(tree, aliases):
 
 # template engine
 
-def _flatten(thing):
-'''yield a single stream from a possibly nested set of iterators'''
-thing = templateutil.unwraphybrid(thing)
-if isinstance(thing, bytes):
-yield thing
-elif isinstance(thing, str):
-# We can only hit this on Python 3, and it's here to guard
-# against infinite recursion.
-raise error.ProgrammingError('Mercurial IO including templates is done'
- ' with bytes, not strings, got %r' % 
thing)
-elif thing is None:
-pass
-elif not util.safehasattr(thing, '__iter__'):
-yield pycompat.bytestr(thing)
-else:
-for i in thing:
-i = templateutil.unwraphybrid(i)
-if isinstance(i, bytes):
-yield i
-elif i is None:
-pass
-elif not util.safehasattr(i, '__iter__'):
-yield pycompat.bytestr(i)
-else:
-for j in _flatten(i):
-yield j
-
 def unquotestring(s):
 '''unwrap quotes if any; otherwise returns unmodified string'''
 if len(s) < 2 or s[0] not in "'\"" or s[0] != s[-1]:
@@ -706,7 +679,7 @@ class engine(object):
 if extramapping:
 extramapping.update(mapping)
 mapping = extramapping
-return _flatten(func(self, mapping, data))
+return templateutil.flatten(func(self, mapping, data))
 
 engines = {'default': engine}
 
diff --git a/mercurial/templateutil.py b/mercurial/templateutil.py
--- a/mercurial/templateutil.py
+++ b/mercurial/templateutil.py
@@ -234,6 +234,33 @@ def _showcompatlist(context, mapping, na
 if context.preload(endname):
 yield context.process(endname, mapping)
 
+def flatten(thing):
+"""Yield a single stream from a possibly nested set of iterators"""
+thing = unwraphybrid(thing)
+if isinstance(thing, bytes):
+yield thing
+elif isinstance(thing, str):
+# We can only hit this on Python 3, and it's here to guard
+# against infinite recursion.
+raise error.ProgrammingError('Mercurial IO including templates is done'
+ ' with bytes, not strings, got %r' % 
thing)
+elif thing is None:
+pass
+elif not util.safehasattr(thing, '__iter__'):
+yield pycompat.bytestr(thing)
+else:
+for i in thing:
+i = unwraphybrid(i)
+if isinstance(i, bytes):
+yield i
+elif i is None:
+pass
+elif not util.safehasattr(i, '__iter__'):
+yield pycompat.bytestr(i)
+else:
+for j in flatten(i):
+yield j
+
 def stringify(thing):
 """Turn values into bytes by converting into text and concatenating them"""
 thing = unwraphybrid(thing)
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 6 of 7] templater: extract unwrapinteger() function from evalinteger()

2018-03-24 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1521804852 -32400
#  Fri Mar 23 20:34:12 2018 +0900
# Node ID b5bdcfbf663e1fa1d7c2004a0ef6b3172cc8eff9
# Parent  974b91e77122678881e9618d1682cfe0cf02d367
templater: extract unwrapinteger() function from evalinteger()

diff --git a/mercurial/templateutil.py b/mercurial/templateutil.py
--- a/mercurial/templateutil.py
+++ b/mercurial/templateutil.py
@@ -318,9 +318,12 @@ def evalboolean(context, mapping, arg):
 return bool(stringify(thing))
 
 def evalinteger(context, mapping, arg, err=None):
-v = evalfuncarg(context, mapping, arg)
+return unwrapinteger(evalrawexp(context, mapping, arg), err)
+
+def unwrapinteger(thing, err=None):
+thing = _unwrapvalue(thing)
 try:
-return int(v)
+return int(thing)
 except (TypeError, ValueError):
 raise error.ParseError(err or _('not an integer'))
 
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 5 of 7] templater: extract type conversion from evalfuncarg()

2018-03-24 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1521806601 -32400
#  Fri Mar 23 21:03:21 2018 +0900
# Node ID 974b91e77122678881e9618d1682cfe0cf02d367
# Parent  8b71d63fb9cc8c635fab41b872b8db6d5279a58a
templater: extract type conversion from evalfuncarg()

Needed by the subsequent patches.

diff --git a/mercurial/templateutil.py b/mercurial/templateutil.py
--- a/mercurial/templateutil.py
+++ b/mercurial/templateutil.py
@@ -287,7 +287,12 @@ def evalrawexp(context, mapping, arg):
 
 def evalfuncarg(context, mapping, arg):
 """Evaluate given argument as value type"""
-thing = evalrawexp(context, mapping, arg)
+return _unwrapvalue(evalrawexp(context, mapping, arg))
+
+# TODO: unify this with unwrapvalue() once the bug of templatefunc.join()
+# is fixed. we can't do that right now because join() has to take a generator
+# of byte strings as it is, not a lazy byte string.
+def _unwrapvalue(thing):
 thing = unwrapvalue(thing)
 # evalrawexp() may return string, generator of strings or arbitrary object
 # such as date tuple, but filter does not want generator.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 3 of 7] templater: do not use stringify() to concatenate flattened template output

2018-03-24 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1521285186 -32400
#  Sat Mar 17 20:13:06 2018 +0900
# Node ID 63e4b6939689ee90bb27cd6522903bf44c349952
# Parent  60e473afb171c9c2fae598bdacd6880c1ac41ebf
templater: do not use stringify() to concatenate flattened template output

diff --git a/mercurial/templater.py b/mercurial/templater.py
--- a/mercurial/templater.py
+++ b/mercurial/templater.py
@@ -815,7 +815,7 @@ class templater(object):
 
 def render(self, t, mapping):
 """Render the specified named template and return result as string"""
-return templateutil.stringify(self.generate(t, mapping))
+return b''.join(self.generate(t, mapping))
 
 def generate(self, t, mapping):
 """Return a generator that renders the specified named template and
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH] test-pathconflicts-merge: stop requiring symlink support

2018-03-24 Thread Yuya Nishihara
On Sat, 24 Mar 2018 22:16:57 -0400, Matt Harbison wrote:
> # HG changeset patch
> # User Matt Harbison 
> # Date 1521943858 14400
> #  Sat Mar 24 22:10:58 2018 -0400
> # Node ID a8a0cafcef7950055e6b321a315e6f53e506fcd6
> # Parent  704932ef8913f9a4d0aaeca0ef1bdb1bda0ad87e
> test-pathconflicts-merge: stop requiring symlink support

Nice. Queued, thanks.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D2394: histedit: make histedit's commands accept revsets (issue5746)

2018-03-24 Thread yuja (Yuya Nishihara)
yuja added inline comments.

INLINE COMMENTS

> histedit.py:437
> +rulehash = _ctx.hex()
> +rev = node.bin(rulehash)
> +except error.RepoLookupError:

This could be `rev = scmutil.revsingle(...).node()`.

> histedit.py:438
> +rev = node.bin(rulehash)
> +except error.RepoLookupError:
> +raise error.ParseError("invalid changeset %s" % ruleid)

Note that `error.LookupError` may be raised if `ruleid` is odd-length and if it 
is an ambiguous hash.

I think the error message would be still correct, though.

> histedit.py:439
> +except error.RepoLookupError:
> +raise error.ParseError("invalid changeset %s" % ruleid)
>  return cls(state, rev)

`_("invalid changeset %s")` for translation.

Can you send a followup?

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D2394

To: sangeet259, durin42, #hg-reviewers
Cc: yuja, pulkit, tom.prince, krbullock, rishabhmadan96, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D2872: wireproto: define human output side channel frame

2018-03-24 Thread yuja (Yuya Nishihara)
yuja added inline comments.

INLINE COMMENTS

> wireprotoframing.py:318
> +# Formatting string must be UTF-8.
> +formatting = formatting.decode(r'utf-8', r'replace').encode(r'utf-8')
> +

It's probably better to require everything in ASCII if `formatting` is supposed 
to be fed to `_()`.

It's a disaster to mix utf-8 bytes and local-encoding bytes in codebase.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D2872

To: indygreg, #hg-reviewers, durin42
Cc: yuja, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D2871: wireproto: service multiple command requests per HTTP request

2018-03-24 Thread yuja (Yuya Nishihara)
yuja added inline comments.

INLINE COMMENTS

> wireprotoserver.py:557
>  elif action == 'noop':
>  pass
>  else:

Nit: `return False` instead of returning None?

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D2871

To: indygreg, #hg-reviewers, durin42
Cc: yuja, durin42, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 7] util: mark filtertable as private constant

2018-03-24 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1521869914 -32400
#  Sat Mar 24 14:38:34 2018 +0900
# Node ID 4bd2d19ecff7aa5ce3ce695427a478b9d3be9ff1
# Parent  348e7462944f36f0fbea25bcf407c78d68aeaa1f
util: mark filtertable as private constant

Prepares for porting to utils.*.

diff --git a/mercurial/util.py b/mercurial/util.py
--- a/mercurial/util.py
+++ b/mercurial/util.py
@@ -1541,14 +1541,14 @@ def tempfilter(s, cmd):
 except OSError:
 pass
 
-filtertable = {
+_filtertable = {
 'tempfile:': tempfilter,
 'pipe:': pipefilter,
-}
+}
 
 def filter(s, cmd):
 "filter a string through a command that transforms its input to its output"
-for name, fn in filtertable.iteritems():
+for name, fn in _filtertable.iteritems():
 if cmd.startswith(name):
 return fn(s, cmd[len(name):].lstrip())
 return pipefilter(s, cmd)
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 7 of 7] util: deprecate procutil proxy functions (API)

2018-03-24 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1521870855 -32400
#  Sat Mar 24 14:54:15 2018 +0900
# Node ID 65d54e54ddbe7617f5434d9bf0add18318b4fa3d
# Parent  b7feaf3298d4ba5682624cafa6b87b6b09f31c13
util: deprecate procutil proxy functions (API)

Several functions are re-exported by utils.procutil, which require explicit
modname parameter.

.. api::

   Utility functions related to process/executable management have been moved
   to utils.procutil module.

diff --git a/mercurial/util.py b/mercurial/util.py
--- a/mercurial/util.py
+++ b/mercurial/util.py
@@ -3772,10 +3772,10 @@ def uvarintdecodestream(fh):
 # Deprecation warnings for util.py splitting
 ###
 
-def _deprecatedfunc(func, version):
+def _deprecatedfunc(func, version, modname=None):
 def wrapped(*args, **kwargs):
 fn = pycompat.sysbytes(func.__name__)
-mn = pycompat.sysbytes(func.__module__)[len('mercurial.'):]
+mn = modname or pycompat.sysbytes(func.__module__)[len('mercurial.'):]
 msg = "'util.%s' is deprecated, use '%s.%s'" % (fn, mn, fn)
 nouideprecwarn(msg, version)
 return func(*args, **kwargs)
@@ -3795,46 +3795,55 @@ matchdate = _deprecatedfunc(dateutil.mat
 stderr = procutil.stderr
 stdin = procutil.stdin
 stdout = procutil.stdout
-explainexit = procutil.explainexit
-findexe = procutil.findexe
-getuser = procutil.getuser
-getpid = procutil.getpid
-hidewindow = procutil.hidewindow
-popen = procutil.popen
-quotecommand = procutil.quotecommand
-readpipe = procutil.readpipe
-setbinary = procutil.setbinary
-setsignalhandler = procutil.setsignalhandler
-shellquote = procutil.shellquote
-shellsplit = procutil.shellsplit
-spawndetached = procutil.spawndetached
-sshargs = procutil.sshargs
-testpid = procutil.testpid
+explainexit = _deprecatedfunc(procutil.explainexit, '4.6',
+  modname='utils.procutil')
+findexe = _deprecatedfunc(procutil.findexe, '4.6', modname='utils.procutil')
+getuser = _deprecatedfunc(procutil.getuser, '4.6', modname='utils.procutil')
+getpid = _deprecatedfunc(procutil.getpid, '4.6', modname='utils.procutil')
+hidewindow = _deprecatedfunc(procutil.hidewindow, '4.6',
+ modname='utils.procutil')
+popen = _deprecatedfunc(procutil.popen, '4.6', modname='utils.procutil')
+quotecommand = _deprecatedfunc(procutil.quotecommand, '4.6',
+   modname='utils.procutil')
+readpipe = _deprecatedfunc(procutil.readpipe, '4.6', modname='utils.procutil')
+setbinary = _deprecatedfunc(procutil.setbinary, '4.6', 
modname='utils.procutil')
+setsignalhandler = _deprecatedfunc(procutil.setsignalhandler, '4.6',
+   modname='utils.procutil')
+shellquote = _deprecatedfunc(procutil.shellquote, '4.6',
+ modname='utils.procutil')
+shellsplit = _deprecatedfunc(procutil.shellsplit, '4.6',
+ modname='utils.procutil')
+spawndetached = _deprecatedfunc(procutil.spawndetached, '4.6',
+modname='utils.procutil')
+sshargs = _deprecatedfunc(procutil.sshargs, '4.6', modname='utils.procutil')
+testpid = _deprecatedfunc(procutil.testpid, '4.6', modname='utils.procutil')
 try:
-setprocname = procutil.setprocname
+setprocname = _deprecatedfunc(procutil.setprocname, '4.6',
+  modname='utils.procutil')
 except AttributeError:
 pass
 try:
-unblocksignal = procutil.unblocksignal
+unblocksignal = _deprecatedfunc(procutil.unblocksignal, '4.6',
+modname='utils.procutil')
 except AttributeError:
 pass
 closefds = procutil.closefds
-isatty = procutil.isatty
-popen2 = procutil.popen2
-popen3 = procutil.popen3
-popen4 = procutil.popen4
-pipefilter = procutil.pipefilter
-tempfilter = procutil.tempfilter
-filter = procutil.filter
-mainfrozen = procutil.mainfrozen
-hgexecutable = procutil.hgexecutable
-isstdin = procutil.isstdin
-isstdout = procutil.isstdout
-shellenviron = procutil.shellenviron
-system = procutil.system
-gui = procutil.gui
-hgcmd = procutil.hgcmd
-rundetached = procutil.rundetached
+isatty = _deprecatedfunc(procutil.isatty, '4.6')
+popen2 = _deprecatedfunc(procutil.popen2, '4.6')
+popen3 = _deprecatedfunc(procutil.popen3, '4.6')
+popen4 = _deprecatedfunc(procutil.popen4, '4.6')
+pipefilter = _deprecatedfunc(procutil.pipefilter, '4.6')
+tempfilter = _deprecatedfunc(procutil.tempfilter, '4.6')
+filter = _deprecatedfunc(procutil.filter, '4.6')
+mainfrozen = _deprecatedfunc(procutil.mainfrozen, '4.6')
+hgexecutable = _deprecatedfunc(procutil.hgexecutable, '4.6')
+isstdin = _deprecatedfunc(procutil.isstdin, '4.6')
+isstdout = _deprecatedfunc(procutil.isstdout, '4.6')
+shellenviron = _deprecatedfunc(procutil.shellenviron, '4.6')
+system = _deprecatedfunc(procutil.system, '4.6')
+gui = _deprecatedfunc(procutil.gui, '4.6')
+hgcmd = _deprecatedfunc(procutil.hgcmd, '4.6')
+rundetached = _deprecatedfunc(procutil.rundetached, '4

[PATCH 5 of 7] procutil: bulk-replace util.std* to point to new module

2018-03-24 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1521871773 -32400
#  Sat Mar 24 15:09:33 2018 +0900
# Node ID 45b434eaa0d479be8078bbe16533d2b0d94c7220
# Parent  8adca2640e0b1eb61be50146d429d4276b6f52bd
procutil: bulk-replace util.std* to point to new module

diff --git a/mercurial/chgserver.py b/mercurial/chgserver.py
--- a/mercurial/chgserver.py
+++ b/mercurial/chgserver.py
@@ -61,6 +61,10 @@ from . import (
 util,
 )
 
+from .utils import (
+procutil,
+)
+
 _log = commandserver.log
 
 def _hashlist(items):
@@ -200,7 +204,7 @@ def _newchgui(srcui, csystem, attachio):
 # these situations and will behave differently (write to stdout).
 if (out is not self.fout
 or not util.safehasattr(self.fout, 'fileno')
-or self.fout.fileno() != util.stdout.fileno()):
+or self.fout.fileno() != procutil.stdout.fileno()):
 return util.system(cmd, environ=environ, cwd=cwd, out=out)
 self.flush()
 return self._csystem(cmd, util.shellenviron(environ), cwd)
diff --git a/mercurial/commandserver.py b/mercurial/commandserver.py
--- a/mercurial/commandserver.py
+++ b/mercurial/commandserver.py
@@ -29,6 +29,9 @@ from . import (
 pycompat,
 util,
 )
+from .utils import (
+procutil,
+)
 
 logfile = None
 
@@ -308,8 +311,8 @@ def _protectio(ui):
 ui.flush()
 newfiles = []
 nullfd = os.open(os.devnull, os.O_RDWR)
-for f, sysf, mode in [(ui.fin, util.stdin, r'rb'),
-  (ui.fout, util.stdout, r'wb')]:
+for f, sysf, mode in [(ui.fin, procutil.stdin, r'rb'),
+  (ui.fout, procutil.stdout, r'wb')]:
 if f is sysf:
 newfd = os.dup(f.fileno())
 os.dup2(nullfd, f.fileno())
diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py
--- a/mercurial/dispatch.py
+++ b/mercurial/dispatch.py
@@ -42,6 +42,7 @@ from . import (
 )
 
 from .utils import (
+procutil,
 stringutil,
 )
 
@@ -127,8 +128,8 @@ if pycompat.ispy3:
 pass
 # Otherwise mark it as closed to silence "Exception ignored in"
 # message emitted by the interpreter finalizer. Be careful to
-# not close util.stdout, which may be a fdopen-ed file object and
-# its close() actually closes the underlying file descriptor.
+# not close procutil.stdout, which may be a fdopen-ed file object
+# and its close() actually closes the underlying file descriptor.
 try:
 fp.close()
 except IOError:
@@ -180,7 +181,7 @@ def dispatch(req):
 elif req.ui:
 ferr = req.ui.ferr
 else:
-ferr = util.stderr
+ferr = procutil.stderr
 
 try:
 if not req.ui:
diff --git a/mercurial/hgweb/wsgicgi.py b/mercurial/hgweb/wsgicgi.py
--- a/mercurial/hgweb/wsgicgi.py
+++ b/mercurial/hgweb/wsgicgi.py
@@ -15,13 +15,17 @@ from .. import (
 util,
 )
 
+from ..utils import (
+procutil,
+)
+
 from . import (
 common,
 )
 
 def launch(application):
-util.setbinary(util.stdin)
-util.setbinary(util.stdout)
+util.setbinary(procutil.stdin)
+util.setbinary(procutil.stdout)
 
 environ = dict(encoding.environ.iteritems())
 environ.setdefault(r'PATH_INFO', '')
@@ -31,12 +35,12 @@ def launch(application):
 if environ[r'PATH_INFO'].startswith(scriptname):
 environ[r'PATH_INFO'] = environ[r'PATH_INFO'][len(scriptname):]
 
-stdin = util.stdin
+stdin = procutil.stdin
 if environ.get(r'HTTP_EXPECT', r'').lower() == r'100-continue':
-stdin = common.continuereader(stdin, util.stdout.write)
+stdin = common.continuereader(stdin, procutil.stdout.write)
 
 environ[r'wsgi.input'] = stdin
-environ[r'wsgi.errors'] = util.stderr
+environ[r'wsgi.errors'] = procutil.stderr
 environ[r'wsgi.version'] = (1, 0)
 environ[r'wsgi.multithread'] = False
 environ[r'wsgi.multiprocess'] = True
@@ -49,7 +53,7 @@ def launch(application):
 
 headers_set = []
 headers_sent = []
-out = util.stdout
+out = procutil.stdout
 
 def write(data):
 if not headers_set:
diff --git a/mercurial/hook.py b/mercurial/hook.py
--- a/mercurial/hook.py
+++ b/mercurial/hook.py
@@ -19,6 +19,9 @@ from . import (
 pycompat,
 util,
 )
+from .utils import (
+procutil,
+)
 
 def _pythonhook(ui, repo, htype, hname, funcname, args, throw):
 '''call python hook. hook is callable object, looked up as
@@ -222,11 +225,11 @@ def runhooks(ui, repo, htype, hooks, thr
 for hname, cmd in hooks:
 if oldstdout == -1 and _redirect:
 try:
-stdoutno = util.stdout.fileno()
-stderrno = util.stderr.fileno()
+stdoutno = procutil.stdout.fileno()
+stderrno = procutil.stderr.fileno()
 # temporarily redirect stdout to stderr, if possible

[PATCH 1 of 7] util: mark platform-specific gethgcmd() as private

2018-03-24 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1521878683 -32400
#  Sat Mar 24 17:04:43 2018 +0900
# Node ID 348e7462944f36f0fbea25bcf407c78d68aeaa1f
# Parent  704932ef8913f9a4d0aaeca0ef1bdb1bda0ad87e
util: mark platform-specific gethgcmd() as private

util.hgcmd() is the public interface for gethgcmd().

diff --git a/mercurial/util.py b/mercurial/util.py
--- a/mercurial/util.py
+++ b/mercurial/util.py
@@ -114,7 +114,7 @@ explainexit = platform.explainexit
 findexe = platform.findexe
 getfsmountpoint = platform.getfsmountpoint
 getfstype = platform.getfstype
-gethgcmd = platform.gethgcmd
+_gethgcmd = platform.gethgcmd
 getuser = platform.getuser
 getpid = os.getpid
 groupmembers = platform.groupmembers
@@ -2728,7 +2728,7 @@ def hgcmd():
 return [encoding.environ['EXECUTABLEPATH']]
 else:
 return [pycompat.sysexecutable]
-return gethgcmd()
+return _gethgcmd()
 
 def rundetached(args, condfn):
 """Execute the argument list in a detached process.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 6 of 7] procutil: bulk-replace function calls to point to new module

2018-03-24 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1521871851 -32400
#  Sat Mar 24 15:10:51 2018 +0900
# Node ID b7feaf3298d4ba5682624cafa6b87b6b09f31c13
# Parent  45b434eaa0d479be8078bbe16533d2b0d94c7220
procutil: bulk-replace function calls to point to new module

diff --git a/contrib/dumprevlog b/contrib/dumprevlog
--- a/contrib/dumprevlog
+++ b/contrib/dumprevlog
@@ -8,11 +8,13 @@ import sys
 from mercurial import (
 node,
 revlog,
-util,
+)
+from mercurial.utils import (
+procutil,
 )
 
 for fp in (sys.stdin, sys.stdout, sys.stderr):
-util.setbinary(fp)
+procutil.setbinary(fp)
 
 def binopen(path, mode='rb'):
 if 'b' not in mode:
diff --git a/contrib/phabricator.py b/contrib/phabricator.py
--- a/contrib/phabricator.py
+++ b/contrib/phabricator.py
@@ -66,6 +66,9 @@ from mercurial import (
 url as urlmod,
 util,
 )
+from mercurial.utils import (
+procutil,
+)
 
 cmdtable = {}
 command = registrar.command(cmdtable)
@@ -161,7 +164,8 @@ def callconduit(repo, name, params):
 data = urlencodenested(params)
 curlcmd = repo.ui.config('phabricator', 'curlcmd')
 if curlcmd:
-sin, sout = util.popen2('%s -d @- %s' % (curlcmd, 
util.shellquote(url)))
+sin, sout = procutil.popen2('%s -d @- %s'
+% (curlcmd, procutil.shellquote(url)))
 sin.write(data)
 sin.close()
 body = sout.read()
diff --git a/contrib/simplemerge b/contrib/simplemerge
--- a/contrib/simplemerge
+++ b/contrib/simplemerge
@@ -14,7 +14,9 @@ from mercurial import (
 fancyopts,
 simplemerge,
 ui as uimod,
-util,
+)
+from mercurial.utils import (
+procutil,
 )
 
 options = [('L', 'label', [], _('labels to use on conflict markers')),
@@ -52,7 +54,7 @@ def showhelp():
 
 try:
 for fp in (sys.stdin, sys.stdout, sys.stderr):
-util.setbinary(fp)
+procutil.setbinary(fp)
 
 opts = {}
 try:
diff --git a/contrib/undumprevlog b/contrib/undumprevlog
--- a/contrib/undumprevlog
+++ b/contrib/undumprevlog
@@ -10,12 +10,14 @@ from mercurial import (
 node,
 revlog,
 transaction,
-util,
 vfs as vfsmod,
 )
+from mercurial.utils import (
+procutil,
+)
 
 for fp in (sys.stdin, sys.stdout, sys.stderr):
-util.setbinary(fp)
+procutil.setbinary(fp)
 
 opener = vfsmod.vfs('.', False)
 tr = transaction.transaction(sys.stderr.write, opener, {'store': opener},
diff --git a/hgext/acl.py b/hgext/acl.py
--- a/hgext/acl.py
+++ b/hgext/acl.py
@@ -201,6 +201,9 @@ from mercurial import (
 registrar,
 util,
 )
+from mercurial.utils import (
+procutil,
+)
 
 urlreq = util.urlreq
 
@@ -338,7 +341,7 @@ def hook(ui, repo, hooktype, node=None, 
 user = urlreq.unquote(url[3])
 
 if user is None:
-user = util.getuser()
+user = procutil.getuser()
 
 ui.debug('acl: checking access for user "%s"\n' % user)
 
diff --git a/hgext/blackbox.py b/hgext/blackbox.py
--- a/hgext/blackbox.py
+++ b/hgext/blackbox.py
@@ -49,7 +49,10 @@ from mercurial import (
 ui as uimod,
 util,
 )
-from mercurial.utils import dateutil
+from mercurial.utils import (
+dateutil,
+procutil,
+)
 
 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' 
for
 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
@@ -166,8 +169,8 @@ def wrapui(ui):
 ui._bbinlog = True
 default = self.configdate('devel', 'default-date')
 date = dateutil.datestr(default, '%Y/%m/%d %H:%M:%S')
-user = util.getuser()
-pid = '%d' % util.getpid()
+user = procutil.getuser()
+pid = '%d' % procutil.getpid()
 formattedmsg = msg[0] % msg[1:]
 rev = '(unknown)'
 changed = ''
diff --git a/hgext/bugzilla.py b/hgext/bugzilla.py
--- a/hgext/bugzilla.py
+++ b/hgext/bugzilla.py
@@ -308,6 +308,7 @@ from mercurial import (
 util,
 )
 from mercurial.utils import (
+procutil,
 stringutil,
 )
 
@@ -527,13 +528,13 @@ class bzmysql(bzaccess):
 except TypeError:
 cmd = cmdfmt % {'bzdir': bzdir, 'id': id, 'user': user}
 self.ui.note(_('running notify command %s\n') % cmd)
-fp = util.popen('(%s) 2>&1' % cmd)
+fp = procutil.popen('(%s) 2>&1' % cmd)
 out = fp.read()
 ret = fp.close()
 if ret:
 self.ui.warn(out)
 raise error.Abort(_('bugzilla notify command %s') %
- util.explainexit(ret)[0])
+  procutil.explainexit(ret)[0])
 self.ui.status(_('done\n'))
 
 def get_user_id(self, user):
diff --git a/hgext/convert/common.py b/hgext/convert/common.py
--- a/hgext/convert/common.py
+++ b/hgext/convert/common.py
@@ -22,6 +22,9 @@ from mercurial import (
 pycompat,
 util,
 )
+from mercurial.utils import (
+procutil,
+)
 
 pickle = util.

[PATCH 3 of 7] util: stop using readfile() in tempfilter()

2018-03-24 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1521869554 -32400
#  Sat Mar 24 14:32:34 2018 +0900
# Node ID dd177967cc70361c854ac5b59672c1c903a11c7c
# Parent  4bd2d19ecff7aa5ce3ce695427a478b9d3be9ff1
util: stop using readfile() in tempfilter()

To unblock code move to utils.*. It's merely two lines of very Pythonic code.
No helper function should be needed.

diff --git a/mercurial/util.py b/mercurial/util.py
--- a/mercurial/util.py
+++ b/mercurial/util.py
@@ -1528,7 +1528,8 @@ def tempfilter(s, cmd):
 if code:
 raise error.Abort(_("command '%s' failed: %s") %
   (cmd, explainexit(code)))
-return readfile(outname)
+with open(outname, 'rb') as fp:
+return fp.read()
 finally:
 try:
 if inname:
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH] test-pathconflicts-merge: stop requiring symlink support

2018-03-24 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1521943858 14400
#  Sat Mar 24 22:10:58 2018 -0400
# Node ID a8a0cafcef7950055e6b321a315e6f53e506fcd6
# Parent  704932ef8913f9a4d0aaeca0ef1bdb1bda0ad87e
test-pathconflicts-merge: stop requiring symlink support

The errors from the last time I took a shot at this back in early November have
disappeared, so let's just enable this.

diff --git a/tests/test-pathconflicts-merge.t b/tests/test-pathconflicts-merge.t
--- a/tests/test-pathconflicts-merge.t
+++ b/tests/test-pathconflicts-merge.t
@@ -1,5 +1,3 @@
-#require symlink
-
 Path conflict checking is currently disabled by default because of issue5716.
 Turn it on for this test.
 
@@ -24,11 +22,29 @@ Turn it on for this test.
   $ hg bookmark -i file2
   $ hg up 0
   0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+
+#if symlink
   $ mkdir a
   $ ln -s c a/b
   $ hg add a/b
   $ hg commit -m "link"
   created new head
+#else
+  $ hg import -q --bypass - < # HG changeset patch
+  > link
+  > 
+  > diff --git a/a/b b/a/b
+  > new file mode 12
+  > --- /dev/null
+  > +++ b/a/b
+  > @@ -0,0 +1,1 @@
+  > +c
+  > \ No newline at end of file
+  > EOF
+  $ hg up -q
+#endif
+
   $ hg bookmark -i link
   $ hg up 0
   0 files updated, 0 files merged, 1 files removed, 0 files unresolved
@@ -131,8 +147,15 @@ Merge - local directory conflicts with r
   use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to 
abandon
   [1]
   $ hg mv a/b~2ea68033e3be a/b.old
+
+#if symlink
   $ readlink.py a/b.old
   a/b.old -> c
+#else
+  $ cat a/b.old
+  c (no-eol)
+#endif
+
   $ hg resolve --mark a/b
   (no more unresolved files)
   $ hg commit -m "merge link (rename link)"
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D2701: merge: use constants for actions

2018-03-24 Thread indygreg (Gregory Szorc)
This revision was automatically updated to reflect the committed changes.
Closed by commit rHG43ffd9070da1: merge: use constants for actions (authored by 
indygreg, committed by ).

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D2701?vs=6662&id=7278

REVISION DETAIL
  https://phab.mercurial-scm.org/D2701

AFFECTED FILES
  mercurial/merge.py

CHANGE DETAILS

diff --git a/mercurial/merge.py b/mercurial/merge.py
--- a/mercurial/merge.py
+++ b/mercurial/merge.py
@@ -71,6 +71,23 @@
 MERGE_RECORD_RESOLVED_PATH = b'pr'
 MERGE_RECORD_DRIVER_RESOLVED = b'd'
 
+ACTION_FORGET = b'f'
+ACTION_REMOVE = b'r'
+ACTION_ADD = b'a'
+ACTION_GET = b'g'
+ACTION_PATH_CONFLICT = b'p'
+ACTION_PATH_CONFLICT_RESOLVE = b'pr'
+ACTION_ADD_MODIFIED = b'am'
+ACTION_CREATED = b'c'
+ACTION_DELETED_CHANGED = b'dc'
+ACTION_CHANGED_DELETED = b'cd'
+ACTION_MERGE = b'm'
+ACTION_LOCAL_DIR_RENAME_GET = b'dg'
+ACTION_DIR_RENAME_MOVE_LOCAL = b'dm'
+ACTION_KEEP = b'k'
+ACTION_EXEC = b'e'
+ACTION_CREATED_MERGE = b'cm'
+
 class mergestate(object):
 '''track 3-way merge state of individual files
 
@@ -588,18 +605,18 @@
 if fcd.isabsent():
 # dc: local picked. Need to drop if present, which may
 # happen on re-resolves.
-action = 'f'
+action = ACTION_FORGET
 else:
 # cd: remote picked (or otherwise deleted)
-action = 'r'
+action = ACTION_REMOVE
 else:
 if fcd.isabsent(): # dc: remote picked
-action = 'g'
+action = ACTION_GET
 elif fco.isabsent(): # cd: local picked
 if dfile in self.localctx:
-action = 'am'
+action = ACTION_ADD_MODIFIED
 else:
-action = 'a'
+action = ACTION_ADD
 # else: regular merges (no action necessary)
 self._results[dfile] = r, action
 
@@ -631,7 +648,7 @@
 if r is None:
 updated += 1
 elif r == 0:
-if action == 'r':
+if action == ACTION_REMOVE:
 removed += 1
 else:
 merged += 1
@@ -643,7 +660,13 @@
 
 def actions(self):
 """return lists of actions to perform on the dirstate"""
-actions = {'r': [], 'f': [], 'a': [], 'am': [], 'g': []}
+actions = {
+ACTION_REMOVE: [],
+ACTION_FORGET: [],
+ACTION_ADD: [],
+ACTION_ADD_MODIFIED: [],
+ACTION_GET: [],
+}
 for f, (r, action) in self._results.iteritems():
 if action is not None:
 actions[action].append((f, None, "merge result"))
@@ -658,19 +681,19 @@
 """queues a file to be removed from the dirstate
 
 Meant for use by custom merge drivers."""
-self._results[f] = 0, 'r'
+self._results[f] = 0, ACTION_REMOVE
 
 def queueadd(self, f):
 """queues a file to be added to the dirstate
 
 Meant for use by custom merge drivers."""
-self._results[f] = 0, 'a'
+self._results[f] = 0, ACTION_ADD
 
 def queueget(self, f):
 """queues a file to be marked modified in the dirstate
 
 Meant for use by custom merge drivers."""
-self._results[f] = 0, 'g'
+self._results[f] = 0, ACTION_GET
 
 def _getcheckunknownconfig(repo, section, name):
 config = repo.ui.config(section, name)
@@ -772,14 +795,14 @@
 
 checkunknowndirs = _unknowndirschecker()
 for f, (m, args, msg) in actions.iteritems():
-if m in ('c', 'dc'):
+if m in (ACTION_CREATED, ACTION_DELETED_CHANGED):
 if _checkunknownfile(repo, wctx, mctx, f):
 fileconflicts.add(f)
 elif pathconfig and f not in wctx:
 path = checkunknowndirs(repo, wctx, f)
 if path is not None:
 pathconflicts.add(path)
-elif m == 'dg':
+elif m == ACTION_LOCAL_DIR_RENAME_GET:
 if _checkunknownfile(repo, wctx, mctx, f, args[0]):
 fileconflicts.add(f)
 
@@ -791,7 +814,7 @@
 collectconflicts(unknownconflicts, unknownconfig)
 else:
 for f, (m, args, msg) in actions.iteritems():
-if m == 'cm':
+if m == ACTION_CREATED_MERGE:
 fl2, anc = args
 different = _checkunknownfile(repo, wctx, mctx, f)
 if repo.dirstate._ignore(f):
@@ -812,16 +835,16 @@
 # don't like an abort happening in the middle of
 # merge.update.
 if not different:
-actions[f] = ('g', (fl2, False), "remote created")
+

D2702: commands: use constants for merge things

2018-03-24 Thread indygreg (Gregory Szorc)
This revision was automatically updated to reflect the committed changes.
Closed by commit rHG704932ef8913: commands: use constants for merge things 
(authored by indygreg, committed by ).

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D2702?vs=6971&id=7279

REVISION DETAIL
  https://phab.mercurial-scm.org/D2702

AFFECTED FILES
  mercurial/commands.py

CHANGE DETAILS

diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -4360,11 +4360,12 @@
 # as 'P'.  Resolved path conflicts show as 'R', the same as normal
 # resolved conflicts.
 mergestateinfo = {
-'u': ('resolve.unresolved', 'U'),
-'r': ('resolve.resolved', 'R'),
-'pu': ('resolve.unresolved', 'P'),
-'pr': ('resolve.resolved', 'R'),
-'d': ('resolve.driverresolved', 'D'),
+mergemod.MERGE_RECORD_UNRESOLVED: ('resolve.unresolved', 'U'),
+mergemod.MERGE_RECORD_RESOLVED: ('resolve.resolved', 'R'),
+mergemod.MERGE_RECORD_UNRESOLVED_PATH: ('resolve.unresolved', 'P'),
+mergemod.MERGE_RECORD_RESOLVED_PATH: ('resolve.resolved', 'R'),
+mergemod.MERGE_RECORD_DRIVER_RESOLVED: ('resolve.driverresolved',
+'D'),
 }
 
 for f in ms:
@@ -4387,7 +4388,8 @@
 
 wctx = repo[None]
 
-if ms.mergedriver and ms.mdstate() == 'u':
+if (ms.mergedriver
+and ms.mdstate() == mergemod.MERGE_DRIVER_STATE_UNMARKED):
 proceed = mergemod.driverpreprocess(repo, ms, wctx)
 ms.commit()
 # allow mark and unmark to go through
@@ -4408,7 +4410,7 @@
 
 # don't let driver-resolved files be marked, and run the conclude
 # step if asked to resolve
-if ms[f] == "d":
+if ms[f] == mergemod.MERGE_RECORD_DRIVER_RESOLVED:
 exact = m.exact(f)
 if mark:
 if exact:
@@ -4423,20 +4425,21 @@
 continue
 
 # path conflicts must be resolved manually
-if ms[f] in ("pu", "pr"):
+if ms[f] in (mergemod.MERGE_RECORD_UNRESOLVED_PATH,
+ mergemod.MERGE_RECORD_RESOLVED_PATH):
 if mark:
-ms.mark(f, "pr")
+ms.mark(f, mergemod.MERGE_RECORD_RESOLVED_PATH)
 elif unmark:
-ms.mark(f, "pu")
-elif ms[f] == "pu":
+ms.mark(f, mergemod.MERGE_RECORD_UNRESOLVED_PATH)
+elif ms[f] == mergemod.MERGE_RECORD_UNRESOLVED_PATH:
 ui.warn(_('%s: path conflict must be resolved manually\n')
 % f)
 continue
 
 if mark:
-ms.mark(f, "r")
+ms.mark(f, mergemod.MERGE_RECORD_RESOLVED)
 elif unmark:
-ms.mark(f, "u")
+ms.mark(f, mergemod.MERGE_RECORD_UNRESOLVED)
 else:
 # backup pre-resolve (merge uses .orig for its own purposes)
 a = repo.wjoin(f)



To: indygreg, #hg-reviewers, durin42
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D2700: merge: use constants for merge record state

2018-03-24 Thread indygreg (Gregory Szorc)
This revision was automatically updated to reflect the committed changes.
Closed by commit rHGaa5199c7aa42: merge: use constants for merge record state 
(authored by indygreg, committed by ).

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D2700?vs=6660&id=7277

REVISION DETAIL
  https://phab.mercurial-scm.org/D2700

AFFECTED FILES
  mercurial/merge.py

CHANGE DETAILS

diff --git a/mercurial/merge.py b/mercurial/merge.py
--- a/mercurial/merge.py
+++ b/mercurial/merge.py
@@ -65,6 +65,12 @@
 MERGE_DRIVER_STATE_MARKED = b'm'
 MERGE_DRIVER_STATE_SUCCESS = b's'
 
+MERGE_RECORD_UNRESOLVED = b'u'
+MERGE_RECORD_RESOLVED = b'r'
+MERGE_RECORD_UNRESOLVED_PATH = b'pu'
+MERGE_RECORD_RESOLVED_PATH = b'pr'
+MERGE_RECORD_DRIVER_RESOLVED = b'd'
+
 class mergestate(object):
 '''track 3-way merge state of individual files
 
@@ -391,11 +397,12 @@
 # to prevent older versions of Mercurial that do not support the 
feature
 # from loading them.
 for filename, v in self._state.iteritems():
-if v[0] == 'd':
+if v[0] == MERGE_RECORD_DRIVER_RESOLVED:
 # Driver-resolved merge. These are stored in 'D' records.
 records.append((RECORD_MERGE_DRIVER_MERGE,
 '\0'.join([filename] + v)))
-elif v[0] in ('pu', 'pr'):
+elif v[0] in (MERGE_RECORD_UNRESOLVED_PATH,
+  MERGE_RECORD_RESOLVED_PATH):
 # Path conflicts. These are stored in 'P' records.  The current
 # resolution state ('pu' or 'pr') is stored within the record.
 records.append((RECORD_PATH_CONFLICT,
@@ -467,7 +474,7 @@
 else:
 hash = hex(hashlib.sha1(fcl.path()).digest())
 self._repo.vfs.write('merge/' + hash, fcl.data())
-self._state[fd] = ['u', hash, fcl.path(),
+self._state[fd] = [MERGE_RECORD_UNRESOLVED, hash, fcl.path(),
fca.path(), hex(fca.filenode()),
fco.path(), hex(fco.filenode()),
fcl.flags()]
@@ -480,7 +487,7 @@
 frename: the filename the conflicting file was renamed to
 forigin: origin of the file ('l' or 'r' for local/remote)
 """
-self._state[path] = ['pu', frename, forigin]
+self._state[path] = [MERGE_RECORD_UNRESOLVED_PATH, frename, forigin]
 self._dirty = True
 
 def __contains__(self, dfile):
@@ -506,22 +513,24 @@
 """Obtain the paths of unresolved files."""
 
 for f, entry in self._state.iteritems():
-if entry[0] in ('u', 'pu'):
+if entry[0] in (MERGE_RECORD_UNRESOLVED,
+MERGE_RECORD_UNRESOLVED_PATH):
 yield f
 
 def driverresolved(self):
 """Obtain the paths of driver-resolved files."""
 
 for f, entry in self._state.items():
-if entry[0] == 'd':
+if entry[0] == MERGE_RECORD_DRIVER_RESOLVED:
 yield f
 
 def extras(self, filename):
 return self._stateextras.setdefault(filename, {})
 
 def _resolve(self, preresolve, dfile, wctx):
 """rerun merge process for file path `dfile`"""
-if self[dfile] in 'rd':
+if self[dfile] in (MERGE_RECORD_RESOLVED,
+   MERGE_RECORD_DRIVER_RESOLVED):
 return True, 0
 stateentry = self._state[dfile]
 state, hash, lfile, afile, anode, ofile, onode, flags = stateentry
@@ -571,7 +580,7 @@
 self._stateextras.pop(dfile, None)
 self._dirty = True
 elif not r:
-self.mark(dfile, 'r')
+self.mark(dfile, MERGE_RECORD_RESOLVED)
 
 if complete:
 action = None



To: indygreg, #hg-reviewers, durin42
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D2698: merge: use constants for merge state record types

2018-03-24 Thread indygreg (Gregory Szorc)
This revision was automatically updated to reflect the committed changes.
Closed by commit rHGa532b2f54f95: merge: use constants for merge state record 
types (authored by indygreg, committed by ).

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D2698?vs=6658&id=7275

REVISION DETAIL
  https://phab.mercurial-scm.org/D2698

AFFECTED FILES
  mercurial/merge.py

CHANGE DETAILS

diff --git a/mercurial/merge.py b/mercurial/merge.py
--- a/mercurial/merge.py
+++ b/mercurial/merge.py
@@ -47,6 +47,20 @@
 bits = bits[:-2] + bits[-1:]
 return '\0'.join(bits)
 
+# Merge state record types. See ``mergestate`` docs for more.
+RECORD_LOCAL = b'L'
+RECORD_OTHER = b'O'
+RECORD_MERGED = b'F'
+RECORD_CHANGEDELETE_CONFLICT = b'C'
+RECORD_MERGE_DRIVER_MERGE = b'D'
+RECORD_PATH_CONFLICT = b'P'
+RECORD_MERGE_DRIVER_STATE = b'm'
+RECORD_FILE_VALUES = b'f'
+RECORD_LABELS = b'l'
+RECORD_OVERRIDE = b't'
+RECORD_UNSUPPORTED_MANDATORY = b'X'
+RECORD_UNSUPPORTED_ADVISORY = b'x'
+
 class mergestate(object):
 '''track 3-way merge state of individual files
 
@@ -158,23 +172,24 @@
 unsupported = set()
 records = self._readrecords()
 for rtype, record in records:
-if rtype == 'L':
+if rtype == RECORD_LOCAL:
 self._local = bin(record)
-elif rtype == 'O':
+elif rtype == RECORD_OTHER:
 self._other = bin(record)
-elif rtype == 'm':
+elif rtype == RECORD_MERGE_DRIVER_STATE:
 bits = record.split('\0', 1)
 mdstate = bits[1]
 if len(mdstate) != 1 or mdstate not in 'ums':
 # the merge driver should be idempotent, so just rerun it
 mdstate = 'u'
 
 self._readmergedriver = bits[0]
 self._mdstate = mdstate
-elif rtype in 'FDCP':
+elif rtype in (RECORD_MERGED, RECORD_CHANGEDELETE_CONFLICT,
+   RECORD_PATH_CONFLICT, RECORD_MERGE_DRIVER_MERGE):
 bits = record.split('\0')
 self._state[bits[0]] = bits[1:]
-elif rtype == 'f':
+elif rtype == RECORD_FILE_VALUES:
 filename, rawextras = record.split('\0', 1)
 extraparts = rawextras.split('\0')
 extras = {}
@@ -184,7 +199,7 @@
 i += 2
 
 self._stateextras[filename] = extras
-elif rtype == 'l':
+elif rtype == RECORD_LABELS:
 labels = record.split('\0', 2)
 self._labels = [l for l in labels if len(l) > 0]
 elif not rtype.islower():
@@ -218,25 +233,25 @@
 # we have to infer the "other" changeset of the merge
 # we cannot do better than that with v1 of the format
 mctx = self._repo[None].parents()[-1]
-v1records.append(('O', mctx.hex()))
+v1records.append((RECORD_OTHER, mctx.hex()))
 # add place holder "other" file node information
 # nobody is using it yet so we do no need to fetch the data
 # if mctx was wrong `mctx[bits[-2]]` may fails.
 for idx, r in enumerate(v1records):
-if r[0] == 'F':
+if r[0] == RECORD_MERGED:
 bits = r[1].split('\0')
 bits.insert(-2, '')
 v1records[idx] = (r[0], '\0'.join(bits))
 return v1records
 
 def _v1v2match(self, v1records, v2records):
 oldv2 = set() # old format version of v2 record
 for rec in v2records:
-if rec[0] == 'L':
+if rec[0] == RECORD_LOCAL:
 oldv2.add(rec)
-elif rec[0] == 'F':
+elif rec[0] == RECORD_MERGED:
 # drop the onode data (not contained in v1)
-oldv2.add(('F', _droponode(rec[1])))
+oldv2.add((RECORD_MERGED, _droponode(rec[1])))
 for rec in v1records:
 if rec not in oldv2:
 return False
@@ -256,9 +271,9 @@
 f = self._repo.vfs(self.statepathv1)
 for i, l in enumerate(f):
 if i == 0:
-records.append(('L', l[:-1]))
+records.append((RECORD_LOCAL, l[:-1]))
 else:
-records.append(('F', l[:-1]))
+records.append((RECORD_MERGED, l[:-1]))
 f.close()
 except IOError as err:
 if err.errno != errno.ENOENT:
@@ -296,7 +311,7 @@
 off += 4
 record = data[off:(off + length)]
 off += length
-if rtype == 't':
+if rtype == RECORD_OVERRIDE:
 rtype, record = record[0:1], record[1:]
 records.append((rtype, record))
 f.close()
@@ -359,10 +374,10 @@
 
 def _makerecords(self):
  

D2692: merge: return an attrs class from update() and applyupdates()

2018-03-24 Thread indygreg (Gregory Szorc)
This revision was automatically updated to reflect the committed changes.
Closed by commit rHG71543b942eea: merge: return an attrs class from update() 
and applyupdates() (authored by indygreg, committed by ).

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D2692?vs=6969&id=7274

REVISION DETAIL
  https://phab.mercurial-scm.org/D2692

AFFECTED FILES
  mercurial/hg.py
  mercurial/merge.py

CHANGE DETAILS

diff --git a/mercurial/merge.py b/mercurial/merge.py
--- a/mercurial/merge.py
+++ b/mercurial/merge.py
@@ -22,6 +22,9 @@
 nullid,
 nullrev,
 )
+from .thirdparty import (
+attr,
+)
 from . import (
 copies,
 error,
@@ -1398,6 +1401,30 @@
 prefetch = scmutil.fileprefetchhooks
 prefetch(repo, ctx, [f for sublist in oplist for f, args, msg in sublist])
 
+@attr.s(frozen=True)
+class updateresult(object):
+updatedcount = attr.ib()
+mergedcount = attr.ib()
+removedcount = attr.ib()
+unresolvedcount = attr.ib()
+
+# TODO remove container emulation once consumers switch to new API.
+
+def __getitem__(self, x):
+if x == 0:
+return self.updatedcount
+elif x == 1:
+return self.mergedcount
+elif x == 2:
+return self.removedcount
+elif x == 3:
+return self.unresolvedcount
+else:
+raise IndexError('can only access items 0-3')
+
+def __len__(self):
+return 4
+
 def applyupdates(repo, actions, wctx, mctx, overwrite, labels=None):
 """apply the merge action list to the working directory
 
@@ -1581,7 +1608,8 @@
 if not proceed:
 # XXX setting unresolved to at least 1 is a hack to make sure we
 # error out
-return updated, merged, removed, max(len(unresolvedf), 1)
+return updateresult(updated, merged, removed,
+max(len(unresolvedf), 1))
 newactions = []
 for f, args, msg in mergeactions:
 if f in unresolvedf:
@@ -1656,8 +1684,7 @@
 actions['m'] = [a for a in actions['m'] if a[0] in mfiles]
 
 progress(_updating, None, total=numupdates, unit=_files)
-
-return updated, merged, removed, unresolved
+return updateresult(updated, merged, removed, unresolved)
 
 def recordupdates(repo, actions, branchmerge):
 "record merge actions to the dirstate"
@@ -1878,7 +1905,7 @@
 # call the hooks and exit early
 repo.hook('preupdate', throw=True, parent1=xp2, parent2='')
 repo.hook('update', parent1=xp2, parent2='', error=0)
-return 0, 0, 0, 0
+return updateresult(0, 0, 0, 0)
 
 if (updatecheck == 'linear' and
 pas not in ([p1], [p2])):  # nonlinear
diff --git a/mercurial/hg.py b/mercurial/hg.py
--- a/mercurial/hg.py
+++ b/mercurial/hg.py
@@ -752,7 +752,9 @@
 if quietempty and not any(stats):
 return
 repo.ui.status(_("%d files updated, %d files merged, "
- "%d files removed, %d files unresolved\n") % stats)
+ "%d files removed, %d files unresolved\n") % (
+   stats.updatedcount, stats.mergedcount,
+   stats.removedcount, stats.unresolvedcount))
 
 def updaterepo(repo, node, overwrite, updatecheck=None):
 """Update the working directory to node.



To: indygreg, #hg-reviewers, martinvonz, durin42
Cc: martinvonz, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D2699: merge: use constants for merge driver state

2018-03-24 Thread indygreg (Gregory Szorc)
This revision was automatically updated to reflect the committed changes.
Closed by commit rHG1b158ca37ea4: merge: use constants for merge driver state 
(authored by indygreg, committed by ).

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D2699?vs=6659&id=7276

REVISION DETAIL
  https://phab.mercurial-scm.org/D2699

AFFECTED FILES
  mercurial/merge.py

CHANGE DETAILS

diff --git a/mercurial/merge.py b/mercurial/merge.py
--- a/mercurial/merge.py
+++ b/mercurial/merge.py
@@ -61,6 +61,10 @@
 RECORD_UNSUPPORTED_MANDATORY = b'X'
 RECORD_UNSUPPORTED_ADVISORY = b'x'
 
+MERGE_DRIVER_STATE_UNMARKED = b'u'
+MERGE_DRIVER_STATE_MARKED = b'm'
+MERGE_DRIVER_STATE_SUCCESS = b's'
+
 class mergestate(object):
 '''track 3-way merge state of individual files
 
@@ -147,9 +151,9 @@
 self._other = other
 self._readmergedriver = None
 if self.mergedriver:
-self._mdstate = 's'
+self._mdstate = MERGE_DRIVER_STATE_SUCCESS
 else:
-self._mdstate = 'u'
+self._mdstate = MERGE_DRIVER_STATE_UNMARKED
 shutil.rmtree(self._repo.vfs.join('merge'), True)
 self._results = {}
 self._dirty = False
@@ -168,7 +172,7 @@
 if var in vars(self):
 delattr(self, var)
 self._readmergedriver = None
-self._mdstate = 's'
+self._mdstate = MERGE_DRIVER_STATE_SUCCESS
 unsupported = set()
 records = self._readrecords()
 for rtype, record in records:
@@ -179,9 +183,11 @@
 elif rtype == RECORD_MERGE_DRIVER_STATE:
 bits = record.split('\0', 1)
 mdstate = bits[1]
-if len(mdstate) != 1 or mdstate not in 'ums':
+if len(mdstate) != 1 or mdstate not in (
+MERGE_DRIVER_STATE_UNMARKED, MERGE_DRIVER_STATE_MARKED,
+MERGE_DRIVER_STATE_SUCCESS):
 # the merge driver should be idempotent, so just rerun it
-mdstate = 'u'
+mdstate = MERGE_DRIVER_STATE_UNMARKED
 
 self._readmergedriver = bits[0]
 self._mdstate = mdstate
@@ -1665,7 +1671,8 @@
 
 unresolved = ms.unresolvedcount()
 
-if usemergedriver and not unresolved and ms.mdstate() != 's':
+if (usemergedriver and not unresolved
+and ms.mdstate() != MERGE_DRIVER_STATE_SUCCESS):
 if not driverconclude(repo, ms, wctx, labels=labels):
 # XXX setting unresolved to at least 1 is a hack to make sure we
 # error out



To: indygreg, #hg-reviewers, durin42
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D2693: histedit: always define update results

2018-03-24 Thread indygreg (Gregory Szorc)
This revision was automatically updated to reflect the committed changes.
indygreg marked an inline comment as done.
Closed by commit rHG0351fb0153ba: histedit: always define update results 
(authored by indygreg, committed by ).

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D2693?vs=6653&id=7273

REVISION DETAIL
  https://phab.mercurial-scm.org/D2693

AFFECTED FILES
  hgext/histedit.py

CHANGE DETAILS

diff --git a/hgext/histedit.py b/hgext/histedit.py
--- a/hgext/histedit.py
+++ b/hgext/histedit.py
@@ -566,7 +566,7 @@
 # edits are "in place" we do not need to make any merge,
 # just applies changes on parent for editing
 cmdutil.revert(ui, repo, ctx, (wcpar, node.nullid), all=True)
-stats = None
+stats = mergemod.updateresult(0, 0, 0, 0)
 else:
 try:
 # ui.forcemerge is an internal variable, do not document



To: indygreg, durin42, #hg-reviewers, martinvonz
Cc: martinvonz, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D2394: histedit: make histedit's commands accept revsets (issue5746)

2018-03-24 Thread sangeet259 (Sangeet Kumar Mishra)
This revision was automatically updated to reflect the committed changes.
Closed by commit rHG3d3cff1f6bde: histedit: make histedit's commands 
accept revsets (issue5746) (authored by sangeet259, committed by ).

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D2394?vs=6324&id=7272

REVISION DETAIL
  https://phab.mercurial-scm.org/D2394

AFFECTED FILES
  hgext/histedit.py
  tests/test-histedit-arguments.t

CHANGE DETAILS

diff --git a/tests/test-histedit-arguments.t b/tests/test-histedit-arguments.t
--- a/tests/test-histedit-arguments.t
+++ b/tests/test-histedit-arguments.t
@@ -236,10 +236,10 @@
 
   $ HGEDITOR=cat hg histedit "tip^^" --commands - << EOF
   > pick eb57da33312f 2 three
-  > pick 0
+  > pick 0u98
   > pick 08d98a8350f3 4 five
   > EOF
-  hg: parse error: invalid changeset 0
+  hg: parse error: invalid changeset 0u98
   [255]
 
 Test short version of command
@@ -552,3 +552,39 @@
   #
 
   $ cd ..
+
+Check that histedit's commands accept revsets
+  $ hg init bar
+  $ cd bar
+  $ echo w >> a
+  $ hg ci -qAm "adds a"
+  $ echo x >> b
+  $ hg ci -qAm "adds b"
+  $ echo y >> c
+  $ hg ci -qAm "adds c"
+  $ echo z >> d
+  $ hg ci -qAm "adds d"
+  $ hg log -G -T '{rev} {desc}\n'
+  @  3 adds d
+  |
+  o  2 adds c
+  |
+  o  1 adds b
+  |
+  o  0 adds a
+  
+  $ HGEDITOR=cat hg histedit "2" --commands - << EOF
+  > base -4 adds c
+  > pick 2 adds c
+  > pick tip adds d
+  > EOF
+  $ hg log -G -T '{rev} {desc}\n'
+  @  5 adds d
+  |
+  o  4 adds c
+  |
+  | o  1 adds b
+  |/
+  o  0 adds a
+  
+
diff --git a/hgext/histedit.py b/hgext/histedit.py
--- a/hgext/histedit.py
+++ b/hgext/histedit.py
@@ -425,11 +425,18 @@
 def fromrule(cls, state, rule):
 """Parses the given rule, returning an instance of the histeditaction.
 """
-rulehash = rule.strip().split(' ', 1)[0]
+ruleid = rule.strip().split(' ', 1)[0]
+# ruleid can be anything from rev numbers, hashes, "bookmarks" etc
+# Check for validation of rule ids and get the rulehash
 try:
-rev = node.bin(rulehash)
+rev = node.bin(ruleid)
 except TypeError:
-raise error.ParseError("invalid changeset %s" % rulehash)
+try:
+_ctx = scmutil.revsingle(state.repo, ruleid)
+rulehash = _ctx.hex()
+rev = node.bin(rulehash)
+except error.RepoLookupError:
+raise error.ParseError("invalid changeset %s" % ruleid)
 return cls(state, rev)
 
 def verify(self, prev, expected, seen):



To: sangeet259, durin42, #hg-reviewers
Cc: pulkit, tom.prince, krbullock, rishabhmadan96, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D2394: histedit: make histedit's commands accept revsets (issue5746)

2018-03-24 Thread durin42 (Augie Fackler)
durin42 accepted this revision.
durin42 added a comment.
This revision is now accepted and ready to land.


  queued, many thanks

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D2394

To: sangeet259, durin42, #hg-reviewers
Cc: pulkit, tom.prince, krbullock, rishabhmadan96, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D2939: fsmonitor: layer on another hack in bser.c for os.stat() compat (issue5811)

2018-03-24 Thread durin42 (Augie Fackler)
durin42 updated this revision to Diff 7271.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D2939?vs=7270&id=7271

REVISION DETAIL
  https://phab.mercurial-scm.org/D2939

AFFECTED FILES
  hgext/fsmonitor/pywatchman/bser.c

CHANGE DETAILS

diff --git a/hgext/fsmonitor/pywatchman/bser.c 
b/hgext/fsmonitor/pywatchman/bser.c
--- a/hgext/fsmonitor/pywatchman/bser.c
+++ b/hgext/fsmonitor/pywatchman/bser.c
@@ -96,9 +96,21 @@
   return PySequence_Length(obj->keys);
 }
 
+// Prototype for this function so we can use it before its definition.
+static PyObject* bserobj_getattrro(PyObject* o, PyObject* name);
+
 static PyObject* bserobj_tuple_item(PyObject* o, Py_ssize_t i) {
   bserObject* obj = (bserObject*)o;
 
+  if (i == 8 && PySequence_Size(obj->values) < 7) {
+// Hack alert: Python 3 removed support for os.stat().st_mtime
+// being an integer.Instead, if you need an integer, you have to
+// use os.stat()[stat.ST_MTIME] instead. stat.ST_MTIME is 8, and
+// our stat tuples are shorter than that, so we can detect
+// requests for index 8 on tuples shorter than that and return
+// st_mtime instead.
+return bserobj_getattrro(o, PyBytes_FromString("st_mtime"));
+  }
   return PySequence_GetItem(obj->values, i);
 }
 



To: durin42, #hg-reviewers
Cc: indygreg, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D2939: fsmonitor: layer on another hack in bser.c for os.stat() compat (issue5811)

2018-03-24 Thread durin42 (Augie Fackler)
durin42 added a subscriber: indygreg.
durin42 added a comment.


  @indygreg I think you saw this failure mode, I'd appreciate it if you could 
check if this fixes the watchman failures I introduced (I don't use watchman, 
and so I'm not quite sure how to reproduce.)

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D2939

To: durin42, #hg-reviewers
Cc: indygreg, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D2939: fsmonitor: layer on another hack in bser.c for os.stat() compat (issue5811)

2018-03-24 Thread durin42 (Augie Fackler)
durin42 created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  It's unclear to me how these `bserobj_tuple` objects are used, other
  than as stat objects. This should fix fsmonitor in the wake of
  https://phab.mercurial-scm.org/rHGffa3026d41964b2d06358c4f21f7e722264d1b3f 
and similar changes.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D2939

AFFECTED FILES
  hgext/fsmonitor/pywatchman/bser.c

CHANGE DETAILS

diff --git a/hgext/fsmonitor/pywatchman/bser.c 
b/hgext/fsmonitor/pywatchman/bser.c
--- a/hgext/fsmonitor/pywatchman/bser.c
+++ b/hgext/fsmonitor/pywatchman/bser.c
@@ -99,6 +99,15 @@
 static PyObject* bserobj_tuple_item(PyObject* o, Py_ssize_t i) {
   bserObject* obj = (bserObject*)o;
 
+  if (i == 8 && PySequence_Size(obj->values) < 7) {
+// Hack alert: Python 3 removed support for os.stat().st_mtime
+// being an integer.Instead, if you need an integer, you have to
+// use os.stat()[stat.ST_MTIME] instead. stat.ST_MTIME is 8, and
+// our stat tuples are shorter than that, so we can detect
+// requests for index 8 on tuples shorter than that and return
+// st_mtime instead.
+return bserobj_getattrro(o, "st_mtime");
+  }
   return PySequence_GetItem(obj->values, i);
 }
 



To: durin42, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D2694: merge: deprecate accessing update results by index

2018-03-24 Thread indygreg (Gregory Szorc)
indygreg updated this revision to Diff 7269.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D2694?vs=6970&id=7269

REVISION DETAIL
  https://phab.mercurial-scm.org/D2694

AFFECTED FILES
  hgext/histedit.py
  hgext/rebase.py
  mercurial/commands.py
  mercurial/hg.py
  mercurial/merge.py

CHANGE DETAILS

diff --git a/mercurial/merge.py b/mercurial/merge.py
--- a/mercurial/merge.py
+++ b/mercurial/merge.py
@@ -1408,9 +1408,15 @@
 removedcount = attr.ib()
 unresolvedcount = attr.ib()
 
+def isempty(self):
+return (not self.updatedcount and not self.mergedcount
+and not self.removedcount and not self.unresolvedcount)
+
 # TODO remove container emulation once consumers switch to new API.
 
 def __getitem__(self, x):
+util.nouideprecwarn('access merge.update() results by name instead of '
+'index', '4.6', 2)
 if x == 0:
 return self.updatedcount
 elif x == 1:
@@ -1423,6 +1429,8 @@
 raise IndexError('can only access items 0-3')
 
 def __len__(self):
+util.nouideprecwarn('access merge.update() results by name instead of '
+'index', '4.6', 2)
 return 4
 
 def applyupdates(repo, actions, wctx, mctx, overwrite, labels=None):
@@ -2070,7 +2078,8 @@
 sparse.prunetemporaryincludes(repo)
 
 if not partial:
-repo.hook('update', parent1=xp1, parent2=xp2, error=stats[3])
+repo.hook('update', parent1=xp1, parent2=xp2,
+  error=stats.unresolvedcount)
 return stats
 
 def graft(repo, ctx, pctx, labels, keepparent=False):
diff --git a/mercurial/hg.py b/mercurial/hg.py
--- a/mercurial/hg.py
+++ b/mercurial/hg.py
@@ -749,7 +749,7 @@
 return srcpeer, destpeer
 
 def _showstats(repo, stats, quietempty=False):
-if quietempty and not any(stats):
+if quietempty and stats.isempty():
 return
 repo.ui.status(_("%d files updated, %d files merged, "
  "%d files removed, %d files unresolved\n") % (
@@ -770,9 +770,9 @@
 """update the working directory to node"""
 stats = updaterepo(repo, node, False, updatecheck=updatecheck)
 _showstats(repo, stats, quietempty)
-if stats[3]:
+if stats.unresolvedcount:
 repo.ui.status(_("use 'hg resolve' to retry unresolved file merges\n"))
-return stats[3] > 0
+return stats.unresolvedcount > 0
 
 # naming conflict in clone()
 _update = update
@@ -783,7 +783,7 @@
 repo.vfs.unlinkpath('graftstate', ignoremissing=True)
 if show_stats:
 _showstats(repo, stats, quietempty)
-return stats[3] > 0
+return stats.unresolvedcount > 0
 
 # naming conflict in updatetotally()
 _clean = clean
@@ -882,12 +882,12 @@
 labels=labels)
 
 _showstats(repo, stats)
-if stats[3]:
+if stats.unresolvedcount:
 repo.ui.status(_("use 'hg resolve' to retry unresolved file merges "
  "or 'hg merge --abort' to abandon\n"))
 elif remind and not abort:
 repo.ui.status(_("(branch merge, don't forget to commit)\n"))
-return stats[3] > 0
+return stats.unresolvedcount > 0
 
 def _incoming(displaychlist, subreporecurse, ui, repo, source,
 opts, buffered=False):
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -628,7 +628,7 @@
 repo.setparents(op1, op2)
 dsguard.close()
 hg._showstats(repo, stats)
-if stats[3]:
+if stats.unresolvedcount:
 repo.ui.status(_("use 'hg resolve' to retry unresolved "
  "file merges\n"))
 return 1
@@ -2310,7 +2310,7 @@
 finally:
 repo.ui.setconfig('ui', 'forcemerge', '', 'graft')
 # report any conflicts
-if stats[3] > 0:
+if stats.unresolvedcount > 0:
 # write out state for --continue
 nodelines = [repo[rev].hex() + "\n" for rev in revs[pos:]]
 repo.vfs.write('graftstate', ''.join(nodelines))
diff --git a/hgext/rebase.py b/hgext/rebase.py
--- a/hgext/rebase.py
+++ b/hgext/rebase.py
@@ -525,7 +525,7 @@
 with ui.configoverride(overrides, 'rebase'):
 stats = rebasenode(repo, rev, p1, base, self.collapsef,
dest, wctx=self.wctx)
-if stats[3] > 0:
+if stats.unresolvedcount > 0:
 if self.inmemory:
 raise error.InMemoryMergeConflictsError()
 else:
diff --git a/hgext/histedit.py b/hgext/histedit.py
--- a/hgext/histedit.py
+++ b/hgext/histedit.py
@@ -492,7 +492,7 @@
 hg.update(repo, self.state.parentctxnode, quietempty=True)
 stats = applychanges(repo.ui, repo, rulectx, {})
 

Re: [PATCH] context: skip path conflicts by default when clearing unknown file (issue5776)

2018-03-24 Thread Augie Fackler
On Sat, Mar 24, 2018 at 01:25:14PM -0400, Matt Harbison wrote:
> # HG changeset patch
> # User Matt Harbison 
> # Date 1521869450 14400
> #  Sat Mar 24 01:30:50 2018 -0400
> # Node ID 7624b67b6d7512f283e9e589f5c36fe3e7e4bb16
> # Parent  a61fff493d9888935a1ff5e48bb823499f47e832
> context: skip path conflicts by default when clearing unknown file (issue5776)

queued, thanks

Many many thanks for continuing this work on Windows. I'm excited to
have that buildbot green!
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D2693: histedit: always define update results

2018-03-24 Thread indygreg (Gregory Szorc)
indygreg marked an inline comment as done.
indygreg added inline comments.

INLINE COMMENTS

> martinvonz wrote in histedit.py:492
> remove the "stats and" now?

This is done in the next commit :)

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D2693

To: indygreg, durin42, #hg-reviewers, martinvonz
Cc: martinvonz, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH] context: skip path conflicts by default when clearing unknown file (issue5776)

2018-03-24 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1521869450 14400
#  Sat Mar 24 01:30:50 2018 -0400
# Node ID 7624b67b6d7512f283e9e589f5c36fe3e7e4bb16
# Parent  a61fff493d9888935a1ff5e48bb823499f47e832
context: skip path conflicts by default when clearing unknown file (issue5776)

Prior to adding path conflict checking in 989e884d1be9, the test-audit-path.t
tests failed as shown here (but it was globbed away).  989e884d1be9 made it fail
with a message about the destination manifest containing a conflict (though the
no-symlink case wasn't updated).  When the path conflict checking was gated
behind an experimental config in 2a774cae3a03^::2a774cae3a03, the update started
erroneously succeeding here.  It turns out that the child of 989e884d1be9 is the
origin of this change when path conflict checking is disabled, as shown by
grafting the experimental config range on top of it.

What's happening here is merge.batchget() is writing the symlink 'back' to wdir
(but as a regular file for the no-symlink case), and then tries to write
'back/test', but calls wctx['back/test'].clearunknown() first.  The code that's
gated here was removing the newly written 'back' file, allowing 'back/test' to
succeed.  I tried checking for the dir components of 'back/test' in dirstate,
and skipping removal if present.  But that didn't work because the dirstate
isn't updated after each file is written out.

This is the last persistent test failure on Windows, so the testbot should start
turning green now. \o/

diff --git a/mercurial/context.py b/mercurial/context.py
--- a/mercurial/context.py
+++ b/mercurial/context.py
@@ -1808,10 +1808,11 @@ class workingfilectx(committablefilectx)
 wvfs.audit(f)
 if wvfs.isdir(f) and not wvfs.islink(f):
 wvfs.rmtree(f, forcibly=True)
-for p in reversed(list(util.finddirs(f))):
-if wvfs.isfileorlink(p):
-wvfs.unlink(p)
-break
+if self._repo.ui.configbool('experimental', 
'merge.checkpathconflicts'):
+for p in reversed(list(util.finddirs(f))):
+if wvfs.isfileorlink(p):
+wvfs.unlink(p)
+break
 
 def setflags(self, l, x):
 self._repo.wvfs.setflags(self._path, l, x)
diff --git a/tests/test-audit-path.t b/tests/test-audit-path.t
--- a/tests/test-audit-path.t
+++ b/tests/test-audit-path.t
@@ -109,8 +109,7 @@ attack back/test where back symlinks to 
 #else
 ('back' will be a file and cause some other system specific error)
   $ hg update -Cr2
-  back: is both a file and a directory
-  abort: * (glob)
+  abort: $TESTTMP/target/back/test: $ENOTDIR$
   [255]
 #endif
 
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D1944: wireproto: provide accessors for client capabilities

2018-03-24 Thread joerg.sonnenberger (Joerg Sonnenberger)
joerg.sonnenberger updated this revision to Diff 7268.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D1944?vs=5011&id=7268

REVISION DETAIL
  https://phab.mercurial-scm.org/D1944

AFFECTED FILES
  mercurial/help/internals/wireprotocol.txt
  mercurial/sshpeer.py
  mercurial/wireproto.py
  mercurial/wireprotoserver.py
  mercurial/wireprototypes.py
  tests/test-debugcommands.t
  tests/test-ssh-bundle1.t
  tests/test-ssh-proto-unbundle.t
  tests/test-ssh-proto.t
  tests/test-ssh.t

CHANGE DETAILS

diff --git a/tests/test-ssh.t b/tests/test-ssh.t
--- a/tests/test-ssh.t
+++ b/tests/test-ssh.t
@@ -496,10 +496,13 @@
   devel-peer-request: between
   devel-peer-request:   pairs: 81 bytes
   sending between command
-  remote: 403 (sshv1 !)
+  remote: 413 (sshv1 !)
   protocol upgraded to exp-ssh-v2-0001 (sshv2 !)
-  remote: capabilities: lookup branchmap pushkey known getbundle unbundlehash 
changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ 
unbundle=HG10GZ,HG10BZ,HG10UN batch
+  remote: capabilities: lookup branchmap pushkey known getbundle unbundlehash 
protocaps changegroupsubset streamreqs=generaldelta,revlogv1 
$USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN batch
   remote: 1 (sshv1 !)
+  devel-peer-request: protocaps
+  devel-peer-request:   caps: * bytes (glob)
+  sending protocaps command
   query 1; heads
   devel-peer-request: batched-content
   devel-peer-request:- heads (0 arguments)
diff --git a/tests/test-ssh-proto.t b/tests/test-ssh-proto.t
--- a/tests/test-ssh-proto.t
+++ b/tests/test-ssh-proto.t
@@ -63,9 +63,12 @@
   devel-peer-request: between
   devel-peer-request:   pairs: 81 bytes
   sending between command
-  remote: 403
-  remote: capabilities: lookup branchmap pushkey known getbundle unbundlehash 
changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ 
unbundle=HG10GZ,HG10BZ,HG10UN batch
+  remote: 413
+  remote: capabilities: lookup branchmap pushkey known getbundle unbundlehash 
protocaps changegroupsubset streamreqs=generaldelta,revlogv1 
$USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN batch
   remote: 1
+  devel-peer-request: protocaps
+  devel-peer-request:   caps: * bytes (glob)
+  sending protocaps command
   url: ssh://user@dummy/server
   local: no
   pushable: yes
@@ -82,43 +85,43 @@
   i> write(6) -> 6:
   i> hello\n
   o> readline() -> 4:
-  o> 403\n
-  o> readline() -> 403:
-  o> capabilities: lookup branchmap pushkey known getbundle unbundlehash 
changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ 
unbundle=HG10GZ,HG10BZ,HG10UN batch\n
+  o> 413\n
+  o> readline() -> 413:
+  o> capabilities: lookup branchmap pushkey known getbundle unbundlehash 
protocaps changegroupsubset streamreqs=generaldelta,revlogv1 
$USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN batch\n
 
 `hg debugserve --sshstdio` works
 
   $ cd server
   $ hg debugserve --sshstdio << EOF
   > hello
   > EOF
-  403
-  capabilities: lookup branchmap pushkey known getbundle unbundlehash 
changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ 
unbundle=HG10GZ,HG10BZ,HG10UN batch
+  413
+  capabilities: lookup branchmap pushkey known getbundle unbundlehash 
protocaps changegroupsubset streamreqs=generaldelta,revlogv1 
$USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN batch
 
 I/O logging works
 
   $ hg debugserve --sshstdio --logiofd 1 << EOF
   > hello
   > EOF
   o> write(4) -> 4:
-  o> 403\n
-  o> write(403) -> 403:
-  o> capabilities: lookup branchmap pushkey known getbundle unbundlehash 
changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ 
unbundle=HG10GZ,HG10BZ,HG10UN batch\n
-  403
-  capabilities: lookup branchmap pushkey known getbundle unbundlehash 
changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ 
unbundle=HG10GZ,HG10BZ,HG10UN batch
+  o> 413\n
+  o> write(413) -> 413:
+  o> capabilities: lookup branchmap pushkey known getbundle unbundlehash 
protocaps changegroupsubset streamreqs=generaldelta,revlogv1 
$USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN batch\n
+  413
+  capabilities: lookup branchmap pushkey known getbundle unbundlehash 
protocaps changegroupsubset streamreqs=generaldelta,revlogv1 
$USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN batch
   o> flush() -> None
 
   $ hg debugserve --sshstdio --logiofile $TESTTMP/io << EOF
   > hello
   > EOF
-  403
-  capabilities: lookup branchmap pushkey known getbundle unbundlehash 
changegroupsubset streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ 
unbundle=HG10GZ,HG10BZ,HG10UN batch
+  413
+  capabilities: lookup branchmap pushkey known getbundle unbundlehash 
protocaps changegroupsubset streamreqs=generaldelta,revlogv1 
$USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN batch
 
   $ cat $TESTTMP/io
   o> write(4) -> 4:
-  o> 403\n
-  o> writ

D2752: cbor: add a __init__.py to top level cbor module

2018-03-24 Thread martinvonz (Martin von Zweigbergk)
martinvonz added a comment.


  In https://phab.mercurial-scm.org/D2752#45926, @pulkit wrote:
  
  > In https://phab.mercurial-scm.org/D2752#44289, @indygreg wrote:
  >
  > > I think you should send the relative import patches to upstream. Adding 
`from __future__ import absolute_import` would also be a nice touch.
  >
  >
  > I tried that at https://github.com/agronholm/cbor2/pull/20.  I might be 
doing something wrong here but I am not sure what's that.
  
  
  The relative imports are now done: 
https://github.com/agronholm/cbor2/commit/84181540f6eb650437e3f73cd104a65661fe8e67

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D2752

To: pulkit, #hg-reviewers
Cc: martinvonz, alex_gaynor, indygreg, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D2750: thirdparty: start vendoring cbor python library

2018-03-24 Thread martinvonz (Martin von Zweigbergk)
martinvonz added a comment.


  Seems like a good idea to me. I had missed this series, but I just started 
thinking about having a state file for undo state and was not looking forward 
to coming up with another on-disk format.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D2750

To: pulkit, #hg-reviewers
Cc: martinvonz, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


mercurial@37055: 4 new changesets

2018-03-24 Thread Mercurial Commits
4 new changesets in mercurial:

https://www.mercurial-scm.org/repo/hg/rev/8c3c47362934
changeset:   37052:8c3c47362934
user:Gregory Szorc 
date:Wed Mar 14 15:25:06 2018 -0700
summary: wireproto: implement basic frame reading and processing

https://www.mercurial-scm.org/repo/hg/rev/cd0ca979a8b8
changeset:   37053:cd0ca979a8b8
user:Gregory Szorc 
date:Wed Mar 14 08:18:15 2018 -0700
summary: wireproto: nominally don't expose "batch" to version 2 wire 
transports

https://www.mercurial-scm.org/repo/hg/rev/e7a012b60d6e
changeset:   37054:e7a012b60d6e
user:Gregory Szorc 
date:Wed Mar 14 13:32:31 2018 -0700
summary: wireproto: implement basic command dispatching for HTTPv2

https://www.mercurial-scm.org/repo/hg/rev/61393f888dfe
changeset:   37055:61393f888dfe
bookmark:@
tag: tip
user:Gregory Szorc 
date:Wed Mar 14 13:57:52 2018 -0700
summary: wireproto: define and implement responses in framing protocol

-- 
Repository URL: https://www.mercurial-scm.org/repo/hg
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D2852: wireproto: implement basic frame reading and processing

2018-03-24 Thread yuja (Yuya Nishihara)
yuja added inline comments.

INLINE COMMENTS

> util.py:2569
> +res = self.read(len(b))
> +if res is None:
> +return None

I think read() never returns None.

> wireprotoserver.py:402
> +action, meta = reactor.onframerecv(frametype, frameflags, payload)
> +states.append(json.dumps((action, meta), sort_keys=True,
> + separators=(', ', ': ')))

This wouldn't work on Python 3 because JSON requires unicode.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D2852

To: indygreg, #hg-reviewers, durin42
Cc: yuja, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


mercurial@37051: 2 new changesets

2018-03-24 Thread Mercurial Commits
2 new changesets in mercurial:

https://www.mercurial-scm.org/repo/hg/rev/37d7a1d18b97
changeset:   37050:37d7a1d18b97
user:Gregory Szorc 
date:Tue Mar 13 19:44:59 2018 -0700
summary: wireproto: define content negotiation for HTTPv2

https://www.mercurial-scm.org/repo/hg/rev/40206e227412
changeset:   37051:40206e227412
bookmark:@
tag: tip
user:Gregory Szorc 
date:Mon Mar 19 16:49:53 2018 -0700
summary: wireproto: define and implement protocol for issuing requests

-- 
Repository URL: https://www.mercurial-scm.org/repo/hg
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D2851: wireproto: define and implement protocol for issuing requests

2018-03-24 Thread yuja (Yuya Nishihara)
yuja added inline comments.

INLINE COMMENTS

> wireprotocol.txt:486
> ++---+
> +| Flags (4) |
> ++===+===|

Nit: The order of Type and Flags seems a bit confusing. I read it as
`flags << 4 | type` since this is a little-endian (so naturally LSB-first) 
protocol.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D2851

To: indygreg, #hg-reviewers, durin42
Cc: yuja, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D2850: wireproto: define content negotiation for HTTPv2

2018-03-24 Thread yuja (Yuya Nishihara)
yuja added a comment.


  We might have to handle multiple `Accept` headers correctly, if a proxy
  server MAY modify them. I don't know if that could happen, though.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D2850

To: indygreg, #hg-reviewers, durin42
Cc: yuja, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D2938: grep: make grep search on working directory by default

2018-03-24 Thread av6 (Anton Shestakov)
av6 added inline comments.

INLINE COMMENTS

> commands.py:2485
> +fm.data(node=fm.hexfunc(scmutil.binnode(ctx)))
> +if not bool(opts.get('all')) and not bool(opts.get('rev')):
> +cols = [

This line looks identical to the one later on, with Pulkit's comment about 
usage of bool().

> commands.py:2487-2490
>  ('filename', fn, True),
> -('rev', rev, True),
> +('rev', rev, False),
>  ('linenumber', l.linenum, opts.get('line_number')),
>  ]

This block is not indented enough, but see my other comment below.

> commands.py:2494
> +('filename', fn, True),
> +('rev', rev, True),
> +('linenumber', l.linenum, opts.get('line_number')),

Since the difference in both branches for this if-else block seems to be only 
in this line, and just one value, it probably makes sense to store said value 
in a variable and use it in place of False/True and reduce duplication.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D2938

To: sangeet259, #hg-reviewers
Cc: av6, yuja, pulkit, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH] url: make logginghttphandler compatible with Python 2.7.6

2018-03-24 Thread Pulkit Goyal
On Sat, Mar 24, 2018 at 9:39 AM, Yuya Nishihara  wrote:
> # HG changeset patch
> # User Yuya Nishihara 
> # Date 1521864147 -32400
> #  Sat Mar 24 13:02:27 2018 +0900
> # Node ID f40b6e7fc011715b209774c0d1fbc5b8a6694401
> # Parent  db114320df7ee744047fe9a92a01afc40f9d0e87
> url: make logginghttphandler compatible with Python 2.7.6
>
> There wasn't a usable hook point in httplib, so we have to replace connect()
> to wrap the socket before self._tunnel().

Queued this. Many thanks!
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D2938: grep: make grep search on working directory by default

2018-03-24 Thread yuja (Yuya Nishihara)
yuja added inline comments.

INLINE COMMENTS

> commands.py:2474
> +return util.binary(flog.read(ctx.filenode(fn)))
> +except AttributeError:
> +return util.binary(ctx.filectx(fn).data())

Better to test if ctx is a workingctx (i.e. `ctx.rev() is None`).

Another idea is to make `wctx.filenode()` return wdirid and catch
WdirUnsupported exception
to fall back to the slow path.

> commands.py:2475
> +except AttributeError:
> +return util.binary(ctx.filectx(fn).data())
>  

Nit: `fctx.isbinary()` is preferred.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D2938

To: sangeet259, #hg-reviewers
Cc: yuja, pulkit, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 1 of 5] rcutil: directly call win32.executablepath()

2018-03-24 Thread Pulkit Goyal
On Sat, Mar 24, 2018 at 3:23 PM, Yuya Nishihara  wrote:
> # HG changeset patch
> # User Yuya Nishihara 
> # Date 1521865850 -32400
> #  Sat Mar 24 13:30:50 2018 +0900
> # Node ID 9bfb1ec8fb375630cfca0e42b17676e1892bd90a
> # Parent  3f765e4cbf4c1e53e0fd88992c079b321749d837
> rcutil: directly call win32.executablepath()
>
> Since it isn't supported on POSIX platform, we don't need to double the
> compatibility layers.

Looks good to me. Queued the series. Many thanks!
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH] directaccess: do not abort by 'ff...' hash

2018-03-24 Thread Pulkit Goyal
On Sat, Mar 24, 2018 at 3:18 PM, Yuya Nishihara  wrote:
> # HG changeset patch
> # User Yuya Nishihara 
> # Date 1521879572 -32400
> #  Sat Mar 24 17:19:32 2018 +0900
> # Node ID 3f765e4cbf4c1e53e0fd88992c079b321749d837
> # Parent  f40b6e7fc011715b209774c0d1fbc5b8a6694401
> directaccess: do not abort by 'ff...' hash
>
> Since the 'ff...' hash should never be hidden, we can just ignore it.

Queued this. Many thanks!
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D2057: rust implementation of hg status

2018-03-24 Thread kevincox (Kevin Cox)
kevincox added a comment.


  The latest changes are looking really good. I have a couple more comments but 
I didn't have time for a full review. I'll try to get more reviewed tomorrow. 
It seems that you still have a lot of stuff still in-flight so I'll try to 
slowly review the changes as I have time. If you want input/feedback on any 
particular part just ask and I will prioritize it.
  
  This change is very large so it might be worth splitting off a smaller 
component and getting that submitted first. However I do realize that for 
starting out it is often helpful to get some actual use cases implemented 
before committing the base structures.

INLINE COMMENTS

> Ivzhh wrote in base85.rs:23
> This crate is my previous try to integrate rust into hg. Right now I guess 
> mine main pursue is to add hg r-* commands for rust. I will follow your 
> suggestion when I am implementing the wire protocol and reuse the code for 
> pure rust crate.

I get that, but I still think it makes the code easier to read when the 
python-interop and the logic as separated where it is easy to do so.

> Ivzhh wrote in base85.rs:91
> when I removed the unsafe, I got error: error[E0133]: use of mutable static 
> requires unsafe function or block

I meant safe not as it it didn't need the unsafe keyword, but in that the use 
of the `unsafe` block is safe.

It should really be called the `trust_me,_I_know_this_is_safe` block. But since 
you are not getting the compiler checking it is often useful to add a comment 
why the action you are performing is correct. In this case it is correct 
because the caller initializes this variable before the function is called.

> base85.rs:105
> +}
> +};
> +

If this computation only depends on `len` it would be nice to put it in a 
helper function.

> main.rs:260
> +let res = repo.status();
> +for f in res.modified.iter() {
> +println!("M {}", f.to_str().unwrap());

These are `HashSet`'s which don't have a defined iterator order. IIRC the 
python implementation sorts the results which is probably desirable.

> config.rs:50
> +pub revlog_format: RevlogFormat,
> +/// where to get delta base, please refer to wiki page
> +pub delta: DeltaPolicy,

A link to the mentioned wiki page would be very helpful to readers.

> Ivzhh wrote in dirstate.rs:170
> I kind of get borrow check compile error here. Later I use Occupied() when 
> possible.

Sorry, I misunderstood the logic. You can do this:

  diff -r ccc683587fdb rust/hgstorage/src/dirstate.rs
  --- a/rust/hgstorage/src/dirstate.rs  Sat Mar 24 10:05:53 2018 +
  +++ b/rust/hgstorage/src/dirstate.rs  Sat Mar 24 10:14:58 2018 +
  @@ -184,8 +184,7 @@
   continue;
   }
   
  -if self.dir_state_map.contains_key(rel_path) {
  -let dir_entry = &self.dir_state_map[rel_path];
  +if let Some(dir_entry) = 
self.dir_state_map.get(rel_path) {
   files_not_in_walkdir.remove(rel_path);
   DirState::check_status(&mut res, abs_path, rel_path, 
dir_entry);
   } else if 
!matcher.check_path_ignored(rel_path.to_str().unwrap()) {

> dirstate.rs:103
> +if let Ok(meta_data) = meta_data {
> +let mtime = meta_data.modified().expect("default mtime must 
> exist");
> +

Switch the return type to `std::io::Result` and then you can have

  let metadata = p.metadata()?;
  let mtime = metadata.modified()?;
  // ...

> dirstate.rs:263
> +.unwrap()
> +.as_secs() != dir_entry.mtime as u64
> +{

Does it make sense to make `DirStateEntry.mtime` be a `std::time::SystemTime` 
and convert upon reading the structure in?

If not I would prefer doing the conversion here:

  else if mtd.modified().unwrap() == UNIX_EPOCH + 
Duration::from_secs(dir_entry.mtime as u64) {

(Maybe extract the system time to higher up, or even a helper function on 
dir_entry)

> Ivzhh wrote in local_repo.rs:136
> I think LRU will update reference count (or timestamp) when the data is 
> accessed.

Actually I didn't realize that RwLock doesn't get a regular `get()` since it is 
doing a compile time borrow check. 
https://doc.rust-lang.org/std/sync/struct.RwLock.html#method.get_mut. My 
mistake, the code is fine.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D2057

To: Ivzhh, #hg-reviewers, kevincox
Cc: quark, yuja, glandium, krbullock, indygreg, durin42, kevincox, 
mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D2938: grep: make grep search on working directory by default

2018-03-24 Thread yuja (Yuya Nishihara)
yuja added a comment.


  Perhaps we can start with adding an experimental option to grep files
  including unchanged ones?
  
  IIUC, the new default behavior is something like `hg grep -r "wdir()" 
--all-files`,
  which is basically `s/ctx.files()/ctx/`.
  (needless to say `--all-files` is a bad name, and the following patch is just 
a hack.)
  
diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -1835,7 +1835,7 @@ def walkchangerevs(repo, match, opts, pr
 if not revs:
 return []
 wanted = set()
-slowpath = match.anypats() or (not match.always() and 
opts.get('removed'))
+slowpath = True
 fncache = {}
 change = repo.changectx
 
@@ -1889,7 +1889,7 @@ def walkchangerevs(repo, match, opts, pr
 else:
 self.revs.discard(value)
 ctx = change(value)
-matches = [f for f in ctx.files() if match(f)]
+matches = [f for f in ctx if match(f)]
 if matches:
 fncache[value] = matches
 self.set.add(value)
@@ -1939,7 +1939,7 @@ def walkchangerevs(repo, match, opts, pr
 ctx = change(rev)
 if not fns:
 def fns_generator():
-for f in ctx.files():
+for f in ctx:
 if match(f):
 yield f
 fns = fns_generator()

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D2938

To: sangeet259, #hg-reviewers
Cc: yuja, pulkit, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D2938: grep: make grep search on working directory by default

2018-03-24 Thread sangeet259 (Sangeet Kumar Mishra)
sangeet259 updated this revision to Diff 7267.
sangeet259 edited the summary of this revision.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D2938?vs=7266&id=7267

REVISION DETAIL
  https://phab.mercurial-scm.org/D2938

AFFECTED FILES
  mercurial/commands.py
  tests/test-grep.t

CHANGE DETAILS

diff --git a/tests/test-grep.t b/tests/test-grep.t
--- a/tests/test-grep.t
+++ b/tests/test-grep.t
@@ -24,74 +24,74 @@
 simple
 
   $ hg grep '.*'
-  port:4:export
-  port:4:vaportight
-  port:4:import/export
+  port:export
+  port:vaportight
+  port:import/export
   $ hg grep port port
-  port:4:export
-  port:4:vaportight
-  port:4:import/export
+  port:export
+  port:vaportight
+  port:import/export
 
 simple with color
 
   $ hg --config extensions.color= grep --config color.mode=ansi \
   > --color=always port port
-  
\x1b[0;35mport\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;32m4\x1b[0m\x1b[0;36m:\x1b[0mex\x1b[0;31;1mport\x1b[0m
 (esc)
-  
\x1b[0;35mport\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;32m4\x1b[0m\x1b[0;36m:\x1b[0mva\x1b[0;31;1mport\x1b[0might
 (esc)
-  
\x1b[0;35mport\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;32m4\x1b[0m\x1b[0;36m:\x1b[0mim\x1b[0;31;1mport\x1b[0m/ex\x1b[0;31;1mport\x1b[0m
 (esc)
+  \x1b[0;35mport\x1b[0m\x1b[0;36m:\x1b[0mex\x1b[0;31;1mport\x1b[0m (esc)
+  \x1b[0;35mport\x1b[0m\x1b[0;36m:\x1b[0mva\x1b[0;31;1mport\x1b[0might (esc)
+  
\x1b[0;35mport\x1b[0m\x1b[0;36m:\x1b[0mim\x1b[0;31;1mport\x1b[0m/ex\x1b[0;31;1mport\x1b[0m
 (esc)
 
 simple templated
 
   $ hg grep port \
   > -T '{file}:{rev}:{node|short}:{texts % "{if(matched, text|upper, 
text)}"}\n'
-  port:4:914fa752cdea:exPORT
-  port:4:914fa752cdea:vaPORTight
-  port:4:914fa752cdea:imPORT/exPORT
+  port:::exPORT
+  port:::vaPORTight
+  port:::imPORT/exPORT
 
 simple JSON (no "change" field)
 
   $ hg grep -Tjson port
   [
{
-"date": [4.0, 0],
-"file": "port",
-"line_number": 1,
-"node": "914fa752cdea8ac1a8d5c858b0c736218f6c",
-"rev": 4,
+"date": [0, 0],
+"file": "port",
+"line_number": 1,
+"node": "",
+"rev": null,
 "texts": [{"matched": false, "text": "ex"}, {"matched": true, "text": 
"port"}],
-"user": "spam"
-   },
-   {
-"date": [4.0, 0],
+"user": "test"
+   },
+   {
+"date": [0, 0],
 "file": "port",
 "line_number": 2,
-"node": "914fa752cdea8ac1a8d5c858b0c736218f6c",
-"rev": 4,
+"node": "",
+"rev": null,
 "texts": [{"matched": false, "text": "va"}, {"matched": true, "text": 
"port"}, {"matched": false, "text": "ight"}],
-"user": "spam"
-   },
-   {
-"date": [4.0, 0],
+"user": "test"
+   },
+   {
+"date": [0, 0],
 "file": "port",
 "line_number": 3,
-"node": "914fa752cdea8ac1a8d5c858b0c736218f6c",
-"rev": 4,
+"node": "",
+"rev": null,
 "texts": [{"matched": false, "text": "im"}, {"matched": true, "text": 
"port"}, {"matched": false, "text": "/ex"}, {"matched": true, "text": "port"}],
-"user": "spam"
+"user": "test"
}
   ]
 
 simple JSON without matching lines
 
   $ hg grep -Tjson -l port
   [
{
-"date": [4.0, 0],
-"file": "port",
-"line_number": 1,
-"node": "914fa752cdea8ac1a8d5c858b0c736218f6c",
-"rev": 4,
-"user": "spam"
+"date": [0, 0],
+"file": "port",
+"line_number": 1,
+"node": "",
+"rev": null,
+"user": "test"
}
   ]
 
@@ -207,18 +207,17 @@
 other
 
   $ hg grep -l port port
-  port:4
+  port
   $ hg grep import port
-  port:4:import/export
+  port:import/export
 
   $ hg cp port port2
   $ hg commit -m 4 -u spam -d '5 0'
 
 follow
 
   $ hg grep --traceback -f 'import\n\Z' port2
-  port:0:import
-  
+  [1]
   $ echo deport >> port2
   $ hg commit -m 5 -u eggs -d '6 0'
   $ hg grep -f --all -nu port port2
@@ -256,26 +255,26 @@
   $ echo blue >> color
   $ hg ci -m 3
   $ hg grep orange
-  color:3:orange
+  color:orange
   $ hg grep --all orange
   color:3:+:orange
   color:2:-:orange
   color:1:+:orange
 
 test substring match: '^' should only match at the beginning
 
   $ hg grep '^.' --config extensions.color= --color debug
-  [grep.filename|color][grep.sep|:][grep.rev|3][grep.sep|:][grep.match|b]lack
-  [grep.filename|color][grep.sep|:][grep.rev|3][grep.sep|:][grep.match|o]range
-  [grep.filename|color][grep.sep|:][grep.rev|3][grep.sep|:][grep.match|b]lue
+  [grep.filename|color][grep.sep|:][grep.match|b]lack
+  [grep.filename|color][grep.sep|:][grep.match|o]range
+  [grep.filename|color][grep.sep|:][grep.match|b]lue
 
 match in last "line" without newline
 
   $ $PYTHON -c 'fp = open("noeol", "wb"); fp.write(b"no infinite loop"); 
fp.close();'
   $ hg ci -Amnoeol
   adding noeol
   $ hg grep loop
-  noeol:4:no infinite loop
+  noeol:no infinite loop
 
   $ cd ..
 
@@ -292,8 +291,7 @@
   $ hg ren

[PATCH 5 of 5] util: make safehasattr() a pycompat function

2018-03-24 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1521869072 -32400
#  Sat Mar 24 14:24:32 2018 +0900
# Node ID 92e5b042b91626cb9016e841ba823515d56f787e
# Parent  5814bdd0d29ae544f62ca6a02678137b7e9de397
util: make safehasattr() a pycompat function

So safehasattr() can be imported by utils.* modules. util.safehasattr() still
remains as an alias since it is pretty basic utility available for years.

On current Python 3, the builtin hasattr() should have no problem.

diff --git a/mercurial/pycompat.py b/mercurial/pycompat.py
--- a/mercurial/pycompat.py
+++ b/mercurial/pycompat.py
@@ -243,6 +243,8 @@ if ispy3:
 def open(name, mode='r', buffering=-1, encoding=None):
 return builtins.open(name, sysstr(mode), buffering, encoding)
 
+safehasattr = _wrapattrfunc(builtins.hasattr)
+
 def _getoptbwrapper(orig, args, shortlist, namelist):
 """
 Takes bytes arguments, converts them to unicode, pass them to
@@ -326,6 +328,11 @@ else:
 def getdoc(obj):
 return getattr(obj, '__doc__', None)
 
+_notset = object()
+
+def safehasattr(thing, attr):
+return getattr(thing, attr, _notset) is not _notset
+
 def _getoptbwrapper(orig, args, shortlist, namelist):
 return orig(args, shortlist, namelist)
 
diff --git a/mercurial/util.py b/mercurial/util.py
--- a/mercurial/util.py
+++ b/mercurial/util.py
@@ -67,6 +67,7 @@ empty = pycompat.empty
 httplib = pycompat.httplib
 pickle = pycompat.pickle
 queue = pycompat.queue
+safehasattr = pycompat.safehasattr
 socketserver = pycompat.socketserver
 stderr = pycompat.stderr
 stdin = pycompat.stdin
@@ -177,9 +178,6 @@ except AttributeError:
 
 _notset = object()
 
-def safehasattr(thing, attr):
-return getattr(thing, attr, _notset) is not _notset
-
 def _rapply(f, xs):
 if xs is None:
 # assume None means non-value of optional data
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 3 of 5] test-bundle2-exchange: use error.Abort instead of util.Abort

2018-03-24 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1521868184 -32400
#  Sat Mar 24 14:09:44 2018 +0900
# Node ID 9e694251731bf82895a6976ecba1afa3ece3fe2d
# Parent  f69531100039b5c81677be7c9f10c7598966a120
test-bundle2-exchange: use error.Abort instead of util.Abort

diff --git a/tests/test-bundle2-exchange.t b/tests/test-bundle2-exchange.t
--- a/tests/test-bundle2-exchange.t
+++ b/tests/test-bundle2-exchange.t
@@ -933,10 +933,10 @@ Test lazily acquiring the lock during un
 
   $ cat >> $TESTTMP/locktester.py < import os
-  > from mercurial import extensions, bundle2, util
+  > from mercurial import extensions, bundle2, error
   > def checklock(orig, repo, *args, **kwargs):
   > if repo.svfs.lexists("lock"):
-  > raise util.Abort("Lock should not be taken")
+  > raise error.Abort("Lock should not be taken")
   > return orig(repo, *args, **kwargs)
   > def extsetup(ui):
   >extensions.wrapfunction(bundle2, 'processbundle', checklock)
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 4 of 5] util: drop util.Abort in favor of error.Abort (API)

2018-03-24 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1521868417 -32400
#  Sat Mar 24 14:13:37 2018 +0900
# Node ID 5814bdd0d29ae544f62ca6a02678137b7e9de397
# Parent  9e694251731bf82895a6976ecba1afa3ece3fe2d
util: drop util.Abort in favor of error.Abort (API)

IIRC, error.Abort exists since Mercurial 1.2, so it should be pretty easy
for extensions authors to update their code.

.. api::

   The util.Abort alias has been removed. Use error.Abort.

diff --git a/mercurial/util.py b/mercurial/util.py
--- a/mercurial/util.py
+++ b/mercurial/util.py
@@ -1586,8 +1586,6 @@ def increasingchunks(source, min=1024, m
 if buf:
 yield ''.join(buf)
 
-Abort = error.Abort
-
 def always(fn):
 return True
 
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 5] util: use error.Abort instead of local alias

2018-03-24 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1521868130 -32400
#  Sat Mar 24 14:08:50 2018 +0900
# Node ID f69531100039b5c81677be7c9f10c7598966a120
# Parent  9bfb1ec8fb375630cfca0e42b17676e1892bd90a
util: use error.Abort instead of local alias

diff --git a/mercurial/util.py b/mercurial/util.py
--- a/mercurial/util.py
+++ b/mercurial/util.py
@@ -282,7 +282,7 @@ class digester(object):
 self._hashes = {}
 for k in digests:
 if k not in DIGESTS:
-raise Abort(_('unknown digest type: %s') % k)
+raise error.Abort(_('unknown digest type: %s') % k)
 self._hashes[k] = DIGESTS[k]()
 if s:
 self.update(s)
@@ -293,7 +293,7 @@ class digester(object):
 
 def __getitem__(self, key):
 if key not in DIGESTS:
-raise Abort(_('unknown digest type: %s') % k)
+raise error.Abort(_('unknown digest type: %s') % k)
 return nodemod.hex(self._hashes[key].digest())
 
 def __iter__(self):
@@ -332,13 +332,13 @@ class digestchecker(object):
 
 def validate(self):
 if self._size != self._got:
-raise Abort(_('size mismatch: expected %d, got %d') %
-(self._size, self._got))
+raise error.Abort(_('size mismatch: expected %d, got %d') %
+  (self._size, self._got))
 for k, v in self._digests.items():
 if v != self._digester[k]:
 # i18n: first parameter is a digest name
-raise Abort(_('%s mismatch: expected %s, got %s') %
-(k, v, self._digester[k]))
+raise error.Abort(_('%s mismatch: expected %s, got %s') %
+  (k, v, self._digester[k]))
 
 try:
 buffer = buffer
@@ -1528,8 +1528,8 @@ def tempfilter(s, cmd):
 if pycompat.sysplatform == 'OpenVMS' and code & 1:
 code = 0
 if code:
-raise Abort(_("command '%s' failed: %s") %
-(cmd, explainexit(code)))
+raise error.Abort(_("command '%s' failed: %s") %
+  (cmd, explainexit(code)))
 return readfile(outname)
 finally:
 try:
@@ -1831,7 +1831,7 @@ def copyfile(src, dest, hardlink=False, 
 oldstat.stat[stat.ST_MTIME] + 1) & 0x7fff
 os.utime(dest, (advanced, advanced))
 except shutil.Error as inst:
-raise Abort(str(inst))
+raise error.Abort(str(inst))
 
 def copyfiles(src, dst, hardlink=None, progress=lambda t, pos: None):
 """Copy a directory tree using hardlinks if possible."""
@@ -2809,7 +2809,8 @@ def getport(port):
 try:
 return socket.getservbyname(pycompat.sysstr(port))
 except socket.error:
-raise Abort(_("no port number associated with service '%s'") % port)
+raise error.Abort(_("no port number associated with service '%s'")
+  % port)
 
 class url(object):
 r"""Reliable URL parser.
@@ -2970,7 +2971,7 @@ class url(object):
 
 if (self.host and self.scheme == 'file' and
 self.host not in ('localhost', '127.0.0.1', '[::1]')):
-raise Abort(_('file:// URLs can only refer to localhost'))
+raise error.Abort(_('file:// URLs can only refer to 
localhost'))
 
 self.path = path
 
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 1 of 5] rcutil: directly call win32.executablepath()

2018-03-24 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1521865850 -32400
#  Sat Mar 24 13:30:50 2018 +0900
# Node ID 9bfb1ec8fb375630cfca0e42b17676e1892bd90a
# Parent  3f765e4cbf4c1e53e0fd88992c079b321749d837
rcutil: directly call win32.executablepath()

Since it isn't supported on POSIX platform, we don't need to double the
compatibility layers.

diff --git a/mercurial/posix.py b/mercurial/posix.py
--- a/mercurial/posix.py
+++ b/mercurial/posix.py
@@ -626,9 +626,6 @@ class cachestat(object):
 def __ne__(self, other):
 return not self == other
 
-def executablepath():
-return None # available on Windows only
-
 def statislink(st):
 '''check whether a stat result is a symlink'''
 return st and stat.S_ISLNK(st.st_mode)
diff --git a/mercurial/scmwindows.py b/mercurial/scmwindows.py
--- a/mercurial/scmwindows.py
+++ b/mercurial/scmwindows.py
@@ -21,7 +21,7 @@ fallbackpager = 'more'
 def systemrcpath():
 '''return default os-specific hgrc search path'''
 rcpath = []
-filename = util.executablepath()
+filename = win32.executablepath()
 # Use mercurial.ini found in directory with hg.exe
 progrc = os.path.join(os.path.dirname(filename), 'mercurial.ini')
 rcpath.append(progrc)
diff --git a/mercurial/util.py b/mercurial/util.py
--- a/mercurial/util.py
+++ b/mercurial/util.py
@@ -108,7 +108,6 @@ cachestat = platform.cachestat
 checkexec = platform.checkexec
 checklink = platform.checklink
 copymode = platform.copymode
-executablepath = platform.executablepath
 expandglobs = platform.expandglobs
 explainexit = platform.explainexit
 findexe = platform.findexe
diff --git a/mercurial/windows.py b/mercurial/windows.py
--- a/mercurial/windows.py
+++ b/mercurial/windows.py
@@ -31,7 +31,6 @@ except ImportError:
 
 osutil = policy.importmod(r'osutil')
 
-executablepath = win32.executablepath
 getfsmountpoint = win32.getvolumename
 getfstype = win32.getfstype
 getuser = win32.getuser
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH] directaccess: do not abort by 'ff...' hash

2018-03-24 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1521879572 -32400
#  Sat Mar 24 17:19:32 2018 +0900
# Node ID 3f765e4cbf4c1e53e0fd88992c079b321749d837
# Parent  f40b6e7fc011715b209774c0d1fbc5b8a6694401
directaccess: do not abort by 'ff...' hash

Since the 'ff...' hash should never be hidden, we can just ignore it.

diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py
--- a/mercurial/scmutil.py
+++ b/mercurial/scmutil.py
@@ -1419,7 +1419,7 @@ def _getrevsfromsymbols(repo, symbols):
 
 try:
 s = pmatch(s)
-except error.LookupError:
+except (error.LookupError, error.WdirUnsupported):
 s = None
 
 if s is not None:
diff --git a/tests/test-directaccess.t b/tests/test-directaccess.t
--- a/tests/test-directaccess.t
+++ b/tests/test-directaccess.t
@@ -179,6 +179,19 @@ This should not throw error
foo
   -bar
 
+Test special hash/rev
+
+  $ hg log -qr 'null:wdir() & '
+  -1:
+  $ hg log -qr 'null:wdir() & '
+  2147483647:
+  $ hg log -qr 'null:wdir() & rev(-1)'
+  -1:
+  $ hg log -qr 'null:wdir() & rev(2147483647)'
+  2147483647:
+  $ hg log -qr 'null:wdir() & 2147483647'
+  2147483647:
+
 Commands with undefined cmdtype should not work right now
 
   $ hg phase -r 28ad74
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D2938: grep: make grep search on working directory by default

2018-03-24 Thread pulkit (Pulkit Goyal)
pulkit added a comment.


  No need to add Edit1, Edit2 in commit message. If something changes from one 
version to another that deserves mention, include that in commit message as 
normal.

INLINE COMMENTS

> commands.py:2583
> +# when nothing is passed in -r or --all
> +if not bool(opts.get('rev')) and not bool(opts.get('all')):
> +rev = scmutil.revsingle(repo, opts.get('rev'), None).node()

Nit: no need to add bool() calls.

> commands.py:2584
> +if not bool(opts.get('rev')) and not bool(opts.get('all')):
> +rev = scmutil.revsingle(repo, opts.get('rev'), None).node()
> +m = scmutil.match(repo[rev], pats, opts, default='relglob')

The above if condition wants opts['rev'] to be empty and here you are using 
it's value.

> test-grep.t:343
>  
> -  $ cd ..
> +Test that grep searches only on working directory 
> +  $ cd ..

For better testing, please add untracked files which can be probable match. 
Also I suspect there will be existing tests for hg grep which should break 
because of new behavior.

> test-grep.t:357
> +  $ hg grep 'revsets'
> +  secondfile:None:mercurial revsets are awesome and makes life easier
> +  $ echo "another generic string" > fourthone

what's this None here?

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D2938

To: sangeet259, #hg-reviewers
Cc: pulkit, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D2938: grep: make grep search on working directory by default

2018-03-24 Thread sangeet259 (Sangeet Kumar Mishra)
sangeet259 updated this revision to Diff 7266.
sangeet259 edited the summary of this revision.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D2938?vs=7262&id=7266

REVISION DETAIL
  https://phab.mercurial-scm.org/D2938

AFFECTED FILES
  mercurial/commands.py
  tests/test-grep.t

CHANGE DETAILS

diff --git a/tests/test-grep.t b/tests/test-grep.t
--- a/tests/test-grep.t
+++ b/tests/test-grep.t
@@ -340,4 +340,25 @@
   $ hg grep "MaCam" --all
   binfile.bin:0:+: Binary file matches
 
-  $ cd ..
+Test that grep searches only on working directory 
+  $ cd ..
+  $ hg init t5
+  $ cd t5
+  $ echo "mercurial revsets are awesome" > firstfile
+  $ hg add firstfile
+  $ hg commit -m  'adds firstfile'
+  $ hg rm firstfile
+  $ hg commit -m 'removes firstfile'
+  $ echo "mercurial revsets are awesome and makes life easier" > secondfile
+  $ echo "some generic text" > thirdfile
+  $ hg add secondfile thirdfile
+  $ hg commit -m 'adds two new files'
+  $ hg grep 'revsets'
+  secondfile:None:mercurial revsets are awesome and makes life easier
+  $ echo "another generic string" > fourthone
+
+Search on added but not commit i.e dirty working directory
+  $ hg add fourthone
+  $ hg grep "generic"
+  fourthone:another generic string
+  thirdfile:some generic text
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -2469,21 +2469,31 @@
 @util.cachefunc
 def binary():
 flog = getfile(fn)
-return util.binary(flog.read(ctx.filenode(fn)))
+try:
+return util.binary(flog.read(ctx.filenode(fn)))
+except AttributeError:
+return util.binary(ctx.filectx(fn).data())
 
 fieldnamemap = {'filename': 'file', 'linenumber': 'line_number'}
 if opts.get('all'):
 iter = difflinestates(pstates, states)
 else:
 iter = [('', l) for l in states]
 for change, l in iter:
 fm.startitem()
-fm.data(node=fm.hexfunc(ctx.node()))
-cols = [
+fm.data(node=fm.hexfunc(scmutil.binnode(ctx)))
+if not bool(opts.get('all')) and not bool(opts.get('rev')):
+cols = [
 ('filename', fn, True),
-('rev', rev, True),
+('rev', rev, False),
 ('linenumber', l.linenum, opts.get('line_number')),
 ]
+else:
+cols = [
+('filename', fn, True),
+('rev', rev, True),
+('linenumber', l.linenum, opts.get('line_number')),
+]
 if opts.get('all'):
 cols.append(('change', change, True))
 cols.extend([
@@ -2568,26 +2578,46 @@
 
 ui.pager('grep')
 fm = ui.formatter('grep', opts)
-for ctx in cmdutil.walkchangerevs(repo, match, opts, prep):
-rev = ctx.rev()
-parent = ctx.p1().rev()
-for fn in sorted(revfiles.get(rev, [])):
-states = matches[rev][fn]
-copy = copies.get(rev, {}).get(fn)
-if fn in skip:
-if copy:
-skip[copy] = True
+# This if part handles the default situation,\
+# when nothing is passed in -r or --all
+if not bool(opts.get('rev')) and not bool(opts.get('all')):
+rev = scmutil.revsingle(repo, opts.get('rev'), None).node()
+m = scmutil.match(repo[rev], pats, opts, default='relglob')
+m.bad = lambda x, y: False
+ctx = repo[rev]
+ds = ctx.repo().dirstate
+
+for fn in ctx.matches(m):
+if rev is None and ds[fn] == 'r':
 continue
-pstates = matches.get(parent, {}).get(copy or fn, [])
-if pstates or states:
-r = display(fm, fn, ctx, pstates, states)
+data = ctx.filectx(fn).data()
+states = []
+for lnum, cstart, cend, line in matchlines(data):
+states.append(linestate(line, lnum, cstart, cend))
+if states:
+r = display(fm, fn, ctx, [], states)
 found = found or r
-if r and not opts.get('all'):
-skip[fn] = True
+else :
+for ctx in cmdutil.walkchangerevs(repo, match, opts, prep):
+rev = ctx.rev()
+parent = ctx.p1().rev()
+for fn in sorted(revfiles.get(rev, [])):
+states = matches[rev][fn]
+copy = copies.get(rev, {}).get(fn)
+if fn in skip:
 if copy:
 skip[copy] = True
-del matches[rev]
-del revfiles[rev]
+continue
+pstates = matches.get(parent, {}).get(copy or fn, [])
+if pstates or states:
+r = display(fm, fn, ctx, pstates, states)
+found = f