D3852: namespaces: let namespaces override singlenode() definition

2018-06-27 Thread martinvonz (Martin von Zweigbergk)
martinvonz updated this revision to Diff 9333.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D3852?vs=9331=9333

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

AFFECTED FILES
  mercurial/namespaces.py

CHANGE DETAILS

diff --git a/mercurial/namespaces.py b/mercurial/namespaces.py
--- a/mercurial/namespaces.py
+++ b/mercurial/namespaces.py
@@ -95,21 +95,16 @@
 
 def singlenode(self, repo, name):
 """
-Return the 'best' node for the given name. Best means the first node
-in the first nonempty list returned by a name-to-nodes mapping function
-in the defined precedence order.
+Return the 'best' node for the given name. What's best is defined
+by the namespace's singlenode() function. The first match returned by
+a namespace in the defined precedence order is used.
 
 Raises a KeyError if there is no such node.
 """
 for ns, v in self._names.iteritems():
-n = v.namemap(repo, name)
+n = v.singlenode(repo, name)
 if n:
-# return max revision number
-if len(n) > 1:
-cl = repo.changelog
-maxrev = max(cl.rev(node) for node in n)
-return cl.node(maxrev)
-return n[0]
+return n
 raise KeyError(_('no such name: %s') % name)
 
 class namespace(object):
@@ -142,7 +137,7 @@
 
 def __init__(self, name, templatename=None, logname=None, colorname=None,
  logfmt=None, listnames=None, namemap=None, nodemap=None,
- deprecated=None, builtin=False):
+ deprecated=None, builtin=False, singlenode=None):
 """create a namespace
 
 name: the namespace to be registered (in plural form)
@@ -158,6 +153,7 @@
 nodemap: function that inputs a node, output name(s)
 deprecated: set of names to be masked for ordinary use
 builtin: whether namespace is implemented by core Mercurial
+singlenode: function that inputs a name, output best node (or None)
 """
 self.name = name
 self.templatename = templatename
@@ -167,6 +163,18 @@
 self.listnames = listnames
 self.namemap = namemap
 self.nodemap = nodemap
+if not singlenode:
+def singlenode(repo, name):
+n = self.namemap(repo, name)
+if n:
+# return max revision number
+if len(n) > 1:
+cl = repo.changelog
+maxrev = max(cl.rev(node) for node in n)
+return cl.node(maxrev)
+return n[0]
+return None
+self.singlenode = singlenode
 
 # if logname is not specified, use the template name as backup
 if self.logname is None:



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


D3851: tests: pass "rev" argument to commands.update() as string

2018-06-27 Thread martinvonz (Martin von Zweigbergk)
martinvonz updated this revision to Diff 9332.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D3851?vs=9330=9332

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

AFFECTED FILES
  tests/test-basic.t

CHANGE DETAILS

diff --git a/tests/test-basic.t b/tests/test-basic.t
--- a/tests/test-basic.t
+++ b/tests/test-basic.t
@@ -64,7 +64,7 @@
   > from mercurial import ui, hg, commands
   > myui = ui.ui.load()
   > repo = hg.repository(myui, path=b'.')
-  > commands.update(myui, repo, rev=0)
+  > commands.update(myui, repo, rev="0")
   > EOF
   $ hg up null
   0 files updated, 0 files merged, 1 files removed, 0 files unresolved



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


D3852: namespaces: let namespaces override singlenode() definition

2018-06-27 Thread martinvonz (Martin von Zweigbergk)
martinvonz created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  Some namespaces have multiple nodes per name (meaning that their
  namemap() returns multiple nodes). One such namespace is the "topics"
  namespace (from the evolve repo). We also have our own internal
  namespace at Google (for review units) that has multiple nodes per
  name. These namespaces may not want to use the default "pick highest
  revnum" resolution that we currently use when resolving a name to a
  single node. As an example, they may decide that `hg co ` should
  check out a commit that's last in some sense even if an earlier commit
  had just been amended and thus had a higher revnum [1]. This patch
  gives the namespace the option to continue to return multiple nodes
  and to override how the best node is picked. Allowing namespaces to
  override that may also be useful as an optimization (it may be cheaper
  for the namespace to find just that node).
  
  I have been arguing (in https://phab.mercurial-scm.org/D3715) for using all 
the nodes returned from
  namemap() when resolving the symbol to a revset, so e.g. `hg log -r
  stable` would resolve to *all* nodes on stable, not just the one with
  the highest revnum (except that I don't actually think we should
  change it for the branch namespace because of BC). Most people seem
  opposed to that. If we decide not to do it, I think we can deprecate
  the namemap() function in favor of the new singlenode() (I find it
  weird to have namespaces, like the branch namespace, where namemap()
  isn't nodemap()'s inverse). I therefore think this patch makes sense
  regardless of what we decide on that issue.
  
  [1] Actually, even the branch namespace would have wanted to override
  
singlenode() if it had supported multiple nodes. That's because
closes branch heads are mostly ignored, so "hg co default" will
not check out the highest-revnum node if that's a closed head.

REPOSITORY
  rHG Mercurial

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

AFFECTED FILES
  mercurial/namespaces.py

CHANGE DETAILS

diff --git a/mercurial/namespaces.py b/mercurial/namespaces.py
--- a/mercurial/namespaces.py
+++ b/mercurial/namespaces.py
@@ -95,21 +95,16 @@
 
 def singlenode(self, repo, name):
 """
-Return the 'best' node for the given name. Best means the first node
-in the first nonempty list returned by a name-to-nodes mapping function
-in the defined precedence order.
+Return the 'best' node for the given name. What's best is defined
+by the namespace's singlenode() function. The first match returned by
+a namespace in the defined precedence order is used.
 
 Raises a KeyError if there is no such node.
 """
 for ns, v in self._names.iteritems():
-n = v.namemap(repo, name)
+n = v.singlenode(repo, name)
 if n:
-# return max revision number
-if len(n) > 1:
-cl = repo.changelog
-maxrev = max(cl.rev(node) for node in n)
-return cl.node(maxrev)
-return n[0]
+return n
 raise KeyError(_('no such name: %s') % name)
 
 class namespace(object):
@@ -142,7 +137,7 @@
 
 def __init__(self, name, templatename=None, logname=None, colorname=None,
  logfmt=None, listnames=None, namemap=None, nodemap=None,
- deprecated=None, builtin=False):
+ deprecated=None, builtin=False, singlenode=None):
 """create a namespace
 
 name: the namespace to be registered (in plural form)
@@ -158,6 +153,7 @@
 nodemap: function that inputs a node, output name(s)
 deprecated: set of names to be masked for ordinary use
 builtin: whether namespace is implemented by core Mercurial
+singlenode: function that inputs a name, output best node (or None)
 """
 self.name = name
 self.templatename = templatename
@@ -167,6 +163,18 @@
 self.listnames = listnames
 self.namemap = namemap
 self.nodemap = nodemap
+if not singlenode:
+def singlenode(repo, name):
+n = self.namemap(repo, name)
+if n:
+# return max revision number
+if len(n) > 1:
+cl = repo.changelog
+maxrev = max(cl.rev(node) for node in n)
+return cl.node(maxrev)
+return n[0]
+return None
+self.singlenode = singlenode
 
 # if logname is not specified, use the template name as backup
 if self.logname is None:



To: martinvonz, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org

D3851: tests: pass "rev" argument to commands.update() as string

2018-06-27 Thread martinvonz (Martin von Zweigbergk)
martinvonz created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  commands.update() normally gets its "rev" argument as a string, but
  test-basic.t was passing an integer. That happened to work, but we
  shouldn't rely on it.

REPOSITORY
  rHG Mercurial

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

AFFECTED FILES
  tests/test-basic.t

CHANGE DETAILS

diff --git a/tests/test-basic.t b/tests/test-basic.t
--- a/tests/test-basic.t
+++ b/tests/test-basic.t
@@ -64,7 +64,7 @@
   > from mercurial import ui, hg, commands
   > myui = ui.ui.load()
   > repo = hg.repository(myui, path=b'.')
-  > commands.update(myui, repo, rev=0)
+  > commands.update(myui, repo, rev="0")
   > EOF
   $ hg up null
   0 files updated, 0 files merged, 1 files removed, 0 files unresolved



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


Re: [PATCH STABLE v2] hghave: don't claim we have `tic` if it's NetBSD's binary (issue5698)

2018-06-27 Thread Kyle Lippincott
also looks good

On Wed, Jun 27, 2018 at 8:50 AM, Augie Fackler  wrote:

