D2593: state: add logic to parse the state file in old way if cbor fails
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
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
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
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
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
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()
# 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()
# 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()
# 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
# 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()
# 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()
# 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
# 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
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)
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
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
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
# 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)
# 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
# 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
# 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
# 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()
# 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
# 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
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
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
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
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()
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
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
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)
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)
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)
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)
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)
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
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)
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
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)
# 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
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
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
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
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
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
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
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
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
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
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
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()
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
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
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
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
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
# 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
# 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)
# 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
# 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()
# 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
# 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
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
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