[PATCH 8 of 8] parser: stabilize output of prettyformat() by using byte-safe repr()

2017-09-03 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1504441045 -32400
#  Sun Sep 03 21:17:25 2017 +0900
# Node ID a9b5bfc65a2fd68c66a5bc8fec651320ce2d7d3c
# Parent  2f19734c56c0227e004a849e8037378f9d930e7d
parser: stabilize output of prettyformat() by using byte-safe repr()

The format of leaf nodes is slightly changed so they look more similar to
internal nodes.

diff --git a/mercurial/parser.py b/mercurial/parser.py
--- a/mercurial/parser.py
+++ b/mercurial/parser.py
@@ -20,6 +20,7 @@ from __future__ import absolute_import
 
 from .i18n import _
 from . import (
+encoding,
 error,
 util,
 )
@@ -193,9 +194,17 @@ def unescapestr(s):
 # mangle Python's exception into our format
 raise error.ParseError(str(e).lower())
 
+def _brepr(obj):
+if isinstance(obj, bytes):
+return b"'%s'" % util.escapestr(obj)
+return encoding.strtolocal(repr(obj))
+
 def _prettyformat(tree, leafnodes, level, lines):
-if not isinstance(tree, tuple) or tree[0] in leafnodes:
-lines.append((level, str(tree)))
+if not isinstance(tree, tuple):
+lines.append((level, _brepr(tree)))
+elif tree[0] in leafnodes:
+rs = map(_brepr, tree[1:])
+lines.append((level, '(%s %s)' % (tree[0], ' '.join(rs
 else:
 lines.append((level, '(%s' % tree[0]))
 for s in tree[1:]:
@@ -219,9 +228,9 @@ def simplifyinfixops(tree, targetnodes):
 ...   ('symbol', '2')),
 ... ('symbol', '3')))
 (or
-  ('symbol', '1')
-  ('symbol', '2')
-  ('symbol', '3'))
+  (symbol '1')
+  (symbol '2')
+  (symbol '3'))
 >>> f(('func',
 ... ('symbol', 'p1'),
 ... ('or',
@@ -246,25 +255,25 @@ def simplifyinfixops(tree, targetnodes):
 ...   ('symbol', '7'),
 ...   ('symbol', '8'
 (func
-  ('symbol', 'p1')
+  (symbol 'p1')
   (or
 (func
-  ('symbol', 'sort')
+  (symbol 'sort')
   (list
 (or
-  ('symbol', '1')
-  ('symbol', '2')
-  ('symbol', '3'))
+  (symbol '1')
+  (symbol '2')
+  (symbol '3'))
 (negate
-  ('symbol', 'rev'
+  (symbol 'rev'
 (and
-  ('symbol', '4')
+  (symbol '4')
   (group
 (or
-  ('symbol', '5')
-  ('symbol', '6')
-  ('symbol', '7'
-('symbol', '8')))
+  (symbol '5')
+  (symbol '6')
+  (symbol '7'
+(symbol '8')))
 """
 if not isinstance(tree, tuple):
 return tree
@@ -561,8 +570,8 @@ class basealiasrules(object):
 >>> args = ['$1', '$2', 'foo']
 >>> pprint(builddefn('$1 or foo', args))
 (or
-  ('_aliasarg', '$1')
-  ('_aliasarg', 'foo'))
+  (_aliasarg '$1')
+  (_aliasarg 'foo'))
 >>> try:
 ... builddefn('$1 or $bar', args)
 ... except error.ParseError as inst:
@@ -571,12 +580,12 @@ class basealiasrules(object):
 >>> args = ['$1', '$10', 'foo']
 >>> pprint(builddefn('$10 or baz', args))
 (or
-  ('_aliasarg', '$10')
-  ('symbol', 'baz'))
+  (_aliasarg '$10')
+  (symbol 'baz'))
 >>> pprint(builddefn('"$1" or "foo"', args))
 (or
-  ('string', '$1')
-  ('string', 'foo'))
+  (string '$1')
+  (string 'foo'))
 """
 tree = cls._parse(defn)
 if args:
diff --git a/mercurial/templater.py b/mercurial/templater.py
--- a/mercurial/templater.py
+++ b/mercurial/templater.py
@@ -194,18 +194,18 @@ def _unnesttemplatelist(tree):
 >>> def f(tree):
 ... print prettyformat(_unnesttemplatelist(tree))
 >>> f(('template', []))
-('string', '')
+(string '')
 >>> f(('template', [('string', 'foo')]))
-('string', 'foo')
+(string 'foo')
 >>> f(('template', [('string', 'foo'), ('symbol', 'rev')]))
 (template
-  ('string', 'foo')
-  ('symbol', 'rev'))
+  (string 'foo')
+  (symbol 'rev'))
 >>> f(('template', [('symbol', 'rev')]))  # template(rev) -> str
 (template
-  ('symbol', 'rev'))
+  (symbol 'rev'))
 >>> f(('template', [('template', [('string', 'foo')])]))
-('string', 'foo')
+(string 'foo')
 """
 if not isinstance(tree, tuple):
 return tree
diff --git a/tests/test-command-template.t b/tests/test-command-template.t
--- a/tests/test-command-template.t
+++ b/tests/test-command-template.t
@@ -41,62 +41,62 @@ Test division:
   $ hg debugtemplate -r0 -v '{5 / 2} {mod(5, 2)}\n'
   (template
 (/
-  ('integer', '5')
-  ('integer', '2'))
-('string', ' ')
+  (integer '5')
+  (integer '2'))
+(string ' ')
 (func
-  ('symbol', 'mod')
+  (symbol 'mod')
   (list
-('integer', '5')
-('integer', '2')))

D618: largefiles: remove unused assignments from wrapfunction()

2017-09-03 Thread martinvonz (Martin von Zweigbergk)
martinvonz created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  The return values from wrapfunction() were never used here. Using the
  value is also a little tricky and wrappedfunction() should be
  preferred, so let's just delete the assignments.
  
  There's also a bunch of return values from wrapcommand() being
  assigned to a variable here, but at least that value can be (and is
  used after some of the assignments).

REPOSITORY
  rHG Mercurial

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

AFFECTED FILES
  hgext/largefiles/uisetup.py

CHANGE DETAILS

diff --git a/hgext/largefiles/uisetup.py b/hgext/largefiles/uisetup.py
--- a/hgext/largefiles/uisetup.py
+++ b/hgext/largefiles/uisetup.py
@@ -53,8 +53,7 @@
 
 # The scmutil function is called both by the (trivial) addremove command,
 # and in the process of handling commit -A (issue3542)
-entry = extensions.wrapfunction(scmutil, 'addremove',
-overrides.scmutiladdremove)
+extensions.wrapfunction(scmutil, 'addremove', overrides.scmutiladdremove)
 extensions.wrapfunction(cmdutil, 'add', overrides.cmdutiladd)
 extensions.wrapfunction(cmdutil, 'remove', overrides.cmdutilremove)
 extensions.wrapfunction(cmdutil, 'forget', overrides.cmdutilforget)
@@ -64,8 +63,8 @@
 # Subrepos call status function
 entry = extensions.wrapcommand(commands.table, 'status',
overrides.overridestatus)
-entry = extensions.wrapfunction(subrepo.hgsubrepo, 'status',
-overrides.overridestatusfn)
+extensions.wrapfunction(subrepo.hgsubrepo, 'status',
+overrides.overridestatusfn)
 
 entry = extensions.wrapcommand(commands.table, 'log',
overrides.overridelog)
@@ -111,46 +110,41 @@
 pushopt = [('', 'lfrev', [],
 _('upload largefiles for these revisions'), _('REV'))]
 entry[1].extend(pushopt)
-entry = extensions.wrapfunction(exchange, 'pushoperation',
-overrides.exchangepushoperation)
+extensions.wrapfunction(exchange, 'pushoperation',
+overrides.exchangepushoperation)
 
 entry = extensions.wrapcommand(commands.table, 'clone',
overrides.overrideclone)
 cloneopt = [('', 'all-largefiles', None,
  _('download all versions of all largefiles'))]
 entry[1].extend(cloneopt)
-entry = extensions.wrapfunction(hg, 'clone', overrides.hgclone)
-entry = extensions.wrapfunction(hg, 'postshare', overrides.hgpostshare)
+extensions.wrapfunction(hg, 'clone', overrides.hgclone)
+extensions.wrapfunction(hg, 'postshare', overrides.hgpostshare)
 
 entry = extensions.wrapcommand(commands.table, 'cat',
overrides.overridecat)
-entry = extensions.wrapfunction(merge, '_checkunknownfile',
-overrides.overridecheckunknownfile)
-entry = extensions.wrapfunction(merge, 'calculateupdates',
-overrides.overridecalculateupdates)
-entry = extensions.wrapfunction(merge, 'recordupdates',
-overrides.mergerecordupdates)
-entry = extensions.wrapfunction(merge, 'update',
-overrides.mergeupdate)
-entry = extensions.wrapfunction(filemerge, '_filemerge',
-overrides.overridefilemerge)
-entry = extensions.wrapfunction(cmdutil, 'copy',
-overrides.overridecopy)
+extensions.wrapfunction(merge, '_checkunknownfile',
+overrides.overridecheckunknownfile)
+extensions.wrapfunction(merge, 'calculateupdates',
+overrides.overridecalculateupdates)
+extensions.wrapfunction(merge, 'recordupdates',
+overrides.mergerecordupdates)
+extensions.wrapfunction(merge, 'update', overrides.mergeupdate)
+extensions.wrapfunction(filemerge, '_filemerge',
+overrides.overridefilemerge)
+extensions.wrapfunction(cmdutil, 'copy', overrides.overridecopy)
 
 # Summary calls dirty on the subrepos
-entry = extensions.wrapfunction(subrepo.hgsubrepo, 'dirty',
-overrides.overridedirty)
+extensions.wrapfunction(subrepo.hgsubrepo, 'dirty', 
overrides.overridedirty)
 
-entry = extensions.wrapfunction(cmdutil, 'revert',
-overrides.overriderevert)
+extensions.wrapfunction(cmdutil, 'revert', overrides.overriderevert)
 
 extensions.wrapcommand(commands.table, 'archive',
overrides.overridearchivecmd)
 extensions.wrapfunction(archival, 'archive', overrides.overridearchive)
 

[PATCH] dagop: fix docstring of `cutfunc`

2017-09-03 Thread Jun Wu
# HG changeset patch
# User Jun Wu 
# Date 1504468483 25200
#  Sun Sep 03 12:54:43 2017 -0700
# Node ID 75cb2afd931082496524b47b7dc0f34204b77292
# Parent  68afb88b51bb626cd25440e2df812f2306463b55
dagop: fix docstring of `cutfunc`

I was using `keepfunc`, then found `cutfunc` easier to understand. But
forgot to update the documentation. This patch fixes it.

Maybe it could be applied in-place.

diff --git a/mercurial/dagop.py b/mercurial/dagop.py
--- a/mercurial/dagop.py
+++ b/mercurial/dagop.py
@@ -103,5 +103,5 @@ def revancestors(repo, revs, followfirst
 
 If cutfunc is provided, it will be used to cut the traversal of the DAG.
-When cutfunc(X) returns False, the DAG traversal stops - revision X and
+When cutfunc(X) returns True, the DAG traversal stops - revision X and
 X's ancestors in the traversal path will be skipped. This could be an
 optimization sometimes.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D617: filemerge: use fctx.write() in the internal:dump tool, instead of copy

2017-09-03 Thread phillco (Phil Cohen)
phillco created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  This is slower but allows this tool to work with the "deferred writes"
  milestone of in-memory merge.
  
  The performance hit is not too noticiable since this only used for the :dump
  merge tool during a conflict.

REPOSITORY
  rHG Mercurial

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

AFFECTED FILES
  mercurial/filemerge.py

CHANGE DETAILS

diff --git a/mercurial/filemerge.py b/mercurial/filemerge.py
--- a/mercurial/filemerge.py
+++ b/mercurial/filemerge.py
@@ -468,7 +468,7 @@
 a = _workingpath(repo, fcd)
 fd = fcd.path()
 
-util.copyfile(a, a + ".local")
+util.writefile(a + ".local", repo.wwritedata(fcd.path(), fcd.data()))
 repo.wwrite(fd + ".other", fco.data(), fco.flags())
 repo.wwrite(fd + ".base", fca.data(), fca.flags())
 return False, 1, False



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


D616: context: add overlayworkingcontext and overlayworkingfilectx

2017-09-03 Thread phillco (Phil Cohen)
phillco created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  These two classes will be used extensively in the first in-memory merge
  milestone.

REPOSITORY
  rHG Mercurial

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

AFFECTED FILES
  mercurial/context.py

CHANGE DETAILS

diff --git a/mercurial/context.py b/mercurial/context.py
--- a/mercurial/context.py
+++ b/mercurial/context.py
@@ -1974,6 +1974,186 @@
 def setflags(self, l, x):
 self._repo.wvfs.setflags(self._path, l, x)
 
+class overlayworkingctx(workingctx):
+"""Wraps another mutable context with a write-back cache that can be 
flushed
+at a later time.
+
+self._cache[path] maps to a dict with keys: {
+'exists': bool?
+'date': date?
+'data': str?
+'flags': str?
+}
+If `exists` is True, either `data` or `flags` must be non-None (either 
both,
+or just `flags`), and 'date' is non-None. If it is `False`, the file was
+deleted.
+"""
+
+def __init__(self, repo, wrappedctx):
+super(overlayworkingctx, self).__init__(repo)
+self._repo = repo
+self._wrappedctx = wrappedctx
+self.clean()
+
+def data(self, path):
+if self.isdirty(path):
+if self._cache[path]['exists']:
+if self._cache[path]['data']:
+return self._cache[path]['data']
+else:
+# Must fallback here, too, because we only set flags.
+return self._underlyingctx(path).data()
+else:
+raise IOError("No such file or directory: %s" % self._path)
+else:
+return self._underlyingctx(path).data()
+
+def filedate(self, path):
+if self.isdirty(path):
+return self._cache[path]['date']
+else:
+return self._underlyingctx(path).date()
+
+def flags(self, path):
+if self.isdirty(path):
+if self._cache[path]['exists']:
+return self._cache[path]['flags']
+else:
+raise IOError("No such file or directory: %s" % self._path)
+else:
+return self._underlyingctx(path).flags()
+
+def write(self, path, data, flags=None):
+if data is None:
+raise error.ProgrammingError("data must be non-None")
+self._markdirty(path)
+self._cache[path]['exists'] = True
+self._cache[path]['data'] = data
+self._cache[path]['date'] = util.makedate()
+if flags is not None:
+self._cache[path]['flags'] = flags
+pass
+
+def setflags(self, path, l, x):
+self._markdirty(path)
+self._cache[path]['exists'] = True
+self._cache[path]['date'] = util.makedate()
+self._cache[path]['flags'] = (l and 'l' or '') + (x and 'x' or '')
+
+def remove(self, path):
+self._markdirty(path)
+self._cache[path]['exists'] = False
+self._cache[path]['data'] = None
+self._cache[path]['flags'] = None
+
+def exists(self, path):
+if self.isdirty(path):
+return self._cache[path]['exists']
+return self._underlyingctx(path).exists()
+
+def size(self, path):
+if self.isdirty(path):
+if self._cache[path]['exists']:
+return len(self._cache[path]['data'])
+else:
+raise IOError("No such file or directory: %s" % self._path)
+return self._underlyingctx(path).size()
+
+def flushall(self):
+for path in self._writeorder:
+if self._cache[path]['exists'] is True:
+self._underlyingctx(path).clearunknown()
+if self._cache[path]['data'] is not None:
+if self._cache[path]['flags'] is None:
+raise error.ProgrammingError('data set but not flags')
+self._underlyingctx(path).write(
+self._cache[path]['data'],
+self._cache[path]['flags'])
+else:
+self._underlyingctx(path).setflags(
+'l' in self._cache[path]['flags'],
+'x' in self._cache[path]['flags'])
+elif self._cache[path]['exists'] is False:
+self._underlyingctx(path).remove(path)
+else:
+continue
+self.clean()
+
+def isdirty(self, path):
+return path in self._cache
+
+def clean(self):
+self._cache = {}
+self._writeorder = []
+
+def _markdirty(self, path):
+if path not in self._cache:
+self._cache[path] = {
+'exists': None,
+'data': None,
+'flags': None,
+}
+self._writeorder.append(path)
+
+def filectx(self, path, filelog=None):
+return 

[PATCH] posix: update os.popen with subprocess (issue4746)

2017-09-03 Thread mlaneuville
# HG changeset patch
# User Matthieu Laneuville 
# Date 1504454402 -7200
#  Sun Sep 03 18:00:02 2017 +0200
# Node ID 3ad3112109da2bac9cb280f7a13f35897d55175c
# Parent  b2eb0aa445cbe7cadc8b7691c6266908adfc5057
# EXP-Topic issue4746
posix: update os.popen with subprocess (issue4746)

'hg import' can be configured to use a custom patch tool via the 'ui.patch'
option. However, it sometimes claims that the exit status of the tool is
different from what it really is.

posix.explainexit() was rewritten for the subprocess module, but
posix.popen() still calls os.popen(). This patch fixes the issue by replacing
the deprecated os.popen() with subprocess.Popen() in posix.popen().

diff -r b2eb0aa445cb -r 3ad3112109da mercurial/mail.py
--- a/mercurial/mail.py Tue Aug 22 21:21:43 2017 -0400
+++ b/mercurial/mail.py Sun Sep 03 18:00:02 2017 +0200
@@ -139,9 +139,11 @@
 cmdline = '%s -f %s %s' % (program, util.email(sender),
' '.join(map(util.email, recipients)))
 ui.note(_('sending mail: %s\n') % cmdline)
-fp = util.popen(cmdline, 'w')
+f = util.popen(cmdline, 'w')
+fp = f.stdin
 fp.write(msg)
-ret = fp.close()
+fp.close()
+ret = f.wait()
 if ret:
 raise error.Abort('%s %s' % (
 os.path.basename(program.split(None, 1)[0]),
diff -r b2eb0aa445cb -r 3ad3112109da mercurial/patch.py
--- a/mercurial/patch.pyTue Aug 22 21:21:43 2017 -0400
+++ b/mercurial/patch.pySun Sep 03 18:00:02 2017 +0200
@@ -2087,8 +2087,9 @@
 cwd = repo.root
 if cwd:
 args.append('-d %s' % util.shellquote(cwd))
-fp = util.popen('%s %s -p%d < %s' % (patcher, ' '.join(args), strip,
-   util.shellquote(patchname)))
+f = util.popen('%s %s -p%d < %s' % (patcher, ' '.join(args), strip,
+util.shellquote(patchname)))
+fp = f.stdout
 try:
 for line in util.iterfile(fp):
 line = line.rstrip()
@@ -2113,7 +2114,7 @@
 finally:
 if files:
 scmutil.marktouched(repo, files, similarity)
-code = fp.close()
+code = f.wait()
 if code:
 raise PatchError(_("patch command failed: %s") %
  util.explainexit(code)[0])
diff -r b2eb0aa445cb -r 3ad3112109da mercurial/posix.py
--- a/mercurial/posix.pyTue Aug 22 21:21:43 2017 -0400
+++ b/mercurial/posix.pySun Sep 03 18:00:02 2017 +0200
@@ -16,6 +16,7 @@
 import re
 import select
 import stat
+import subprocess
 import sys
 import tempfile
 import unicodedata
@@ -448,7 +449,12 @@
 return cmd
 
 def popen(command, mode='r'):
-return os.popen(command, mode)
+if 'r' in mode:
+return subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
+elif 'w' in mode:
+return subprocess.Popen(command, shell=True, stdin=subprocess.PIPE)
+else:
+raise ValueError
 
 def testpid(pid):
 '''return False if pid dead, True if running or not sure'''
diff -r b2eb0aa445cb -r 3ad3112109da tests/test-issue4746.t
--- /dev/null   Thu Jan 01 00:00:00 1970 +
+++ b/tests/test-issue4746.tSun Sep 03 18:00:02 2017 +0200
@@ -0,0 +1,30 @@
+  $ hg init fuzzy
+  $ cd fuzzy
+  $ echo line1 > a
+  $ echo line0 >> a
+  $ echo line3 >> a
+  $ hg ci -Am adda
+  adding a
+
+  $ echo line1 > a
+  $ echo line2 >> a
+  $ echo line0 >> a
+  $ echo line3 >> a
+  $ hg ci -m change a
+
+  $ hg export tip > fuzzy-tip.patch
+
+  $ hg up -C 0
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+  $ echo lines1 > a
+  $ echo lines0 >> a
+  $ echo lines1 >> a
+  $ echo lines0 >> a
+  $ hg ci -m brancha
+  created new head
+
+  $ hg import fuzzy-tip.patch --config ui.patch="patch --merge"
+  applying fuzzy-tip.patch
+  abort: patch command failed: exited with status 1
+  [255]
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 6 of 8] py3: use bytes[n:n + 1] to get bytes in templater._parsetemplate()

2017-09-03 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1504427837 -32400
#  Sun Sep 03 17:37:17 2017 +0900
# Node ID 6f837717bec80a273aa7263d1d2af0f68ff04237
# Parent  59a3de8a667ca07200449a64a4716ccbd7c54a93
py3: use bytes[n:n + 1] to get bytes in templater._parsetemplate()

diff --git a/mercurial/templater.py b/mercurial/templater.py
--- a/mercurial/templater.py
+++ b/mercurial/templater.py
@@ -169,7 +169,7 @@ def _parsetemplate(tmpl, start, stop, qu
 parsed.append(('string', parser.unescapestr(tmpl[pos:stop])))
 pos = stop
 break
-c = tmpl[n]
+c = tmpl[n:n + 1]
 bs = (n - pos) - len(tmpl[pos:n].rstrip('\\'))
 if bs % 2 == 1:
 # escaped (e.g. '\{', '\\\{', but not '\\{')
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 3 of 8] py3: fix type of regex literals in subrepo.py

2017-09-03 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1504418483 -32400
#  Sun Sep 03 15:01:23 2017 +0900
# Node ID 004d163d1bbc31825c134eb4d43e60b11ced61ca
# Parent  03f65a976779da5cfb8adf475a01ac0e14e42761
py3: fix type of regex literals in subrepo.py

diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py
--- a/mercurial/subrepo.py
+++ b/mercurial/subrepo.py
@@ -134,7 +134,7 @@ def state(ctx, ui):
 # However, we still want to allow back references to go
 # through unharmed, so we turn r'\\1' into r'\1'. Again,
 # extra escapes are needed because re.sub string decodes.
-repl = re.sub(r'([0-9]+)', r'\\\1', repl)
+repl = re.sub(br'([0-9]+)', br'\\\1', repl)
 try:
 src = re.sub(pattern, repl, src, 1)
 except re.error as e:
@@ -1154,7 +1154,7 @@ class svnsubrepo(abstractsubrepo):
 @propertycache
 def _svnversion(self):
 output, err = self._svncommand(['--version', '--quiet'], filename=None)
-m = re.search(r'^(\d+)\.(\d+)', output)
+m = re.search(br'^(\d+)\.(\d+)', output)
 if not m:
 raise error.Abort(_('cannot retrieve svn tool version'))
 return (int(m.group(1)), int(m.group(2)))
@@ -1373,11 +1373,11 @@ class gitsubrepo(abstractsubrepo):
 
 @staticmethod
 def _gitversion(out):
-m = re.search(r'^git version (\d+)\.(\d+)\.(\d+)', out)
+m = re.search(br'^git version (\d+)\.(\d+)\.(\d+)', out)
 if m:
 return (int(m.group(1)), int(m.group(2)), int(m.group(3)))
 
-m = re.search(r'^git version (\d+)\.(\d+)', out)
+m = re.search(br'^git version (\d+)\.(\d+)', out)
 if m:
 return (int(m.group(1)), int(m.group(2)), 0)
 
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 5 of 8] py3: fix type of attribute name in smartset.py

2017-09-03 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1504426493 -32400
#  Sun Sep 03 17:14:53 2017 +0900
# Node ID 59a3de8a667ca07200449a64a4716ccbd7c54a93
# Parent  4a0d22cd832998cc6211e4becf23d5e08a84058d
py3: fix type of attribute name in smartset.py

diff --git a/mercurial/smartset.py b/mercurial/smartset.py
--- a/mercurial/smartset.py
+++ b/mercurial/smartset.py
@@ -357,7 +357,7 @@ class baseset(abstractsmartset):
 
 def _fastsetop(self, other, op):
 # try to use native set operations as fast paths
-if (type(other) is baseset and '_set' in other.__dict__ and '_set' in
+if (type(other) is baseset and r'_set' in other.__dict__ and r'_set' in
 self.__dict__ and self._ascending is not None):
 s = baseset(data=getattr(self._set, op)(other._set),
 istopo=self._istopo)
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 7 of 8] py3: fix repr(util.url) to return system string

2017-09-03 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1504428683 -32400
#  Sun Sep 03 17:51:23 2017 +0900
# Node ID 2f19734c56c0227e004a849e8037378f9d930e7d
# Parent  6f837717bec80a273aa7263d1d2af0f68ff04237
py3: fix repr(util.url) to return system string

This is required on Python 3.

diff --git a/mercurial/util.py b/mercurial/util.py
--- a/mercurial/util.py
+++ b/mercurial/util.py
@@ -2804,6 +2804,7 @@ class url(object):
 if v is not None:
 setattr(self, a, urlreq.unquote(v))
 
+@encoding.strmethod
 def __repr__(self):
 attrs = []
 for a in ('scheme', 'user', 'passwd', 'host', 'port', 'path',
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 1 of 8] py3: fix type of regex literals in patch.py

2017-09-03 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1504422735 -32400
#  Sun Sep 03 16:12:15 2017 +0900
# Node ID 313ecdde1470bb3a0e1f9beced7e596b8004e456
# Parent  68afb88b51bb626cd25440e2df812f2306463b55
py3: fix type of regex literals in patch.py

diff --git a/mercurial/patch.py b/mercurial/patch.py
--- a/mercurial/patch.py
+++ b/mercurial/patch.py
@@ -205,10 +205,11 @@ def extract(ui, fileobj):
 
 # attempt to detect the start of a patch
 # (this heuristic is borrowed from quilt)
-diffre = re.compile(r'^(?:Index:[ \t]|diff[ \t]|RCS file: |'
-r'retrieving revision [0-9]+(\.[0-9]+)*$|'
-r'---[ \t].*?^\+\+\+[ \t]|'
-r'\*\*\*[ \t].*?^---[ \t])', re.MULTILINE|re.DOTALL)
+diffre = re.compile(br'^(?:Index:[ \t]|diff[ \t]|RCS file: |'
+br'retrieving revision [0-9]+(\.[0-9]+)*$|'
+br'---[ \t].*?^\+\+\+[ \t]|'
+br'\*\*\*[ \t].*?^---[ \t])',
+re.MULTILINE | re.DOTALL)
 
 data = {}
 fd, tmpname = tempfile.mkstemp(prefix='hg-patch-')
@@ -230,7 +231,7 @@ def extract(ui, fileobj):
 pend = subject.find(']')
 if pend >= 0:
 subject = subject[pend + 1:].lstrip()
-subject = re.sub(r'\n[ \t]+', ' ', subject)
+subject = re.sub(br'\n[ \t]+', ' ', subject)
 ui.debug('Subject: %s\n' % subject)
 if data['user']:
 ui.debug('From: %s\n' % data['user'])
@@ -1760,7 +1761,7 @@ def scanpatch(fp):
 - ('hunk',[hunk_lines])
 - ('range',   (-start,len, +start,len, proc))
 """
-lines_re = re.compile(r'@@ -(\d+),(\d+) \+(\d+),(\d+) @@\s*(.*)')
+lines_re = re.compile(br'@@ -(\d+),(\d+) \+(\d+),(\d+) @@\s*(.*)')
 lr = linereader(fp)
 
 def scanwhile(first, p):
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 8] py3: replace bytes[n] with bytes[n:n + 1] in patch.py where needed

2017-09-03 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1504423160 -32400
#  Sun Sep 03 16:19:20 2017 +0900
# Node ID 03f65a976779da5cfb8adf475a01ac0e14e42761
# Parent  313ecdde1470bb3a0e1f9beced7e596b8004e456
py3: replace bytes[n] with bytes[n:n + 1] in patch.py where needed

diff --git a/mercurial/patch.py b/mercurial/patch.py
--- a/mercurial/patch.py
+++ b/mercurial/patch.py
@@ -1693,7 +1693,7 @@ def pathtransform(path, strip, prefix):
  (count, strip, path))
 i += 1
 # consume '//' in the path
-while i < pathlen - 1 and path[i] == '/':
+while i < pathlen - 1 and path[i:i + 1] == '/':
 i += 1
 count -= 1
 return path[:i].lstrip(), prefix + path[i:].rstrip()
@@ -1788,7 +1788,7 @@ def scanpatch(fp):
 else:
 lr.push(fromfile)
 yield 'file', header
-elif line[0] == ' ':
+elif line[0:1] == ' ':
 yield 'context', scanwhile(line, lambda l: l[0] in ' \\')
 elif line[0] in '-+':
 yield 'hunk', scanwhile(line, lambda l: l[0] in '-+\\')
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 4 of 8] py3: fix mixed bytes/unicode in revsetlang._aliassyminitletters

2017-09-03 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1504425803 -32400
#  Sun Sep 03 17:03:23 2017 +0900
# Node ID 4a0d22cd832998cc6211e4becf23d5e08a84058d
# Parent  004d163d1bbc31825c134eb4d43e60b11ced61ca
py3: fix mixed bytes/unicode in revsetlang._aliassyminitletters

diff --git a/mercurial/revsetlang.py b/mercurial/revsetlang.py
--- a/mercurial/revsetlang.py
+++ b/mercurial/revsetlang.py
@@ -473,7 +473,7 @@ def optimize(tree):
 
 # the set of valid characters for the initial letter of symbols in
 # alias declarations and definitions
-_aliassyminitletters = _syminitletters | set(pycompat.sysstr('$'))
+_aliassyminitletters = _syminitletters | {'$'}
 
 def _parsewith(spec, lookup=None, syminitletters=None):
 """Generate a parse tree of given spec with given tokenizing options
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D605: phabricator: add a config to use curl for communication

2017-09-03 Thread yuja (Yuya Nishihara)
yuja added inline comments.

INLINE COMMENTS

> phabricator.py:122
> +if curlcmd:
> +sin, sout = util.popen2('%s -d @- %s' % (curlcmd, 
> util.shellquote(url)))
> +sin.write(data)

Maybe it's better to insert `--` for extra safety.

REPOSITORY
  rHG Mercurial

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

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


D610: check-code: forbid "\S" in egrep regular expression

2017-09-03 Thread quark (Jun Wu)
This revision was automatically updated to reflect the committed changes.
Closed by commit rHG11499bad0359: check-code: forbid "\S" in egrep regular 
expression (authored by quark).

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D610?vs=1567=1587

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

AFFECTED FILES
  contrib/check-code.py
  tests/test-context-metadata.t

CHANGE DETAILS

diff --git a/tests/test-context-metadata.t b/tests/test-context-metadata.t
--- a/tests/test-context-metadata.t
+++ b/tests/test-context-metadata.t
@@ -36,7 +36,7 @@
   date:Thu Jan 01 00:00:00 1970 +
   summary: Changed
   
-  $ hg --config extensions.metaedit=$TESTTMP/metaedit.py metaedit 'parents=0' 
2>&1 | egrep '^\S*Error'
+  $ hg --config extensions.metaedit=$TESTTMP/metaedit.py metaedit 'parents=0' 
2>&1 | egrep '^RuntimeError'
   RuntimeError: can't reuse the manifest: its p1 doesn't match the new ctx p1
 
   $ hg --config extensions.metaedit=$TESTTMP/metaedit.py metaedit 'user=foo 
'
diff --git a/contrib/check-code.py b/contrib/check-code.py
--- a/contrib/check-code.py
+++ b/contrib/check-code.py
@@ -119,6 +119,7 @@
 (r'\[[^\]]+==', '[ foo == bar ] is a bashism, use [ foo = bar ] instead'),
 (r'(^|\|\s*)grep (-\w\s+)*[^|]*[(|]\w',
  "use egrep for extended grep syntax"),
+(r'(^|\|\s*)e?grep .*\\S', "don't use \\S in regular expression"),
 (r'(?https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D441: revset: optimize "draft() & ::x" pattern

2017-09-03 Thread quark (Jun Wu)
This revision was automatically updated to reflect the committed changes.
Closed by commit rHG68afb88b51bb: revset: optimize "draft() & ::x" pattern 
(authored by quark).

CHANGED PRIOR TO COMMIT
  https://phab.mercurial-scm.org/D441?vs=1571=1591#toc

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D441?vs=1571=1591

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

AFFECTED FILES
  mercurial/dagop.py
  mercurial/revset.py
  mercurial/revsetlang.py
  tests/test-revset.t

CHANGE DETAILS

diff --git a/tests/test-revset.t b/tests/test-revset.t
--- a/tests/test-revset.t
+++ b/tests/test-revset.t
@@ -4321,3 +4321,147 @@
 
   $ hg log -r 'successors(B+A)-contentdivergent()-obsolete()' -T '{desc}\n'
   Z
+
+Test `draft() & ::x` optimization
+
+  $ hg init $TESTTMP/repo2
+  $ cd $TESTTMP/repo2
+  $ hg debugdrawdag <<'EOS'
+  >   P5 S1
+  >|  |
+  > S2 | D3
+  >   \|/
+  >   P4
+  >|
+  >   P3 D2
+  >|  |
+  >   P2 D1
+  >|/
+  >   P1
+  >|
+  >   P0
+  > EOS
+  $ hg phase --public -r P5
+  $ hg phase --force --secret -r S1+S2
+  $ hg log -G -T '{rev} {desc} {phase}' -r 'sort(all(), topo, 
topo.firstbranch=P5)'
+  o  8 P5 public
+  |
+  | o  10 S1 secret
+  | |
+  | o  7 D3 draft
+  |/
+  | o  9 S2 secret
+  |/
+  o  6 P4 public
+  |
+  o  5 P3 public
+  |
+  o  3 P2 public
+  |
+  | o  4 D2 draft
+  | |
+  | o  2 D1 draft
+  |/
+  o  1 P1 public
+  |
+  o  0 P0 public
+  
+  $ hg debugrevspec --verify -p analyzed -p optimized 'draft() & 
::(((S1+D1+P5)-D3)+S2)'
+  * analyzed:
+  (and
+(func
+  ('symbol', 'draft')
+  None)
+(func
+  ('symbol', 'ancestors')
+  (or
+(list
+  (and
+(or
+  (list
+('symbol', 'S1')
+('symbol', 'D1')
+('symbol', 'P5')))
+(not
+  ('symbol', 'D3')))
+  ('symbol', 'S2')
+  * optimized:
+  (func
+('symbol', '_phaseandancestors')
+(list
+  ('symbol', 'draft')
+  (or
+(list
+  (difference
+(func
+  ('symbol', '_list')
+  ('string', 'S1\x00D1\x00P5'))
+('symbol', 'D3'))
+  ('symbol', 'S2')
+  $ hg debugrevspec --verify -p analyzed -p optimized 'secret() & ::9'
+  * analyzed:
+  (and
+(func
+  ('symbol', 'secret')
+  None)
+(func
+  ('symbol', 'ancestors')
+  ('symbol', '9')))
+  * optimized:
+  (func
+('symbol', '_phaseandancestors')
+(list
+  ('symbol', 'secret')
+  ('symbol', '9')))
+  $ hg debugrevspec --verify -p analyzed -p optimized '7 & ( (not public()) & 
::(tag()) )'
+  * analyzed:
+  (and
+('symbol', '7')
+(and
+  (not
+(func
+  ('symbol', 'public')
+  None))
+  (func
+('symbol', 'ancestors')
+(func
+  ('symbol', 'tag')
+  None
+  * optimized:
+  (and
+('symbol', '7')
+(func
+  ('symbol', '_phaseandancestors')
+  (list
+('symbol', '_notpublic')
+(func
+  ('symbol', 'tag')
+  None
+  $ hg debugrevspec --verify -p optimized '(not public()) & 
ancestors(S1+D2+P5, 1)'
+  * optimized:
+  (and
+(func
+  ('symbol', '_notpublic')
+  None)
+(func
+  ('symbol', 'ancestors')
+  (list
+(func
+  ('symbol', '_list')
+  ('string', 'S1\x00D2\x00P5'))
+('symbol', '1'
+  $ hg debugrevspec --verify -p optimized '(not public()) & 
ancestors(S1+D2+P5, depth=1)'
+  * optimized:
+  (and
+(func
+  ('symbol', '_notpublic')
+  None)
+(func
+  ('symbol', 'ancestors')
+  (list
+(func
+  ('symbol', '_list')
+  ('string', 'S1\x00D2\x00P5'))
+(keyvalue
+  ('symbol', 'depth')
+  ('symbol', '1')
diff --git a/mercurial/revsetlang.py b/mercurial/revsetlang.py
--- a/mercurial/revsetlang.py
+++ b/mercurial/revsetlang.py
@@ -369,6 +369,11 @@
 wb, tb = _optimize(x[2], True)
 w = min(wa, wb)
 
+# (draft/secret/_notpublic() & ::x) have a fast path
+m = _match('_() & ancestors(_)', ('and', ta, tb))
+if m and getsymbol(m[1]) in {'draft', 'secret', '_notpublic'}:
+return w, _build('_phaseandancestors(_, _)', m[1], m[2])
+
 # (::x and not ::y)/(not ::y and ::x) have a fast path
 m = _matchonly(ta, tb) or _matchonly(tb, ta)
 if m:
diff --git a/mercurial/revset.py b/mercurial/revset.py
--- a/mercurial/revset.py
+++ b/mercurial/revset.py
@@ -1577,6 +1577,37 @@
 getargs(x, 0, 0, "_notpublic takes no arguments")
 return _phase(repo, subset, phases.draft, phases.secret)
 
+# for internal use
+@predicate('_phaseandancestors(phasename, set)', safe=True)
+def _phaseandancestors(repo, subset, x):
+# equivalent to (phasename() & ancestors(set)) but more efficient
+# phasename could be one of 'draft', 'secret', or '_notpublic'
+args = getargs(x, 2, 

D515: phabricator: standardize colors

2017-09-03 Thread quark (Jun Wu)
This revision was automatically updated to reflect the committed changes.
Closed by commit rHG941c33cfde81: phabricator: standardize colors (authored by 
quark).

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D515?vs=1546=1589

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

AFFECTED FILES
  contrib/phabricator.py

CHANGE DETAILS

diff --git a/contrib/phabricator.py b/contrib/phabricator.py
--- a/contrib/phabricator.py
+++ b/contrib/phabricator.py
@@ -59,6 +59,15 @@
 cmdtable = {}
 command = registrar.command(cmdtable)
 
+colortable = {
+'phabricator.action.created': 'green',
+'phabricator.action.skipped': 'magenta',
+'phabricator.action.updated': 'magenta',
+'phabricator.desc': '',
+'phabricator.drev': 'bold',
+'phabricator.node': '',
+}
+
 def urlencodenested(params):
 """like urlencode, but works with nested parameters.
 
@@ -413,9 +422,9 @@
 diffmap[ctx.node()] = diff
 newrevid = int(revision[r'object'][r'id'])
 if revid:
-action = _('updated')
+action = 'updated'
 else:
-action = _('created')
+action = 'created'
 
 # Create a local tag to note the association, if commit message
 # does not have it already
@@ -428,10 +437,18 @@
 # Nothing changed. But still set "newrevid" so the next revision
 # could depend on this one.
 newrevid = revid
-action = _('skipped')
+action = 'skipped'
 
-ui.write(_('D%s: %s - %s: %s\n') % (newrevid, action, ctx,
-ctx.description().split('\n')[0]))
+actiondesc = ui.label(
+{'created': _('created'),
+ 'skipped': _('skipped'),
+ 'updated': _('updated')}[action],
+'phabricator.action.%s' % action)
+drevdesc = ui.label('D%s' % newrevid, 'phabricator.drev')
+nodedesc = ui.label(bytes(ctx), 'phabricator.node')
+desc = ui.label(ctx.description().split('\n')[0], 'phabricator.desc')
+ui.write(_('%s - %s - %s: %s\n') % (drevdesc, actiondesc, nodedesc,
+desc))
 drevids.append(newrevid)
 lastrevid = newrevid
 



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


D608: wireproto: do not abort after successful lookup

2017-09-03 Thread spectral (Kyle Lippincott)
This revision was automatically updated to reflect the committed changes.
Closed by commit rHG6c6169f71b8d: wireproto: do not abort after successful 
lookup (authored by spectral).

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D608?vs=1560=1588

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

AFFECTED FILES
  mercurial/wireproto.py

CHANGE DETAILS

diff --git a/mercurial/wireproto.py b/mercurial/wireproto.py
--- a/mercurial/wireproto.py
+++ b/mercurial/wireproto.py
@@ -235,7 +235,8 @@
 success, data = d[:-1].split(" ", 1)
 if int(success):
 yield bin(data)
-self._abort(error.RepoError(data))
+else:
+self._abort(error.RepoError(data))
 
 @batchable
 def heads(self):



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


D605: phabricator: add a config to use curl for communication

2017-09-03 Thread quark (Jun Wu)
This revision was automatically updated to reflect the committed changes.
Closed by commit rHG8b659b7388c0: phabricator: add a config to use curl for 
communication (authored by quark).

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D605?vs=1568=1590

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

AFFECTED FILES
  contrib/phabricator.py

CHANGE DETAILS

diff --git a/contrib/phabricator.py b/contrib/phabricator.py
--- a/contrib/phabricator.py
+++ b/contrib/phabricator.py
@@ -28,6 +28,11 @@
 # callsign is "FOO".
 callsign = FOO
 
+# curl command to use. If not set (default), use builtin HTTP library to
+# communicate. If set, use the specified curl command. This could be useful
+# if you need to specify advanced options that is not easily supported by
+# the internal library.
+curlcmd = curl --connect-timeout 2 --retry 3 --silent
 """
 
 from __future__ import absolute_import
@@ -108,12 +113,20 @@
 """call Conduit API, params is a dict. return json.loads result, or None"""
 host, token = readurltoken(repo)
 url, authinfo = util.url('/'.join([host, 'api', name])).authinfo()
-urlopener = urlmod.opener(repo.ui, authinfo)
 repo.ui.debug('Conduit Call: %s %s\n' % (url, params))
 params = params.copy()
 params['api.token'] = token
-request = util.urlreq.request(url, data=urlencodenested(params))
-body = urlopener.open(request).read()
+data = urlencodenested(params)
+curlcmd = repo.ui.config('phabricator', 'curlcmd')
+if curlcmd:
+sin, sout = util.popen2('%s -d @- %s' % (curlcmd, 
util.shellquote(url)))
+sin.write(data)
+sin.close()
+body = sout.read()
+else:
+urlopener = urlmod.opener(repo.ui, authinfo)
+request = util.urlreq.request(url, data=data)
+body = urlopener.open(request).read()
 repo.ui.debug('Conduit Response: %s\n' % body)
 parsed = json.loads(body)
 if parsed.get(r'error_code'):



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


D609: check-code: forbid using bash in shebang

2017-09-03 Thread quark (Jun Wu)
This revision was automatically updated to reflect the committed changes.
Closed by commit rHGe267d4ee4f2d: check-code: forbid using bash in shebang 
(authored by quark).

CHANGED PRIOR TO COMMIT
  https://phab.mercurial-scm.org/D609?vs=1566=1586#toc

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D609?vs=1566=1586

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

AFFECTED FILES
  contrib/check-code.py

CHANGE DETAILS

diff --git a/contrib/check-code.py b/contrib/check-code.py
--- a/contrib/check-code.py
+++ b/contrib/check-code.py
@@ -119,7 +119,8 @@
 (r'\[[^\]]+==', '[ foo == bar ] is a bashism, use [ foo = bar ] instead'),
 (r'(^|\|\s*)grep (-\w\s+)*[^|]*[(|]\w',
  "use egrep for extended grep syntax"),
-(r'/bin/', "don't use explicit paths for tools"),
+(r'(? \1)", rephere),
-(r"( +)(#([^\n]*\S)?)", repcomment),
+(r"( +)(#([^!][^\n]*\S)?)", repcomment),
 ]
 
 pypats = [



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


D596: amend: add tests for amending only some files from commit to be amended

2017-09-03 Thread singhsrb (Saurabh Singh)
This revision was automatically updated to reflect the committed changes.
Closed by commit rHG6fb5a06b92c6: amend: add tests for amending only some files 
from commit to be amended (authored by singhsrb).

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D596?vs=1565=1585

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

AFFECTED FILES
  tests/test-commit-amend.t

CHANGE DETAILS

diff --git a/tests/test-commit-amend.t b/tests/test-commit-amend.t
--- a/tests/test-commit-amend.t
+++ b/tests/test-commit-amend.t
@@ -1174,3 +1174,96 @@
   new mode 100755
   
 #endif
+
+Test amend with file inclusion options
+--
+
+These tests ensure that we are always amending some files that were part of the
+pre-amend commit. We want to test that the remaining files in the pre-amend
+commit were not changed in the amended commit. We do so by performing a diff of
+the amended commit against its parent commit.
+  $ cd ..
+  $ hg init testfileinclusions
+  $ cd testfileinclusions
+  $ echo a > a
+  $ echo b > b
+  $ hg commit -Aqm "Adding a and b"
+
+Only add changes to a particular file
+  $ echo a >> a
+  $ echo b >> b
+  $ hg commit --amend -I a
+  $ hg diff --git -r null -r .
+  diff --git a/a b/a
+  new file mode 100644
+  --- /dev/null
+  +++ b/a
+  @@ -0,0 +1,2 @@
+  +a
+  +a
+  diff --git a/b b/b
+  new file mode 100644
+  --- /dev/null
+  +++ b/b
+  @@ -0,0 +1,1 @@
+  +b
+
+  $ echo a >> a
+  $ hg commit --amend b
+  $ hg diff --git -r null -r .
+  diff --git a/a b/a
+  new file mode 100644
+  --- /dev/null
+  +++ b/a
+  @@ -0,0 +1,2 @@
+  +a
+  +a
+  diff --git a/b b/b
+  new file mode 100644
+  --- /dev/null
+  +++ b/b
+  @@ -0,0 +1,2 @@
+  +b
+  +b
+
+Exclude changes to a particular file
+  $ echo b >> b
+  $ hg commit --amend -X a
+  $ hg diff --git -r null -r .
+  diff --git a/a b/a
+  new file mode 100644
+  --- /dev/null
+  +++ b/a
+  @@ -0,0 +1,2 @@
+  +a
+  +a
+  diff --git a/b b/b
+  new file mode 100644
+  --- /dev/null
+  +++ b/b
+  @@ -0,0 +1,3 @@
+  +b
+  +b
+  +b
+
+Check the addremove flag
+  $ echo c > c
+  $ rm a
+  $ hg commit --amend -A
+  removing a
+  adding c
+  $ hg diff --git -r null -r .
+  diff --git a/b b/b
+  new file mode 100644
+  --- /dev/null
+  +++ b/b
+  @@ -0,0 +1,3 @@
+  +b
+  +b
+  +b
+  diff --git a/c b/c
+  new file mode 100644
+  --- /dev/null
+  +++ b/c
+  @@ -0,0 +1,1 @@
+  +c



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


D611: nlink: use a random temp file name for checking

2017-09-03 Thread yuja (Yuya Nishihara)
yuja requested changes to this revision.
yuja added inline comments.
This revision now requires changes to proceed.

INLINE COMMENTS

> util.py:1458
>  # work around issue2543 (or testfile may get lost on Samba shares)
> -f1 = testfile + ".hgtmp1"
> -if os.path.lexists(f1):
> -return False
> -try:
> -posixfile(f1, 'w').close()
> -except IOError:
> -try:
> -os.unlink(f1)
> -except OSError:
> -pass
> -return False
> -
> -f2 = testfile + ".hgtmp2"
> +fd, f1 = tempfile.mkstemp(prefix='.%s-' % os.path.basename(testfile),
> +  suffix='1~', dir=os.path.dirname(testfile))

mkstemp() may raise OSError, which should be caught as before.

REPOSITORY
  rHG Mercurial

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

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


D441: revset: optimize "draft() & ::x" pattern

2017-09-03 Thread yuja (Yuya Nishihara)
yuja accepted this revision.
yuja added a comment.
This revision is now accepted and ready to land.


  Queued, thanks. I've removed `_()` because `_phaseandancestors()` is an 
internal function.

INLINE COMMENTS

> revset.py:1607
> +if phasename == 'draft': # need to remove secret changesets
> +revs = revs.filter(lambda r: getphase(repo, r) == draft)
> +return subset & revs

`revs & phasecache.getrevset(repo, [phasename])` might be
slightly faster, but I don't think it would make any noticeable difference.

> revsetlang.py:373
> +# (draft/secret/_notpublic() & ::x) have a fast path
> +m = _match('_() & ancestors(_)', ('and', ta, tb))
> +if m and getsymbol(m[1]) in {'draft', 'secret', '_notpublic'}:

Perhaps `::x & phasename()` can be optimized, too.

REPOSITORY
  rHG Mercurial

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

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


D583: commands: correctly show inactive multiheaded branches

2017-09-03 Thread the31k
the31k added inline comments.

INLINE COMMENTS

> test-branches.t:432
> -  3 files updated, 0 files merged, 2 files removed, 0 files unresolved
> -  $ hg commit -d '9 0' --close-branch -m 'reclosing this branch'
>$ hg up -C b

I decided to move this commit before multihead branches testing takes place to 
keep this commit's revision number. Named the section "Reclose branch".

REPOSITORY
  rHG Mercurial

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

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


D583: commands: correctly show inactive multiheaded branches

2017-09-03 Thread the31k
the31k updated this revision to Diff 1584.
the31k edited the summary of this revision.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D583?vs=1476=1584

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

AFFECTED FILES
  mercurial/branchmap.py
  mercurial/commands.py
  tests/test-branches.t

CHANGE DETAILS

diff --git a/tests/test-branches.t b/tests/test-branches.t
--- a/tests/test-branches.t
+++ b/tests/test-branches.t
@@ -418,6 +418,131 @@
   date:Thu Jan 01 00:00:09 1970 +
   summary: prune bad branch
   
+
+reclose branch
+
+  $ hg up -C c
+  3 files updated, 0 files merged, 2 files removed, 0 files unresolved
+  $ hg commit -d '9 0' --close-branch -m 'reclosing this branch'
+  $ hg branches
+  b 13:e23b5505d1ad
+  a branch name much longer than the default justification used by branches 
7:10ff5895aa57
+  a  5:d8cbc61dbaa6 (inactive)
+  default0:19709c5a4e75 (inactive)
+  $ hg branches --closed
+  b 13:e23b5505d1ad
+  a branch name much longer than the default justification used by branches 
7:10ff5895aa57
+  c 14:f894c25619d3 (closed)
+  a  5:d8cbc61dbaa6 (inactive)
+  default0:19709c5a4e75 (inactive)
+
+multihead branch
+
+  $ hg up -C default
+  0 files updated, 0 files merged, 3 files removed, 0 files unresolved
+  $ hg branch m
+  marked working directory as branch m
+  $ touch m
+  $ hg add m
+  $ hg commit -d '10 0' -m 'multihead base'
+  $ echo "m1" >m
+  $ hg commit -d '10 0' -m 'head 1'
+  $ hg up -C .^
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ echo "m2" >m
+  $ hg commit -d '10 0' -m 'head 2'
+  created new head
+  $ hg log -b m
+  changeset:   17:df343b0df04f
+  branch:  m
+  tag: tip
+  parent:  15:f3447637f53e
+  user:test
+  date:Thu Jan 01 00:00:10 1970 +
+  summary: head 2
+  
+  changeset:   16:a58ca5d3bdf3
+  branch:  m
+  user:test
+  date:Thu Jan 01 00:00:10 1970 +
+  summary: head 1
+  
+  changeset:   15:f3447637f53e
+  branch:  m
+  parent:  0:19709c5a4e75
+  user:test
+  date:Thu Jan 01 00:00:10 1970 +
+  summary: multihead base
+  
+  $ hg heads --topo m
+  changeset:   17:df343b0df04f
+  branch:  m
+  tag: tip
+  parent:  15:f3447637f53e
+  user:test
+  date:Thu Jan 01 00:00:10 1970 +
+  summary: head 2
+  
+  changeset:   16:a58ca5d3bdf3
+  branch:  m
+  user:test
+  date:Thu Jan 01 00:00:10 1970 +
+  summary: head 1
+  
+  $ hg branches
+  m 17:df343b0df04f
+  b 13:e23b5505d1ad
+  a branch name much longer than the default justification used by branches 
7:10ff5895aa57
+  a  5:d8cbc61dbaa6 (inactive)
+  default0:19709c5a4e75 (inactive)
+
+partially merge multihead branch
+
+  $ hg up -C default
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ hg branch md
+  marked working directory as branch md
+  $ hg merge m
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ hg commit -d '11 0' -m 'merge head 2'
+  $ hg heads --topo m
+  changeset:   16:a58ca5d3bdf3
+  branch:  m
+  user:test
+  date:Thu Jan 01 00:00:10 1970 +
+  summary: head 1
+  
+  $ hg branches
+  md18:c914c99f1fbb
+  m 17:df343b0df04f
+  b 13:e23b5505d1ad
+  a branch name much longer than the default justification used by branches 
7:10ff5895aa57
+  a  5:d8cbc61dbaa6 (inactive)
+  default0:19709c5a4e75 (inactive)
+
+partially close multihead branch
+
+  $ hg up -C a58ca5d3bdf3
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg commit -d '12 0' -m 'close head 1' --close-branch
+  $ hg heads --topo m
+  changeset:   19:cd21a80baa3d
+  branch:  m
+  tag: tip
+  parent:  16:a58ca5d3bdf3
+  user:test
+  date:Thu Jan 01 00:00:12 1970 +
+  summary: close head 1
+  
+  $ hg branches
+  md18:c914c99f1fbb
+  b 13:e23b5505d1ad
+  a branch name much longer than the default justification used by branches 
7:10ff5895aa57
+  m 17:df343b0df04f (inactive)
+  a  5:d8cbc61dbaa6 (inactive)
+  default0:19709c5a4e75 (inactive)
+
 default branch colors:
 
   $ cat <> $HGRCPATH
@@ -427,22 +552,23 @@
   > mode = ansi
   > EOF
 
-  $ hg up -C c
-  3 files updated, 0 files merged, 2 files removed, 0 files unresolved
-  $ hg commit -d 

D588: win32: use fewer system calls for unlink()

2017-09-03 Thread abuehl (Adrian Buehlmann)
abuehl added inline comments.

INLINE COMMENTS

> win32.py:537
> +if e.errno == errno.ENOENT:
> +raise
> +

why continue on errors != ENOENT ?

REPOSITORY
  rHG Mercurial

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

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