> # HG changeset patch
> # User Augie Fackler 
> # Date 1529932907 14400
> #  Mon Jun 25 09:21:47 2018 -0400
> # Branch stable
> # Node ID af7d21e1e44c1bb756af28b5978d3f7ee7d50eda
> # Parent  0b63a6743010dfdbf8a8154186e119949bdaa1cc
> hghave: don't claim we have `tic` if it's NetBSD's binary (issue5698)
>
> test-status-color.t fails with different output because of mismatches
> between how `tic` behaves from NetBSD's base system and ncurses'
> verison (if I understand the bug right). The bug suggested using -V to
> avoid the issue, so we'll do that.
>
> diff --git a/tests/hghave.py b/tests/hghave.py
> --- a/tests/hghave.py
> +++ b/tests/hghave.py
> @@ -545,7 +545,11 @@ def has_tic():
>  try:
>  import curses
>  curses.COLOR_BLUE
> -return matchoutput('test -x "`which tic`"', br'')
> +if not matchoutput('test -x "`which tic`"', br''):
> +return False
> +# We have a tic, but make sure it's not the NetBSD system one
> +# which doesn't pass test-status-color.t.
> +return not matchoutput('tic -V 2>&1', br'unknown option')
>  except ImportError:
>  return False
>
> ___
> Mercurial-devel mailing list
> Mercurial-devel@mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
>
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 2 of 2] revlog: do inclusive descendant testing (API)

2018-06-27 Thread Martin von Zweigbergk via Mercurial-devel
On Mon, Jun 25, 2018 at 9:54 AM Paul Morelle 
wrote:

> On 21/06/18 18:30, Martin von Zweigbergk wrote:
>
> On Thu, Jun 21, 2018 at 7:24 AM Paul Morelle 
> wrote:
>
>> # HG changeset patch
>> # User Boris Feld 
>> # Date 1529585081 -3600
>> #  Thu Jun 21 13:44:41 2018 +0100
>> # Node ID 59fea52e54e014722486f7c049e192fa505032d8
>> # Parent  8d20b1b4b6a0297e7f9640d285b15a5d6647369e
>> # EXP-Topic descendant
>> # Available At https://bitbucket.org/octobus/mercurial-devel/
>> #  hg pull https://bitbucket.org/octobus/mercurial-devel/ -r
>> 59fea52e54e0
>> revlog: do inclusive descendant testing (API)
>>
>> In many other places, a revision is considered a descendant of itself.
>> We update the behavior of `revlog.descendant()` to match this.
>>
>> No test breaks, so it seems safe to do so.
>>
>> diff -r 8d20b1b4b6a0 -r 59fea52e54e0 mercurial/revlog.py
>> --- a/mercurial/revlog.py   Thu Jun 21 13:32:07 2018 +0100
>> +++ b/mercurial/revlog.py   Thu Jun 21 13:44:41 2018 +0100
>> @@ -1378,7 +1378,7 @@
>>  def descendant(self, start, end):
>>  if start == nullrev:
>>  return True
>> -return start in self.ancestors([end])
>> +return start in self.ancestors([end], inclusive=True)
>>
>
> Is this now equivalent to self.isancestor(start, end)? That method relies
> on commonancestorsheads instead of lazyancestors. What are the performance
> trade-offs? Equivalent both when there are many ancestors and when there
> are many descendants?
>
> Hello Martin,
>
> Interestingly, it turns out that we have the following flock of functions:
>
>- ancestors: commonancestorsheads(parent_func, *revs)
>   - uses revnum
>   - any number of arguments
>   - written in Python
>- cext/revlog.c: revlog.index.commonancestorsheads(*revs)
>   - uses revnum
>   - any number of arguments
>   - written in C
>- revlog: revlog.commonancestorsheads(node-a, node-b)
>   - uses nodes
>   - takes exactly two nodes
>   - Calls either self.index.c…a…heads  or ancestors.c…a…heads
>- revlog: revlog.isancestor(anc, desc)
>   - uses nodes
>   - calls revlog.commonancestorsheads
>- revlog: revlog.descendant(rev-a, rev-b)
>   - uses revs
>   - has it own very slow code
>- revlog: revlog.descendant(rev-a, rev-b)
>   - uses revs
>   - has it own very slow code
>   - non-inclusive
>- context: context.descendant(other)
>   - uses contexts
>   - calls revlog.descendant
>   - non-inclusive
>
> At the algorithm level, `anc in ancestors(desc)` will be faster when anc
> is not an ancestor of desc (or they are many gca), since it will finish
> sooner. However given `commonancestorheads` benefits from a C
> implementation, it is currently the fastest option.
>
> In short terms, I think the following actions would make sense:
>
>1. Extract a lower level `revlog._commonancestorheads(*revs)` from
>`revlog.commonancestorsheads`
>
> What would the new function do? commonancestorsheads is already pretty
short. Do you mean to just make it work on revnums instead of nodeids? Or
do you mean for making it optionally inclusive?

>
>1. Use it in `revlog.descendant`
>2. Make `revlog.isancestor` use `revlog.descendant`
>
> Why is that better than making descendant call isancestor?

Does this seems sensible to you?
>
> --
> Paul Morelle
>
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH STABLE v2] hghave: don't claim we have `tic` if it's NetBSD's binary (issue5698)

2018-06-27 Thread Augie Fackler
# HG changeset patch
# User Augie Fackler 
# Date 1529932907 14400
#  Mon Jun 25 09:21:47 2018 -0400
# Branch stable
# Node ID af7d21e1e44c1bb756af28b5978d3f7ee7d50eda
# Parent  0b63a6743010dfdbf8a8154186e119949bdaa1cc
hghave: don't claim we have `tic` if it's NetBSD's binary (issue5698)

test-status-color.t fails with different output because of mismatches
between how `tic` behaves from NetBSD's base system and ncurses'
verison (if I understand the bug right). The bug suggested using -V to
avoid the issue, so we'll do that.

diff --git a/tests/hghave.py b/tests/hghave.py
--- a/tests/hghave.py
+++ b/tests/hghave.py
@@ -545,7 +545,11 @@ def has_tic():
 try:
 import curses
 curses.COLOR_BLUE
-return matchoutput('test -x "`which tic`"', br'')
+if not matchoutput('test -x "`which tic`"', br''):
+return False
+# We have a tic, but make sure it's not the NetBSD system one
+# which doesn't pass test-status-color.t.
+return not matchoutput('tic -V 2>&1', br'unknown option')
 except ImportError:
 return False
 
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D3716: ui: add an uninterruptable context manager that can block SIGINT

2018-06-27 Thread durin42 (Augie Fackler)
durin42 added a comment.


  I'm not in love with uninterruptible as a name (I think unsafeoperation is 
more explicit) but I don't feel strongly. The rest of the suggestions I liked, 
so the series is updated and ready for another look.

REPOSITORY
  rHG Mercurial

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

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


D3716: ui: add an uninterruptable context manager that can block SIGINT

2018-06-27 Thread durin42 (Augie Fackler)
durin42 updated this revision to Diff 9326.
durin42 edited the summary of this revision.
durin42 retitled this revision from "ui: add an unsafeoperation context manager 
that can block SIGINT" to "ui: add an uninterruptable context manager that can 
block SIGINT".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D3716?vs=9033=9326

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

AFFECTED FILES
  mercurial/configitems.py
  mercurial/ui.py
  mercurial/utils/procutil.py
  tests/test-nointerrupt.t

CHANGE DETAILS

diff --git a/tests/test-nointerrupt.t b/tests/test-nointerrupt.t
new file mode 100644
--- /dev/null
+++ b/tests/test-nointerrupt.t
@@ -0,0 +1,83 @@
+Dummy extension simulating unsafe long running command
+  $ cat > sleepext.py < import time
+  > import itertools
+  > 
+  > from mercurial import registrar
+  > from mercurial.i18n import _
+  > 
+  > cmdtable = {}
+  > command = registrar.command(cmdtable)
+  > 
+  > @command(b'sleep', [], _(b'TIME'), norepo=True)
+  > def sleep(ui, sleeptime=b"1", **opts):
+  > with ui.uninterruptable():
+  > for _i in itertools.repeat(None, int(sleeptime)):
+  > time.sleep(1)
+  > ui.warn(b"end of unsafe operation\n")
+  > ui.warn(b"%s second(s) passed\n" % sleeptime)
+  > EOF
+
+Kludge to emulate timeout(1) which is not generally available.
+  $ cat > timeout.py < from __future__ import print_function
+  > import argparse
+  > import signal
+  > import subprocess
+  > import sys
+  > import time
+  > 
+  > ap = argparse.ArgumentParser()
+  > ap.add_argument('-s', nargs=1, default='SIGTERM')
+  > ap.add_argument('duration', nargs=1, type=int)
+  > ap.add_argument('argv', nargs='*')
+  > opts = ap.parse_args()
+  > try:
+  > sig = int(opts.s[0])
+  > except ValueError:
+  > sname = opts.s[0]
+  > if not sname.startswith('SIG'):
+  > sname = 'SIG' + sname
+  > sig = getattr(signal, sname)
+  > proc = subprocess.Popen(opts.argv)
+  > time.sleep(opts.duration[0])
+  > proc.poll()
+  > if proc.returncode is None:
+  > proc.send_signal(sig)
+  > proc.wait()
+  > sys.exit(124)
+  > EOF
+
+Set up repository
+  $ hg init repo
+  $ cd repo
+  $ cat >> $HGRCPATH << EOF
+  > [extensions]
+  > sleepext = ../sleepext.py
+  > EOF
+
+Test ctrl-c
+  $ python $TESTTMP/timeout.py -s INT 1 hg sleep 2
+  interrupted!
+  [124]
+
+  $ cat >> $HGRCPATH << EOF
+  > [experimental]
+  > nointerrupt = yes
+  > EOF
+
+  $ python $TESTTMP/timeout.py -s INT 1 hg sleep 2
+  interrupted!
+  [124]
+
+  $ cat >> $HGRCPATH << EOF
+  > [experimental]
+  > nointerrupt-interactiveonly = False
+  > EOF
+
+  $ python $TESTTMP/timeout.py -s INT 1 hg sleep 2
+  shutting down cleanly
+  press ^C again to terminate immediately (dangerous)
+  end of unsafe operation
+  interrupted!
+  [124]
diff --git a/mercurial/utils/procutil.py b/mercurial/utils/procutil.py
--- a/mercurial/utils/procutil.py
+++ b/mercurial/utils/procutil.py
@@ -408,3 +408,36 @@
 finally:
 if prevhandler is not None:
 signal.signal(signal.SIGCHLD, prevhandler)
+
+@contextlib.contextmanager
+def uninterruptable(warn):
+"""Inhibit SIGINT handling on a region of code.
+
+Note that if this is called in a non-main thread, it turns into a no-op.
+
+Args:
+  warn: A callable which takes no arguments, and returns True if the
+previous signal handling should be restored.
+"""
+
+oldsiginthandler = [signal.getsignal(signal.SIGINT)]
+shouldbail = []
+
+def disabledsiginthandler(*args):
+if warn():
+signal.signal(signal.SIGINT, oldsiginthandler[0])
+del oldsiginthandler[0]
+shouldbail.append(True)
+
+try:
+try:
+signal.signal(signal.SIGINT, disabledsiginthandler)
+except ValueError:
+# wrong thread, oh well, we tried
+del oldsiginthandler[0]
+yield
+finally:
+if oldsiginthandler:
+signal.signal(signal.SIGINT, oldsiginthandler[0])
+if shouldbail:
+raise KeyboardInterrupt
diff --git a/mercurial/ui.py b/mercurial/ui.py
--- a/mercurial/ui.py
+++ b/mercurial/ui.py
@@ -224,6 +224,7 @@
 self._colormode = None
 self._terminfoparams = {}
 self._styles = {}
+self._uninterruptible = False
 
 if src:
 self.fout = src.fout
@@ -334,6 +335,37 @@
 self._blockedtimes[key + '_blocked'] += \
 (util.timer() - starttime) * 1000
 
+@contextlib.contextmanager
+def uninterruptable(self):
+"""Mark an operation as unsafe.
+
+Most operations on a repository are safe to interrupt, but a
+few are risky (for example repair.strip). This context manager
+lets you advise Mercurial that something risky is happening so
+that control-C etc can be blocked if desired.
+"""
+enabled = self.configbool('experimental', 

D3719: narrowbundle2: when we handle a widen, mark the operation as unsafe

2018-06-27 Thread durin42 (Augie Fackler)
durin42 updated this revision to Diff 9329.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D3719?vs=9026=9329

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

AFFECTED FILES
  hgext/narrow/narrowbundle2.py

CHANGE DETAILS

diff --git a/hgext/narrow/narrowbundle2.py b/hgext/narrow/narrowbundle2.py
--- a/hgext/narrow/narrowbundle2.py
+++ b/hgext/narrow/narrowbundle2.py
@@ -408,6 +408,8 @@
  topic='widen')
 repo._bookmarks = bmstore
 if chgrpfile:
+op._widen_uninterr = repo.ui.uninterruptable()
+op._widen_uninterr.__enter__()
 # presence of _widen_bundle attribute activates widen handler later
 op._widen_bundle = chgrpfile
 # Set the new narrowspec if we're widening. The setnewnarrowpats() method
@@ -455,6 +457,7 @@
 (undovfs.join(undofile), stringutil.forcebytestr(e)))
 
 # Remove partial backup only if there were no exceptions
+op._widen_uninterr.__exit__(None, None, None)
 vfs.unlink(chgrpfile)
 
 def setup():



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


D3717: repair: mark the critical section of strip() as unsafe

2018-06-27 Thread durin42 (Augie Fackler)
durin42 updated this revision to Diff 9327.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D3717?vs=9024=9327

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

AFFECTED FILES
  mercurial/repair.py

CHANGE DETAILS

diff --git a/mercurial/repair.py b/mercurial/repair.py
--- a/mercurial/repair.py
+++ b/mercurial/repair.py
@@ -186,76 +186,77 @@
 tmpbundlefile = backupbundle(repo, savebases, saveheads, node, 'temp',
  compress=False, obsolescence=False)
 
-try:
-with repo.transaction("strip") as tr:
-offset = len(tr.entries)
+with ui.uninterruptable():
+try:
+with repo.transaction("strip") as tr:
+offset = len(tr.entries)
 
-tr.startgroup()
-cl.strip(striprev, tr)
-stripmanifest(repo, striprev, tr, files)
-
-for fn in files:
-repo.file(fn).strip(striprev, tr)
-tr.endgroup()
+tr.startgroup()
+cl.strip(striprev, tr)
+stripmanifest(repo, striprev, tr, files)
 
-for i in xrange(offset, len(tr.entries)):
-file, troffset, ignore = tr.entries[i]
-with repo.svfs(file, 'a', checkambig=True) as fp:
-fp.truncate(troffset)
-if troffset == 0:
-repo.store.markremoved(file)
+for fn in files:
+repo.file(fn).strip(striprev, tr)
+tr.endgroup()
 
-deleteobsmarkers(repo.obsstore, stripobsidx)
-del repo.obsstore
-repo.invalidatevolatilesets()
-repo._phasecache.filterunknown(repo)
+for i in xrange(offset, len(tr.entries)):
+file, troffset, ignore = tr.entries[i]
+with repo.svfs(file, 'a', checkambig=True) as fp:
+fp.truncate(troffset)
+if troffset == 0:
+repo.store.markremoved(file)
+
+deleteobsmarkers(repo.obsstore, stripobsidx)
+del repo.obsstore
+repo.invalidatevolatilesets()
+repo._phasecache.filterunknown(repo)
 
-if tmpbundlefile:
-ui.note(_("adding branch\n"))
-f = vfs.open(tmpbundlefile, "rb")
-gen = exchange.readbundle(ui, f, tmpbundlefile, vfs)
-if not repo.ui.verbose:
-# silence internal shuffling chatter
-repo.ui.pushbuffer()
-tmpbundleurl = 'bundle:' + vfs.join(tmpbundlefile)
-txnname = 'strip'
-if not isinstance(gen, bundle2.unbundle20):
-txnname = "strip\n%s" % util.hidepassword(tmpbundleurl)
-with repo.transaction(txnname) as tr:
-bundle2.applybundle(repo, gen, tr, source='strip',
-url=tmpbundleurl)
-if not repo.ui.verbose:
-repo.ui.popbuffer()
-f.close()
+if tmpbundlefile:
+ui.note(_("adding branch\n"))
+f = vfs.open(tmpbundlefile, "rb")
+gen = exchange.readbundle(ui, f, tmpbundlefile, vfs)
+if not repo.ui.verbose:
+# silence internal shuffling chatter
+repo.ui.pushbuffer()
+tmpbundleurl = 'bundle:' + vfs.join(tmpbundlefile)
+txnname = 'strip'
+if not isinstance(gen, bundle2.unbundle20):
+txnname = "strip\n%s" % util.hidepassword(tmpbundleurl)
+with repo.transaction(txnname) as tr:
+bundle2.applybundle(repo, gen, tr, source='strip',
+url=tmpbundleurl)
+if not repo.ui.verbose:
+repo.ui.popbuffer()
+f.close()
 
-with repo.transaction('repair') as tr:
-bmchanges = [(m, repo[newbmtarget].node()) for m in updatebm]
-bm.applychanges(repo, tr, bmchanges)
+with repo.transaction('repair') as tr:
+bmchanges = [(m, repo[newbmtarget].node()) for m in updatebm]
+bm.applychanges(repo, tr, bmchanges)
 
-# remove undo files
-for undovfs, undofile in repo.undofiles():
-try:
-undovfs.unlink(undofile)
-except OSError as e:
-if e.errno != errno.ENOENT:
-ui.warn(_('error removing %s: %s\n') %
-(undovfs.join(undofile),
- stringutil.forcebytestr(e)))
+# remove undo files
+for undovfs, undofile in repo.undofiles():
+try:
+undovfs.unlink(undofile)
+except OSError as e:
+if e.errno != errno.ENOENT:
+

D3718: narrow: mark the critical chunks of narrowing/widening as unsafe

2018-06-27 Thread durin42 (Augie Fackler)
durin42 updated this revision to Diff 9328.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D3718?vs=9025=9328

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

AFFECTED FILES
  hgext/narrow/narrowcommands.py

CHANGE DETAILS

diff --git a/hgext/narrow/narrowcommands.py b/hgext/narrow/narrowcommands.py
--- a/hgext/narrow/narrowcommands.py
+++ b/hgext/narrow/narrowcommands.py
@@ -203,50 +203,51 @@
   hint=_('use --force-delete-local-changes to '
  'ignore'))
 
-if revstostrip:
-tostrip = [unfi.changelog.node(r) for r in revstostrip]
-if repo['.'].node() in tostrip:
-# stripping working copy, so move to a different commit first
-urev = max(repo.revs('(::%n) - %ln + null',
- repo['.'].node(), visibletostrip))
-hg.clean(repo, urev)
-repair.strip(ui, unfi, tostrip, topic='narrow')
+with ui.uninterruptable():
+if revstostrip:
+tostrip = [unfi.changelog.node(r) for r in revstostrip]
+if repo['.'].node() in tostrip:
+# stripping working copy, so move to a different commit first
+urev = max(repo.revs('(::%n) - %ln + null',
+ repo['.'].node(), visibletostrip))
+hg.clean(repo, urev)
+repair.strip(ui, unfi, tostrip, topic='narrow')
 
-todelete = []
-for f, f2, size in repo.store.datafiles():
-if f.startswith('data/'):
-file = f[5:-2]
-if not newmatch(file):
-todelete.append(f)
-elif f.startswith('meta/'):
-dir = f[5:-13]
-dirs = ['.'] + sorted(util.dirs({dir})) + [dir]
-include = True
-for d in dirs:
-visit = newmatch.visitdir(d)
-if not visit:
-include = False
-break
-if visit == 'all':
-break
-if not include:
-todelete.append(f)
+todelete = []
+for f, f2, size in repo.store.datafiles():
+if f.startswith('data/'):
+file = f[5:-2]
+if not newmatch(file):
+todelete.append(f)
+elif f.startswith('meta/'):
+dir = f[5:-13]
+dirs = ['.'] + sorted(util.dirs({dir})) + [dir]
+include = True
+for d in dirs:
+visit = newmatch.visitdir(d)
+if not visit:
+include = False
+break
+if visit == 'all':
+break
+if not include:
+todelete.append(f)
 
-repo.destroying()
+repo.destroying()
 
-with repo.transaction("narrowing"):
-for f in todelete:
-ui.status(_('deleting %s\n') % f)
-util.unlinkpath(repo.svfs.join(f))
-repo.store.markremoved(f)
+with repo.transaction("narrowing"):
+for f in todelete:
+ui.status(_('deleting %s\n') % f)
+util.unlinkpath(repo.svfs.join(f))
+repo.store.markremoved(f)
 
-for f in repo.dirstate:
-if not newmatch(f):
-repo.dirstate.drop(f)
-repo.wvfs.unlinkpath(f)
-repo.setnarrowpats(newincludes, newexcludes)
+for f in repo.dirstate:
+if not newmatch(f):
+repo.dirstate.drop(f)
+repo.wvfs.unlinkpath(f)
+repo.setnarrowpats(newincludes, newexcludes)
 
-repo.destroyed()
+repo.destroyed()
 
 def _widen(ui, repo, remote, commoninc, newincludes, newexcludes):
 newmatch = narrowspec.match(repo.root, newincludes, newexcludes)
@@ -269,28 +270,29 @@
 repo.setnarrowpats(newincludes, newexcludes)
 repo.setnewnarrowpats = setnewnarrowpats
 
-ds = repo.dirstate
-p1, p2 = ds.p1(), ds.p2()
-with ds.parentchange():
-ds.setparents(node.nullid, node.nullid)
-common = commoninc[0]
-with wrappedextraprepare:
-exchange.pull(repo, remote, heads=common)
-with ds.parentchange():
-ds.setparents(p1, p2)
+with ui.uninterruptable():
+ds = repo.dirstate
+p1, p2 = ds.p1(), ds.p2()
+with ds.parentchange():
+ds.setparents(node.nullid, node.nullid)
+common = commoninc[0]
+with wrappedextraprepare:
+exchange.pull(repo, remote, heads=common)
+with ds.parentchange():
+ds.setparents(p1, p2)
 
-actions = {k: [] for k in 'a am f g cd dc r dm dg m e k p pr'.split()}
-addgaction = actions['g'].append
+actions = {k: [] for k in 'a am f g cd dc r dm dg m e k p pr'.split()}
+addgaction = actions['g'].append
 
-mf = 

Re: [PATCH 2 of 2] revset: fix heads() order to always follow the input set (BC)

2018-06-27 Thread Martin von Zweigbergk via Mercurial-devel
On Wed, Jun 27, 2018 at 7:53 AM Yuya Nishihara  wrote:

> # HG changeset patch
> # User Yuya Nishihara 
> # Date 1530110381 -32400
> #  Wed Jun 27 23:39:41 2018 +0900
> # Node ID 542ca250795430ee77aeb5e5558f36f60dab3ca1
> # Parent  5aee640e2a99a305dc6f5219c35d2140180169a1
> revset: fix heads() order to always follow the input set (BC)
>

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


mercurial@38476: 15 new changesets

2018-06-27 Thread Mercurial Commits
15 new changesets in mercurial:

https://www.mercurial-scm.org/repo/hg/rev/61e4cf1be5b2
changeset:   38462:61e4cf1be5b2
user:Boris Feld 
date:Mon May 28 18:15:21 2018 +0200
summary: shelve: directly handle the abort process

https://www.mercurial-scm.org/repo/hg/rev/f4776f8b98e0
changeset:   38463:f4776f8b98e0
user:Boris Feld 
date:Tue May 29 00:13:48 2018 +0200
summary: shelve: directly handle `--continue`

https://www.mercurial-scm.org/repo/hg/rev/920f69c0b549
changeset:   38464:920f69c0b549
user:Boris Feld 
date:Tue May 29 00:12:35 2018 +0200
summary: shelve: actually test corrupted shelve state

https://www.mercurial-scm.org/repo/hg/rev/a8f99334ae31
changeset:   38465:a8f99334ae31
user:Boris Feld 
date:Tue May 29 00:15:44 2018 +0200
summary: shelve: stop testing missing rebase state file

https://www.mercurial-scm.org/repo/hg/rev/2c2e82469b89
changeset:   38466:2c2e82469b89
user:Yuya Nishihara 
date:Sat Jun 23 19:23:53 2018 +0900
summary: convert: don't pass --no-files to "darcs show repo" command

https://www.mercurial-scm.org/repo/hg/rev/09b09fe7ee90
changeset:   38467:09b09fe7ee90
user:Martin von Zweigbergk 
date:Mon Jun 25 11:01:11 2018 -0700
summary: terse: add tests of running from subdirectory

https://www.mercurial-scm.org/repo/hg/rev/854c2ccc800e
changeset:   38468:854c2ccc800e
user:Martin von Zweigbergk 
date:Mon Jun 25 11:04:17 2018 -0700
summary: terse: pass "clean" and "unknown" booleans by name for clarity

https://www.mercurial-scm.org/repo/hg/rev/9ef9884e5d50
changeset:   38469:9ef9884e5d50
user:Pulkit Goyal <7895pul...@gmail.com>
date:Tue Jun 26 00:37:02 2018 +0530
summary: py3: make tests/test-diff-antipatience.t work with python 3

https://www.mercurial-scm.org/repo/hg/rev/4c358bdaada8
changeset:   38470:4c358bdaada8
user:Pulkit Goyal <7895pul...@gmail.com>
date:Tue Jun 26 01:08:47 2018 +0530
summary: py3: add b'' prefixes in tests/test-bundle2-pushback.t

https://www.mercurial-scm.org/repo/hg/rev/91228d9ae7c8
changeset:   38471:91228d9ae7c8
user:Pulkit Goyal <7895pul...@gmail.com>
date:Tue Jun 26 02:04:17 2018 +0530
summary: patchbomb: use email.mime.multipart instead of email.MIMEMultipart

https://www.mercurial-scm.org/repo/hg/rev/d17d1ee1d602
changeset:   38472:d17d1ee1d602
user:Pulkit Goyal <7895pul...@gmail.com>
date:Tue Jun 26 02:05:11 2018 +0530
summary: patchbomb: use email.mime.base instead of email.MIMEBase

https://www.mercurial-scm.org/repo/hg/rev/622f79e3a1cb
changeset:   38473:622f79e3a1cb
user:Sushil khanchi 
date:Tue Jun 26 16:14:02 2018 +0530
summary: graft: add no-commit mode (issue5631)

https://www.mercurial-scm.org/repo/hg/rev/96f65bdf0bf4
changeset:   38474:96f65bdf0bf4
user:Augie Fackler 
date:Tue Jun 26 10:33:52 2018 -0400
summary: stringutil: add a new function to do minimal regex escaping

https://www.mercurial-scm.org/repo/hg/rev/67dc32d4e790
changeset:   38475:67dc32d4e790
user:Augie Fackler 
date:Tue Jun 26 10:36:23 2018 -0400
summary: cleanup: migrate from re.escape to stringutil.reescape

https://www.mercurial-scm.org/repo/hg/rev/b4cfd803b3f2
changeset:   38476:b4cfd803b3f2
bookmark:@
tag: tip
user:Augie Fackler 
date:Tue Jun 26 11:38:58 2018 -0400
summary: tests: fix up some lax escaping in test-template-basic.t

-- 
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 2 of 2] revset: fix heads() order to always follow the input set (BC)

2018-06-27 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1530110381 -32400
#  Wed Jun 27 23:39:41 2018 +0900
# Node ID 542ca250795430ee77aeb5e5558f36f60dab3ca1
# Parent  5aee640e2a99a305dc6f5219c35d2140180169a1
revset: fix heads() order to always follow the input set (BC)

An argument expression should never affect the order of the result set.
That's the rule of the revset predicates.

diff --git a/mercurial/revset.py b/mercurial/revset.py
--- a/mercurial/revset.py
+++ b/mercurial/revset.py
@@ -1129,11 +1129,14 @@ def head(repo, subset, x):
 hs.update(cl.rev(h) for h in ls)
 return subset & baseset(hs)
 
-@predicate('heads(set)', safe=True)
-def heads(repo, subset, x):
+@predicate('heads(set)', safe=True, takeorder=True)
+def heads(repo, subset, x, order):
 """Members of set with no children in set.
 """
-s = getset(repo, subset, x)
+# argument set should never define order
+if order == defineorder:
+order = followorder
+s = getset(repo, subset, x, order=order)
 ps = parents(repo, subset, x)
 return s - ps
 
diff --git a/tests/test-revset.t b/tests/test-revset.t
--- a/tests/test-revset.t
+++ b/tests/test-revset.t
@@ -1376,20 +1376,20 @@ Test heads
 , set([0, 1, 2, 3, 4, 5, 6, 8])>>>
   9
 
- BROKEN: but should follow the order of the subset
+ but should follow the order of the subset
 
   $ log 'heads(all())'
   7
   9
   $ log 'heads(tip:0)'
+  7
   9
-  7
   $ log 'tip:0 & heads(all())'
   9
   7
   $ log 'tip:0 & heads(0:tip)'
+  9
   7
-  9
 
   $ log 'keyword(issue)'
   6
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 1 of 2] test-revset: show that order of heads() can be wrong

2018-06-27 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1530110037 -32400
#  Wed Jun 27 23:33:57 2018 +0900
# Node ID 5aee640e2a99a305dc6f5219c35d2140180169a1
# Parent  b4cfd803b3f2697928be9b3a96787bcee3447c7e
test-revset: show that order of heads() can be wrong

diff --git a/tests/test-revset.t b/tests/test-revset.t
--- a/tests/test-revset.t
+++ b/tests/test-revset.t
@@ -1357,8 +1357,40 @@ test author
   6
   7
   9
+
+Test heads
+
   $ log 'heads(6::)'
   7
+
+ heads() can be computed in subset '9:'
+
+  $ hg debugrevspec -s '9: & heads(all())'
+  * set:
+  ,
+  >,
+, set([0, 1, 2, 3, 4, 5, 6, 8])>>>
+  9
+
+ BROKEN: but should follow the order of the subset
+
+  $ log 'heads(all())'
+  7
+  9
+  $ log 'heads(tip:0)'
+  9
+  7
+  $ log 'tip:0 & heads(all())'
+  9
+  7
+  $ log 'tip:0 & heads(0:tip)'
+  7
+  9
+
   $ log 'keyword(issue)'
   6
   $ log 'keyword("test a")'
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D3850: stringutil: update list of re-special characters to include &~

2018-06-27 Thread durin42 (Augie Fackler)
This revision was automatically updated to reflect the committed changes.
Closed by commit rHGde275ab362cb: stringutil: update list of re-special 
characters to include ~ (authored by durin42, committed by ).

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D3850?vs=9323=9325

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

AFFECTED FILES
  mercurial/utils/stringutil.py

CHANGE DETAILS

diff --git a/mercurial/utils/stringutil.py b/mercurial/utils/stringutil.py
--- a/mercurial/utils/stringutil.py
+++ b/mercurial/utils/stringutil.py
@@ -25,7 +25,7 @@
 
 # regex special chars pulled from https://bugs.python.org/issue29995
 # which was part of Python 3.7.
-_respecial = pycompat.bytestr(b'()[]{}?*+-|^$\\.# \t\n\r\v\f')
+_respecial = pycompat.bytestr(b'()[]{}?*+-|^$\\.&~# \t\n\r\v\f')
 _regexescapemap = {ord(i): (b'\\' + i).decode('latin1') for i in _respecial}
 
 def reescape(pat):



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


D3849: rebase: refactor dryrun implementation

2018-06-27 Thread khanchi97 (Sushil khanchi)
khanchi97 updated this revision to Diff 9324.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D3849?vs=9321=9324

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

AFFECTED FILES
  hgext/rebase.py

CHANGE DETAILS

diff --git a/hgext/rebase.py b/hgext/rebase.py
--- a/hgext/rebase.py
+++ b/hgext/rebase.py
@@ -818,19 +818,23 @@
 opts[r'dest'] = '_destautoorphanrebase(SRC)'
 
 if dryrun:
+leaveunfinished = True
+inmemory = True
+rbsrt = rebaseruntime(repo, ui, inmemory, opts)
 try:
 overrides = {('rebase', 'singletransaction'): True}
 with ui.configoverride(overrides, 'rebase'):
-_origrebase(ui, repo, inmemory=True, leaveunfinished=True,
-**opts)
+_origrebase(ui, repo, inmemory=True, rbsrt=rbsrt,
+leaveunfinished=leaveunfinished, **opts)
 except error.InMemoryMergeConflictsError:
 ui.status(_('hit a merge conflict\n'))
 return 1
 else:
 ui.status(_('there will be no conflict, you can rebase\n'))
 return 0
 finally:
-_origrebase(ui, repo, abort=True)
+with repo.wlock(), repo.lock():
+rbsrt._prepareabortorcontinue(isabort=True)
 elif inmemory:
 try:
 # in-memory merge doesn't support conflicts, so if we hit any, 
abort
@@ -846,9 +850,11 @@
 else:
 return _origrebase(ui, repo, **opts)
 
-def _origrebase(ui, repo, inmemory=False, leaveunfinished=False, **opts):
+def _origrebase(ui, repo, inmemory=False, leaveunfinished=False, rbsrt=None,
+**opts):
 opts = pycompat.byteskwargs(opts)
-rbsrt = rebaseruntime(repo, ui, inmemory, opts)
+if not rbsrt:
+rbsrt = rebaseruntime(repo, ui, inmemory, opts)
 
 with repo.wlock(), repo.lock():
 # Validate input and define rebasing points



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


D3841: stringutil: add a new function to do minimal regex escaping

2018-06-27 Thread durin42 (Augie Fackler)
durin42 added a comment.


  In https://phab.mercurial-scm.org/D3841#60110, @yuja wrote:
  
  > > +# regex special chars pulled from https://bugs.python.org/issue29995
  > >  +# which was part of Python 3.7.
  > >  +_respecial = pycompat.bytestr(b'()[]{}?*+-|^$\\.# \t\n\r\v\f')
  > >  +_regexescapemap = {ord(i): (b'\\' + i).decode('latin1') for i in 
_respecial}
  >
  > The Py3.7 version also includes '&' and '~'.
  >
  > https://github.com/python/cpython/blob/v3.7.0rc1/Lib/re.py#L248
  
  
  Nice catch, mailed https://phab.mercurial-scm.org/D3850 as a follow-up.

REPOSITORY
  rHG Mercurial

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

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


D3850: stringutil: update list of re-special characters to include &~

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

REVISION SUMMARY
  I missed this because I was looking at the change that refactored
  re.escape, and these characters were added in
  
https://github.com/python/cpython/commit/05cb728d68a278d11466f9a6c8258d914135c96c.

REPOSITORY
  rHG Mercurial

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

AFFECTED FILES
  mercurial/utils/stringutil.py

CHANGE DETAILS

diff --git a/mercurial/utils/stringutil.py b/mercurial/utils/stringutil.py
--- a/mercurial/utils/stringutil.py
+++ b/mercurial/utils/stringutil.py
@@ -25,7 +25,7 @@
 
 # regex special chars pulled from https://bugs.python.org/issue29995
 # which was part of Python 3.7.
-_respecial = pycompat.bytestr(b'()[]{}?*+-|^$\\.# \t\n\r\v\f')
+_respecial = pycompat.bytestr(b'()[]{}?*+-|^$\\.&~# \t\n\r\v\f')
 _regexescapemap = {ord(i): (b'\\' + i).decode('latin1') for i in _respecial}
 
 def reescape(pat):



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


mercurial@38461: 5 new changesets

2018-06-27 Thread Mercurial Commits
5 new changesets in mercurial:

https://www.mercurial-scm.org/repo/hg/rev/11eda1f1b6e7
changeset:   38457:11eda1f1b6e7
user:Gregory Szorc 
date:Sat May 12 15:51:37 2018 -0700
summary: packaging: consistently create build user in Dockerfiles

https://www.mercurial-scm.org/repo/hg/rev/e5916f1236f3
changeset:   38458:e5916f1236f3
user:Gregory Szorc 
date:Sat May 12 17:03:47 2018 -0700
summary: packaging: replace dockerlib.sh with a Python script

https://www.mercurial-scm.org/repo/hg/rev/c8ef9d897e14
changeset:   38459:c8ef9d897e14
user:Gregory Szorc 
date:Sat May 12 14:41:48 2018 -0700
summary: packaging: don't write files for templatized Dockerfiles

https://www.mercurial-scm.org/repo/hg/rev/7f738edc4a27
changeset:   38460:7f738edc4a27
user:Gregory Szorc 
date:Sat May 12 18:44:03 2018 -0700
summary: packaging: dynamically define make targets

https://www.mercurial-scm.org/repo/hg/rev/8459e8d2f729
changeset:   38461:8459e8d2f729
bookmark:@
tag: tip
user:Boris Feld 
date:Mon May 28 20:51:20 2018 +0200
summary: shelve: check the actual shelvestate in morestatus

-- 
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


Re: D3841: stringutil: add a new function to do minimal regex escaping

2018-06-27 Thread Yuya Nishihara
> +# regex special chars pulled from https://bugs.python.org/issue29995
> +# which was part of Python 3.7.
> +_respecial = pycompat.bytestr(b'()[]{}?*+-|^$\\.# \t\n\r\v\f')
> +_regexescapemap = {ord(i): (b'\\' + i).decode('latin1') for i in _respecial}

The Py3.7 version also includes '&' and '~'.

https://github.com/python/cpython/blob/v3.7.0rc1/Lib/re.py#L248
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D3841: stringutil: add a new function to do minimal regex escaping

2018-06-27 Thread yuja (Yuya Nishihara)
yuja added a comment.


  > +# regex special chars pulled from https://bugs.python.org/issue29995
  >  +# which was part of Python 3.7.
  >  +_respecial = pycompat.bytestr(b'()[]{}?*+-|^$\\.# \t\n\r\v\f')
  >  +_regexescapemap = {ord(i): (b'\\' + i).decode('latin1') for i in 
_respecial}
  
  The Py3.7 version also includes '&' and '~'.
  
  https://github.com/python/cpython/blob/v3.7.0rc1/Lib/re.py#L248

REPOSITORY
  rHG Mercurial

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

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


Re: D3849: rebase: refactor dryrun implementation

2018-06-27 Thread Yuya Nishihara
> @yuja In this patch rebaseruntime is instantiated two times, one in
> _dryrunrebase and second in _origrebase, I don't know if it could make any
> problem although all tests are passing. Maybe _origrebase() also need some
> refactoring.

Perhaps. I don't know if that really matters, but it's better to not keep
two separate rbsrt objects alive.

Can you reorder this as follows?

 1. extract _dryrunrebase() with no code change
 2. pass in rbsrt to _origrebase() (or new function extracted from
_origrebase())
 3. replace _origrebase(abort=True) with rbsrt call

> +def _abortunfinishedrebase(self, backup=False, suppwarns=True):
> +repo = self.repo
> +with repo.wlock(), repo.lock():
> +retcode = self._prepareabortorcontinue(isabort=True)
> +return retcode

If this is just calling _prepareabortorcontinue(), we wouldn't need a new
function. And I think the lock should be held by the caller.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D3849: rebase: refactor dryrun implementation

2018-06-27 Thread yuja (Yuya Nishihara)
yuja added a comment.


  > @yuja In this patch rebaseruntime is instantiated two times, one in
  >  _dryrunrebase and second in _origrebase, I don't know if it could make any
  >  problem although all tests are passing. Maybe _origrebase() also need some
  >  refactoring.
  
  Perhaps. I don't know if that really matters, but it's better to not keep
  two separate rbsrt objects alive.
  
  Can you reorder this as follows?
  
  1. extract _dryrunrebase() with no code change
  2. pass in rbsrt to _origrebase() (or new function extracted from 
_origrebase())
  3. replace _origrebase(abort=True) with rbsrt call
  
  > +def _abortunfinishedrebase(self, backup=False, suppwarns=True):
  >  +repo = self.repo
  >  +with repo.wlock(), repo.lock():
  >  +retcode = self._prepareabortorcontinue(isabort=True)
  >  +return retcode
  
  If this is just calling _prepareabortorcontinue(), we wouldn't need a new
  function. And I think the lock should be held by the caller.

REPOSITORY
  rHG Mercurial

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

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


Re: D3639: remotenames: add paths argument to remotenames revset

2018-06-27 Thread Yuya Nishihara
> +@revsetpredicate('remotenames([path, ...])')

My proposal was `remotenames([pattern])`, just like bookmark(), tag(),
branch(), etc. If we want a convenient way to specify path prefix, we can
add it to the stringmatcher (e.g. 'remotenames("path:server2")'.) And
multiple paths can be specified as 'remotenames(x) + remotenames(y)', though
it isn't exactly the same as 'remotenames("re:|")'.

Does it make sense?
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D3639: remotenames: add paths argument to remotenames revset

2018-06-27 Thread yuja (Yuya Nishihara)
yuja added a comment.


  > +@revsetpredicate('remotenames([path, ...])')
  
  My proposal was `remotenames([pattern])`, just like bookmark(), tag(),
  branch(), etc. If we want a convenient way to specify path prefix, we can
  add it to the stringmatcher (e.g. 'remotenames("path:server2")'.) And
  multiple paths can be specified as 'remotenames(x) + remotenames(y)', though
  it isn't exactly the same as 'remotenames("re:|")'.
  
  Does it make sense?

REPOSITORY
  rHG Mercurial

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

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


D3843: tests: fix up some lax escaping in test-template-basic.t

2018-06-27 Thread durin42 (Augie Fackler)
This revision was automatically updated to reflect the committed changes.
Closed by commit rHGb4cfd803b3f2: tests: fix up some lax escaping in 
test-template-basic.t (authored by durin42, committed by ).

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D3843?vs=9310=9322

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

AFFECTED FILES
  tests/test-template-basic.t

CHANGE DETAILS

diff --git a/tests/test-template-basic.t b/tests/test-template-basic.t
--- a/tests/test-template-basic.t
+++ b/tests/test-template-basic.t
@@ -835,11 +835,11 @@
   -o perso-
   $ hg log -R a -r 2 --template '{sub(r"\\x6e", "-", desc)}\n'
   no person
-  $ hg log -R a -r 2 --template '{sub("n", r"\x2d", desc)}\n'
+  $ hg log -R a -r 2 --template '{sub("n", r"\\x2d", desc)}\n'
   \x2do perso\x2d
   $ hg log -R a -r 2 --template '{sub("n", "\x2d", "no perso\x6e")}\n'
   -o perso-
-  $ hg log -R a -r 2 --template '{sub("n", r"\x2d", r"no perso\x6e")}\n'
+  $ hg log -R a -r 2 --template '{sub("n", r"\\x2d", r"no perso\x6e")}\n'
   \x2do perso\x6e
 
   $ hg log -R a -r 8 --template '{files % "{file}\n"}'



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


[PATCH 2 of 2] hooks: allow Unix style environment variables on external Windows hooks

2018-06-27 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1498969929 14400
#  Sun Jul 02 00:32:09 2017 -0400
# Node ID 6d206e4742d6f31246d0e234add03436ac429ebf
# Parent  7ac9de5a8826fc95864ee4ba844eb8b5c9e71332
hooks: allow Unix style environment variables on external Windows hooks

This will help making common hooks between Windows and non-Windows platforms.

Having to build the shellenviron dict here and in procutil.system() is a bit
unfortunate, but the only other option is to fix up the command inside
procutil.system().  It seems more important that the note about the hook being
run reflects what is actually run.

The patch from last summer added the hooks on the command line, but it looks
like HG_ARGS has since learned about --config args, and the output was just
confusing.  Therefore, it's now loaded from a file in the histedit test for
clarity.

diff --git a/mercurial/help/config.txt b/mercurial/help/config.txt
--- a/mercurial/help/config.txt
+++ b/mercurial/help/config.txt
@@ -886,6 +886,12 @@ They contain the type of hook which trig
 of the hook in the config, respectively. In the example above, this will
 be ``$HG_HOOKTYPE=incoming`` and ``$HG_HOOKNAME=incoming.email``.
 
+.. container:: windows
+
+  Some basic Unix syntax is supported for portability, including ``$VAR``
+  and ``${VAR}`` style variables.  To use a literal ``$``, it must be
+  escaped with a back slash or inside of a strong quote.
+
 ``changegroup``
   Run after a changegroup has been added via push, pull or unbundle.  The ID of
   the first new changeset is in ``$HG_NODE`` and last is in ``$HG_NODE_LAST``.
diff --git a/mercurial/hook.py b/mercurial/hook.py
--- a/mercurial/hook.py
+++ b/mercurial/hook.py
@@ -120,8 +120,6 @@ def pythonhook(ui, repo, htype, hname, f
 return r, False
 
 def _exthook(ui, repo, htype, name, cmd, args, throw):
-ui.note(_("running hook %s: %s\n") % (name, cmd))
-
 starttime = util.timer()
 env = {}
 
@@ -141,6 +139,12 @@ def _exthook(ui, repo, htype, name, cmd,
 v = stringutil.pprint(v)
 env['HG_' + k.upper()] = v
 
+if pycompat.iswindows:
+environ = procutil.shellenviron(env)
+cmd = util.platform.shelltocmdexe(cmd, environ)
+
+ui.note(_("running hook %s: %s\n") % (name, cmd))
+
 if repo:
 cwd = repo.root
 else:
diff --git a/tests/test-histedit-fold.t b/tests/test-histedit-fold.t
--- a/tests/test-histedit-fold.t
+++ b/tests/test-histedit-fold.t
@@ -478,14 +478,7 @@ This is an excuse to test hook with hist
   1:199b6bb90248 b
   0:6c795aa153cb a
 
-Setup the proper environment variable symbol for the platform, to be subbed
-into the hook command.
-#if windows
-  $ NODE="%HG_NODE%"
-#else
-  $ NODE="\$HG_NODE"
-#endif
-  $ hg histedit 6c795aa153cb --config hooks.commit="echo commit $NODE" 
--commands - 2>&1 << EOF | fixbundle
+  $ hg histedit 6c795aa153cb --config hooks.commit='echo commit $HG_NODE' 
--commands - 2>&1 << EOF | fixbundle
   > pick 199b6bb90248 b
   > fold a1a953ffb4b0 c
   > pick 6c795aa153cb a
@@ -496,8 +489,24 @@ into the hook command.
   1:9599899f62c0 a
   0:79b99e9c8e49 b
 
+Test unix -> windows style variable substitution in external hooks.
+
+  $ cat > $TESTTMP/tmp.hgrc <<'EOF'
+  > [hooks]
+  > pre-add = echo no variables
+  > post-add = echo ran $HG_ARGS, literal \$non-var, 'also $non-var', 
$HG_RESULT
+  > EOF
+
+TODO: Windows should output double quotes around "also $non-var"
   $ echo "foo" > amended.txt
-  $ hg add amended.txt
+  $ HGRCPATH=$TESTTMP/tmp.hgrc hg add -v amended.txt
+  running hook pre-add: echo no variables
+  no variables
+  adding amended.txt
+  running hook post-add: echo ran %HG_ARGS%, literal $non-var, 'also 
$non-var', %HG_RESULT% (windows !)
+  running hook post-add: echo ran $HG_ARGS, literal \$non-var, 'also 
$non-var', $HG_RESULT (no-windows !)
+  ran add -v amended.txt, literal $non-var, 'also $non-var', 0 (windows !)
+  ran add -v amended.txt, literal $non-var, also $non-var, 0 (no-windows !)
   $ hg ci -q --config extensions.largefiles= --amend -I amended.txt
   The fsmonitor extension is incompatible with the largefiles extension and 
has been disabled. (fsmonitor !)
 
diff --git a/tests/test-rebase-interruptions.t 
b/tests/test-rebase-interruptions.t
--- a/tests/test-rebase-interruptions.t
+++ b/tests/test-rebase-interruptions.t
@@ -333,12 +333,7 @@ Test rebase interrupted by hooks
 
   $ cp -R a3 hook-pretxncommit
   $ cd hook-pretxncommit
-#if windows
-  $ NODE="%HG_NODE%"
-#else
-  $ NODE="\$HG_NODE"
-#endif
-  $ hg rebase --source 2 --dest 5 --tool internal:other --config 
"hooks.pretxncommit=hg log -r $NODE | grep \"summary: C\""
+  $ hg rebase --source 2 --dest 5 --tool internal:other --config 
'hooks.pretxncommit=hg log -r $HG_NODE | grep "summary: C"'
   rebasing 2:965c486023db "C"
   summary: C
   rebasing 6:a0b2430ebfb8 "F" (tip)
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org

[PATCH 1 of 2] windows: add a method to convert Unix style command lines to Windows style

2018-06-27 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1529817189 14400
#  Sun Jun 24 01:13:09 2018 -0400
# Node ID 7ac9de5a8826fc95864ee4ba844eb8b5c9e71332
# Parent  2c2e82469b8915c8153979cd89a970b7317f882d
windows: add a method to convert Unix style command lines to Windows style

This started as a copy/paste of `os.path.expandvars()`, but limited to a given
dictionary of variables, converting `foo = foo + bar` to `foo += bar`, and
adding 'b' string prefixes.  Then code was added to make sure that a value being
substituted in wouldn't itself be expanded by cmd.exe.  But that left
inconsistent results between `$var1` and `%var1%` when its value was '%foo%'-
since neither were touched, `$var1` wouldn't expand but `%var1%` would.  So
instead, this just converts the Unix style to Windows style (if the variable
exists, because Windows will leave `%missing%` as-is), and lets cmd.exe do its
thing.

I then dropped the %% -> % conversion (because Windows doesn't do this), and
added the ability to escape the '$' with '\'.  The escape character is dropped,
for consistency with shell handling.

After everything seemed stable and working, running the whole test suite flagged
a problem near the end of test-bookmarks.t:1069.  The problem is cmd.exe won't
pass empty variables to its child, so defined but empty variables are now
skipped.  I can't think of anything better, and it seems like a pre-existing
violation of the documentation, which calls out that HG_OLDNODE is empty on
bookmark creation.

Future additions could potentially be replacing strong quotes with double quotes
(cmd.exe doesn't know what to do with the former), escaping a double quote, and
some tilde expansion via os.path.expanduser().  I've got some doubts about
replacing the strong quotes in case sh.exe is run, but it seems like the right
thing to do the vast majority of the time.  The original form of this was
discussed about a year ago[1].

[1] 
https://www.mercurial-scm.org/pipermail/mercurial-devel/2017-July/100735.html

diff --git a/mercurial/windows.py b/mercurial/windows.py
--- a/mercurial/windows.py
+++ b/mercurial/windows.py
@@ -12,6 +12,7 @@ import msvcrt
 import os
 import re
 import stat
+import string
 import sys
 
 from .i18n import _
@@ -253,6 +254,108 @@ normcasefallback = encoding.upperfallbac
 def samestat(s1, s2):
 return False
 
+def shelltocmdexe(path, env):
+r"""Convert shell variables in the form $var and ${var} inside ``path``
+to %var% form.  Existing Windows style variables are left unchanged.
+
+The variables are limited to the given environment.  Unknown variables are
+left unchanged.
+
+>>> e = {b'var1': b'v1', b'var2': b'v2', b'var3': b'v3'}
+>>> # Only valid values are expanded
+>>> shelltocmdexe(b'cmd $var1 ${var2} %var3% $missing ${missing} 
%missing%',
+...   e)
+'cmd %var1% %var2% %var3% $missing ${missing} %missing%'
+>>> # Single quote prevents expansion, as does \$ escaping
+>>> shelltocmdexe(b"cmd '$var1 ${var2} %var3%' \$var1 \${var2} \\", e)
+"cmd '$var1 ${var2} %var3%' $var1 ${var2} \\"
+>>> # $$ -> $, %% is not special, but can be the end and start of variables
+>>> shelltocmdexe(b"cmd $$ %% %var1%%var2%", e)
+'cmd $ %% %var1%%var2%'
+>>> # No double substitution
+>>> shelltocmdexe(b"$var1 %var1%", {b'var1': b'%var2%', b'var2': b'boom'})
+'%var1% %var1%'
+"""
+if b'$' not in path:
+return path
+
+varchars = pycompat.sysbytes(string.ascii_letters + string.digits) + b'_-'
+
+res = b''
+index = 0
+pathlen = len(path)
+while index < pathlen:
+c = path[index]
+if c == b'\'':   # no expansion within single quotes
+path = path[index + 1:]
+pathlen = len(path)
+try:
+index = path.index(b'\'')
+res += b'\'' + path[:index + 1]
+except ValueError:
+res += c + path
+index = pathlen - 1
+elif c == b'%':  # variable
+path = path[index + 1:]
+pathlen = len(path)
+try:
+index = path.index(b'%')
+except ValueError:
+res += b'%' + path
+index = pathlen - 1
+else:
+var = path[:index]
+res += b'%' + var + b'%'
+elif c == b'$':  # variable or '$$'
+if path[index + 1:index + 2] == b'$':
+res += c
+index += 1
+elif path[index + 1:index + 2] == b'{':
+path = path[index + 2:]
+pathlen = len(path)
+try:
+index = path.index(b'}')
+var = path[:index]
+
+# See below for why empty variables are handled specially
+if env.get(var, '') != '':
+res += b'%' + var + b'%'
+else:
+res += b'${' + var 

Re: [PATCH 1 of 3 gca-revset V2] revsets: add commonancestors revset

2018-06-27 Thread Yuya Nishihara
On Tue, 26 Jun 2018 15:40:37 -0700, Sean Farley wrote:
> # HG changeset patch
> # User Sean Farley 
> # Date 1529376114 25200
> #  Mon Jun 18 19:41:54 2018 -0700
> # Branch gca-revset
> # Node ID 6034db436af9b15237bb87f82405eb039dfb
> # Parent  2f5c622fcb739aed795c9ab51ea69c3b46436054
> revsets: add commonancestors revset

> +@predicate('commonancestors(set)', safe=True)
> +def commonancestors(repo, subset, x):
> +"""Returns all common ancestors of the set.
> +
> +This method is for calculating "::x and ::y" (i.e. all the ancestors that
> +are common to both x and y) in an easy and optimized way. We can't quite
> +use "::head()" but that revset returns "::x + ::y + ..." for each head in
> +the repo (whereas we want "::x *and* ::y").
> +
> +"""
> +# only wants the heads of the set passed in
> +h = heads(repo, subset, x)
   ^^
Perhaps it should be fullreposet(repo) since the subset has to be filtered by
any heads which may be out of the subset.

> +commonrevs = repo.revs(" and ".join(["::%s"] * len(h), *h))
   ^^^
Bad parens. And this wouldn't work if h is empty. Instead, we can chain
ancestor revisions.

for r in heads(...):
subset &= dagop.revancestors(repo, baseset([r]))
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 2 of 3 gca-revset V2] revset: add optimization for heads(commonancestors())

2018-06-27 Thread Yuya Nishihara
On Tue, 26 Jun 2018 15:40:38 -0700, Sean Farley wrote:
> # HG changeset patch
> # User Sean Farley 
> # Date 1530051981 25200
> #  Tue Jun 26 15:26:21 2018 -0700
> # Branch gca-revset
> # Node ID 0bab83973dbaecf03167801ddc4550c4b8b581f1
> # Parent  6034db436af9b15237bb87f82405eb039dfb
> revset: add optimization for heads(commonancestors())

> +from .ancestor import commonancestorsheads

symbol import isn't allowed.

> +# for internal use
> +@predicate('_commonancestorheads(set)', safe=True)
> +def _commonancestorheads(repo, subset, x):
> +"""Returns all greatest common ancestors of the changesets.
> +
> +This is an internal method is for quickly calculating "heads(::x and 
> ::y)"
> +
> +These greatest common ancestors are the same ones that the consesus bid
> +merge will find.
> +"""

This has to be a comment. All docstrings are visible in the revset help.

> +h = heads(repo, subset, x)
   ^^
   fullreposet(repo)

heads may be out of the subset.

> +
> +try:
> +ancs = repo.changelog.index.commonancestorsheads(*list(h))
> +return subset & baseset(ancs)
> +except (AttributeError, OverflowError): # C implementation failed
> +return subset & commonancestorsheads(repo.changelog.parentrevs,
> + *list(h))
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D3849: rebase: refactor dryrun implementation

2018-06-27 Thread khanchi97 (Sushil khanchi)
khanchi97 added a subscriber: yuja.
khanchi97 added a comment.


  @yuja In this patch rebaseruntime is instantiated two times, one in 
_dryrunrebase and second in _origrebase, I don't know if it could make any 
problem although all tests are passing. Maybe _origrebase() also need some 
refactoring.
  See if this refactoring is good or if this can be improved, then please give 
some suggestions.
  Thanks :)

REPOSITORY
  rHG Mercurial

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

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


D3849: rebase: refactor dryrun implementation

2018-06-27 Thread khanchi97 (Sushil khanchi)
khanchi97 created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  This patch refactor dry-run code to make it easy to add additional
  functionality in dryrun. Otherwise we had to add every functionality
  through _origrebase() which does not seem a good implementation.

REPOSITORY
  rHG Mercurial

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

AFFECTED FILES
  hgext/rebase.py

CHANGE DETAILS

diff --git a/hgext/rebase.py b/hgext/rebase.py
--- a/hgext/rebase.py
+++ b/hgext/rebase.py
@@ -644,6 +644,12 @@
 repo['.'].node() == repo._bookmarks[self.activebookmark]):
 bookmarks.activate(repo, self.activebookmark)
 
+def _abortunfinishedrebase(self, backup=False, suppwarns=True):
+repo = self.repo
+with repo.wlock(), repo.lock():
+retcode = self._prepareabortorcontinue(isabort=True)
+return retcode
+
 @command('rebase',
 [('s', 'source', '',
  _('rebase the specified changeset and descendants'), _('REV')),
@@ -818,19 +824,7 @@
 opts[r'dest'] = '_destautoorphanrebase(SRC)'
 
 if dryrun:
-try:
-overrides = {('rebase', 'singletransaction'): True}
-with ui.configoverride(overrides, 'rebase'):
-_origrebase(ui, repo, inmemory=True, leaveunfinished=True,
-**opts)
-except error.InMemoryMergeConflictsError:
-ui.status(_('hit a merge conflict\n'))
-return 1
-else:
-ui.status(_('there will be no conflict, you can rebase\n'))
-return 0
-finally:
-_origrebase(ui, repo, abort=True)
+return _dryrunrebase(ui, repo, **opts)
 elif inmemory:
 try:
 # in-memory merge doesn't support conflicts, so if we hit any, 
abort
@@ -846,6 +840,24 @@
 else:
 return _origrebase(ui, repo, **opts)
 
+def _dryrunrebase(ui, repo, **opts):
+leaveunfinished = True
+inmemory = True
+rbsrt = rebaseruntime(repo, ui, inmemory, opts)
+try:
+overrides = {('rebase', 'singletransaction'): True}
+with ui.configoverride(overrides, 'rebase'):
+_origrebase(ui, repo, inmemory=True,
+leaveunfinished=leaveunfinished, **opts)
+except error.InMemoryMergeConflictsError:
+ui.status(_('hit a merge conflict\n'))
+return 1
+else:
+ui.status(_('there will be no conflict, you can rebase\n'))
+return 0
+finally:
+rbsrt._abortunfinishedrebase()
+
 def _origrebase(ui, repo, inmemory=False, leaveunfinished=False, **opts):
 opts = pycompat.byteskwargs(opts)
 rbsrt = rebaseruntime(repo, ui, inmemory, opts)



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