[Bug 5934] New: Consider making histedit create "split" obsmarkers

2018-07-03 Thread mercurial-bugs
https://bz.mercurial-scm.org/show_bug.cgi?id=5934

Bug ID: 5934
   Summary: Consider making histedit create "split" obsmarkers
   Product: Mercurial
   Version: unspecified
  Hardware: PC
OS: Mac OS
Status: UNCONFIRMED
  Severity: feature
  Priority: wish
 Component: histedit
  Assignee: bugzi...@mercurial-scm.org
  Reporter: martinv...@google.com
CC: mercurial-devel@mercurial-scm.org

histedit has a edit action. When the editing starts, it says this:

Editing (a55829a4a822), you may commit or record as needed now.
(hg histedit --continue to resume)

Note that it mentions "record". That at least vaguely suggests that the edit
action can be used for splitting commits. However, the obsmarker it produces is
not a "split" (1:m) obsmarker. Perhaps it should be?

-- 
You are receiving this mail because:
You are on the CC list for the bug.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D3847: fix: disallow 'hg fix --base --whole'

2018-07-03 Thread hooper (Danny Hooper)
hooper added a comment.


  Let's not commit this one if possible. I have another patch with a test case 
that shows the combination is useful.

REPOSITORY
  rHG Mercurial

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

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


D3881: tests: don't allow reodering of glob/re lines across non-glob/re lines

2018-07-03 Thread martinvonz (Martin von Zweigbergk)
martinvonz updated this revision to Diff 9428.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D3881?vs=9423=9428

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

AFFECTED FILES
  tests/run-tests.py
  tests/test-run-tests.py
  tests/test-run-tests.t

CHANGE DETAILS

diff --git a/tests/test-run-tests.t b/tests/test-run-tests.t
--- a/tests/test-run-tests.t
+++ b/tests/test-run-tests.t
@@ -142,21 +142,18 @@
   
   --- $TESTTMP/test-failure-globs.t
   +++ $TESTTMP/test-failure-globs.t.err
-  @@ -2,10 +2,10 @@
+  @@ -2,9 +2,9 @@
  context
  context
  key: 1
   -  value: a
-  +  value: * (glob)
+  +  value: not a
  key: 2
   -  value: b
-  +  value: * (glob)
+  +  value: not b
  key: 3
-  -  value: * (glob)
-  +  value: c
+ value: * (glob)
  key: 4
-  -  value: * (glob)
-  +  value: d
   
   ERROR: test-failure-globs.t output changed
   !
diff --git a/tests/test-run-tests.py b/tests/test-run-tests.py
--- a/tests/test-run-tests.py
+++ b/tests/test-run-tests.py
@@ -40,7 +40,7 @@
 assert not re.search(br'[^ \w\\/\r\n()*?]', expected + output), \
b'single backslash or unknown char'
 test = run_tests.TTest(b'test-run-test.t', b'.', b'.')
-match = test.linematch(expected, output)
+match, exact = test.linematch(expected, output)
 if isinstance(match, str):
 return 'special: ' + match
 elif isinstance(match, bytes):
diff --git a/tests/run-tests.py b/tests/run-tests.py
--- a/tests/run-tests.py
+++ b/tests/run-tests.py
@@ -1484,7 +1484,7 @@
 for i, el in enumerate(els):
 r = False
 if el:
-r = self.linematch(el, lout)
+r, exact = self.linematch(el, lout)
 if isinstance(r, str):
 if r == '-glob':
 lout = ''.join(el.rsplit(' (glob)', 1))
@@ -1508,6 +1508,11 @@
 
 if not self._iftest(conditions):
 optional.append(i)
+if exact:
+# Don't allow line to be matches against a later
+# line in the output
+els.pop(i)
+break
 
 if r:
 if r == "retry":
@@ -1608,7 +1613,7 @@
 
 def linematch(self, el, l):
 if el == l: # perfect match (fast)
-return True
+return True, True
 retry = False
 if el.endswith(b" (?)\n"):
 retry = "retry"
@@ -1629,19 +1634,19 @@
 else:
 el = el[:-7].decode('string-escape') + '\n'
 if el == l or os.name == 'nt' and el[:-1] + b'\r\n' == l:
-return True
+return True, True
 if el.endswith(b" (re)\n"):
-return TTest.rematch(el[:-6], l) or retry
+return (TTest.rematch(el[:-6], l) or retry), False
 if el.endswith(b" (glob)\n"):
 # ignore '(glob)' added to l by 'replacements'
 if l.endswith(b" (glob)\n"):
 l = l[:-8] + b"\n"
-return TTest.globmatch(el[:-8], l) or retry
+return (TTest.globmatch(el[:-8], l) or retry), False
 if os.altsep:
 _l = l.replace(b'\\', b'/')
 if el == _l or os.name == 'nt' and el[:-1] + b'\r\n' == _l:
-return True
-return retry
+return True, True
+return retry, True
 
 @staticmethod
 def parsehghaveoutput(lines):



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


D3878: tests: remove some redundant code in run-tests

2018-07-03 Thread martinvonz (Martin von Zweigbergk)
martinvonz updated this revision to Diff 9425.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D3878?vs=9420=9425

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

AFFECTED FILES
  tests/run-tests.py

CHANGE DETAILS

diff --git a/tests/run-tests.py b/tests/run-tests.py
--- a/tests/run-tests.py
+++ b/tests/run-tests.py
@@ -1490,8 +1490,6 @@
 r = '' # Warn only this line.
 elif r == "retry":
 postout.append(b'  ' + el)
-els.pop(i)
-break
 else:
 log('\ninfo, unknown linematch result: %r\n' % r)
 r = False



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


D3879: tests: move handling of None "el" out of linematch()

2018-07-03 Thread martinvonz (Martin von Zweigbergk)
martinvonz updated this revision to Diff 9426.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D3879?vs=9421=9426

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

AFFECTED FILES
  tests/run-tests.py

CHANGE DETAILS

diff --git a/tests/run-tests.py b/tests/run-tests.py
--- a/tests/run-tests.py
+++ b/tests/run-tests.py
@@ -1482,8 +1482,9 @@
 
 optional = []
 for i, el in enumerate(els):
-
-r = self.linematch(el, lout)
+r = False
+if el:
+r = self.linematch(el, lout)
 if isinstance(r, str):
 if r == '-glob':
 lout = ''.join(el.rsplit(' (glob)', 1))
@@ -1606,41 +1607,40 @@
 return TTest.rematch(res, l)
 
 def linematch(self, el, l):
-retry = False
 if el == l: # perfect match (fast)
 return True
-if el:
-if el.endswith(b" (?)\n"):
-retry = "retry"
-el = el[:-5] + b"\n"
+retry = False
+if el.endswith(b" (?)\n"):
+retry = "retry"
+el = el[:-5] + b"\n"
+else:
+m = optline.match(el)
+if m:
+conditions = [c for c in m.group(2).split(b' ')]
+
+el = m.group(1) + b"\n"
+if not self._iftest(conditions):
+retry = "retry"# Not required by listed features
+
+if el.endswith(b" (esc)\n"):
+if PYTHON3:
+el = el[:-7].decode('unicode_escape') + '\n'
+el = el.encode('utf-8')
 else:
-m = optline.match(el)
-if m:
-conditions = [c for c in m.group(2).split(b' ')]
-
-el = m.group(1) + b"\n"
-if not self._iftest(conditions):
-retry = "retry"# Not required by listed features
-
-if el.endswith(b" (esc)\n"):
-if PYTHON3:
-el = el[:-7].decode('unicode_escape') + '\n'
-el = el.encode('utf-8')
-else:
-el = el[:-7].decode('string-escape') + '\n'
-if el == l or os.name == 'nt' and el[:-1] + b'\r\n' == l:
+el = el[:-7].decode('string-escape') + '\n'
+if el == l or os.name == 'nt' and el[:-1] + b'\r\n' == l:
+return True
+if el.endswith(b" (re)\n"):
+return TTest.rematch(el[:-6], l) or retry
+if el.endswith(b" (glob)\n"):
+# ignore '(glob)' added to l by 'replacements'
+if l.endswith(b" (glob)\n"):
+l = l[:-8] + b"\n"
+return TTest.globmatch(el[:-8], l) or retry
+if os.altsep:
+_l = l.replace(b'\\', b'/')
+if el == _l or os.name == 'nt' and el[:-1] + b'\r\n' == _l:
 return True
-if el.endswith(b" (re)\n"):
-return TTest.rematch(el[:-6], l) or retry
-if el.endswith(b" (glob)\n"):
-# ignore '(glob)' added to l by 'replacements'
-if l.endswith(b" (glob)\n"):
-l = l[:-8] + b"\n"
-return TTest.globmatch(el[:-8], l) or retry
-if os.altsep:
-_l = l.replace(b'\\', b'/')
-if el == _l or os.name == 'nt' and el[:-1] + b'\r\n' == _l:
-return True
 return retry
 
 @staticmethod



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


D3877: tests: don't reimplement enumerate() in run-tests

2018-07-03 Thread martinvonz (Martin von Zweigbergk)
martinvonz updated this revision to Diff 9424.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D3877?vs=9419=9424

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

AFFECTED FILES
  tests/run-tests.py

CHANGE DETAILS

diff --git a/tests/run-tests.py b/tests/run-tests.py
--- a/tests/run-tests.py
+++ b/tests/run-tests.py
@@ -1480,10 +1480,8 @@
 if expected.get(pos, None):
 els = expected[pos]
 
-i = 0
 optional = []
-while i < len(els):
-el = els[i]
+for i, el in enumerate(els):
 
 r = self.linematch(el, lout)
 if isinstance(r, str):
@@ -1512,8 +1510,6 @@
 if not self._iftest(conditions):
 optional.append(i)
 
-i += 1
-
 if r:
 if r == "retry":
 continue



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


D3880: tests: add test showing puzzling test output with (glob) lines

2018-07-03 Thread martinvonz (Martin von Zweigbergk)
martinvonz updated this revision to Diff 9427.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D3880?vs=9422=9427

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

AFFECTED FILES
  tests/test-run-tests.t

CHANGE DETAILS

diff --git a/tests/test-run-tests.t b/tests/test-run-tests.t
--- a/tests/test-run-tests.t
+++ b/tests/test-run-tests.t
@@ -120,6 +120,52 @@
   python hash seed: * (glob)
   [1]
 
+test how multiple globs gets matched with lines in output
+  $ cat > test-failure-globs.t <   $ echo "context"; echo "context"; \
+  > echo "key: 1"; echo "value: not a"; \
+  > echo "key: 2"; echo "value: not b"; \
+  > echo "key: 3"; echo "value: c"; \
+  > echo "key: 4"; echo "value: d"
+  >   context
+  >   context
+  >   key: 1
+  >   value: a
+  >   key: 2
+  >   value: b
+  >   key: 3
+  >   value: * (glob)
+  >   key: 4
+  >   value: * (glob)
+  > EOF
+  $ rt test-failure-globs.t
+  
+  --- $TESTTMP/test-failure-globs.t
+  +++ $TESTTMP/test-failure-globs.t.err
+  @@ -2,10 +2,10 @@
+ context
+ context
+ key: 1
+  -  value: a
+  +  value: * (glob)
+ key: 2
+  -  value: b
+  +  value: * (glob)
+ key: 3
+  -  value: * (glob)
+  +  value: c
+ key: 4
+  -  value: * (glob)
+  +  value: d
+  
+  ERROR: test-failure-globs.t output changed
+  !
+  Failed test-failure-globs.t: output changed
+  # Ran 1 tests, 0 skipped, 1 failed.
+  python hash seed: * (glob)
+  [1]
+  $ rm test-failure-globs.t
+
 test diff colorisation
 
 #if no-windows pygments
@@ -374,6 +420,7 @@
 
   $ cat .testtimes
   test-empty.t * (glob)
+  test-failure-globs.t * (glob)
   test-failure-unicode.t * (glob)
   test-failure.t * (glob)
   test-success.t * (glob)



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


D3880: tests: add test showing puzzling test output with (glob) lines

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

REVISION SUMMARY
  When using multiple (glob) lines, the test runner often moves the
  lines around in the output on failure. I have run into this problem
  many times. The added test shows one example of this. Note that it
  doesn't show the mismatching lines and instead shows diff hunks that
  appear to replace a literal by a glob, and other hunks that should
  clearly match.

REPOSITORY
  rHG Mercurial

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

AFFECTED FILES
  tests/test-run-tests.t

CHANGE DETAILS

diff --git a/tests/test-run-tests.t b/tests/test-run-tests.t
--- a/tests/test-run-tests.t
+++ b/tests/test-run-tests.t
@@ -120,6 +120,52 @@
   python hash seed: * (glob)
   [1]
 
+test how multiple globs gets matched with lines in output
+  $ cat > test-failure-globs.t <   $ echo "context"; echo "context"; \
+  > echo "key: 1"; echo "value: not a"; \
+  > echo "key: 2"; echo "value: not b"; \
+  > echo "key: 3"; echo "value: c"; \
+  > echo "key: 4"; echo "value: d"
+  >   context
+  >   context
+  >   key: 1
+  >   value: a
+  >   key: 2
+  >   value: b
+  >   key: 3
+  >   value: * (glob)
+  >   key: 4
+  >   value: * (glob)
+  > EOF
+  $ rt test-failure-globs.t
+  
+  --- $TESTTMP/test-failure-globs.t
+  +++ $TESTTMP/test-failure-globs.t.err
+  @@ -2,10 +2,10 @@
+ context
+ context
+ key: 1
+  -  value: a
+  +  value: * (glob)
+ key: 2
+  -  value: b
+  +  value: * (glob)
+ key: 3
+  -  value: * (glob)
+  +  value: c
+ key: 4
+  -  value: * (glob)
+  +  value: d
+  
+  ERROR: test-failure-globs.t output changed
+  !
+  Failed test-failure-globs.t: output changed
+  # Ran 1 tests, 0 skipped, 1 failed.
+  python hash seed: * (glob)
+  [1]
+  $ rm test-failure-globs.t
+
 test diff colorisation
 
 #if no-windows pygments
@@ -374,6 +420,7 @@
 
   $ cat .testtimes
   test-empty.t * (glob)
+  test-failure-globs.t * (glob)
   test-failure-unicode.t * (glob)
   test-failure.t * (glob)
   test-success.t * (glob)



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


D3881: tests: don't allow reodering of glob/re lines across non-glob/re lines

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

REVISION SUMMARY
  As shown in the test case added in the previous patch, it can be
  really hard to interpret diffs from the test runner if there are
  multiple lines that would match a given glob or regular expression. It
  looks like this has been the case since 
https://phab.mercurial-scm.org/rHG1ad0ddf8a4c6285598499fbb31de49ddb8ca 
(run-tests: teach
  _processoutput to handle multiple lines of churn, 2016-03-17). It
  seems like the point of that was to preserve the "(glob)" annotation
  on lines even if they got moved. This patch tries to preserve that but
  only allows the lines to be moved past other glob/re lines.

REPOSITORY
  rHG Mercurial

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

AFFECTED FILES
  tests/run-tests.py
  tests/test-run-tests.py
  tests/test-run-tests.t

CHANGE DETAILS

diff --git a/tests/test-run-tests.t b/tests/test-run-tests.t
--- a/tests/test-run-tests.t
+++ b/tests/test-run-tests.t
@@ -142,21 +142,18 @@
   
   --- $TESTTMP/test-failure-globs.t
   +++ $TESTTMP/test-failure-globs.t.err
-  @@ -2,10 +2,10 @@
+  @@ -2,9 +2,9 @@
  context
  context
  key: 1
   -  value: a
-  +  value: * (glob)
+  +  value: not a
  key: 2
   -  value: b
-  +  value: * (glob)
+  +  value: not b
  key: 3
-  -  value: * (glob)
-  +  value: c
+ value: * (glob)
  key: 4
-  -  value: * (glob)
-  +  value: d
   
   ERROR: test-failure-globs.t output changed
   !
diff --git a/tests/test-run-tests.py b/tests/test-run-tests.py
--- a/tests/test-run-tests.py
+++ b/tests/test-run-tests.py
@@ -40,7 +40,7 @@
 assert not re.search(br'[^ \w\\/\r\n()*?]', expected + output), \
b'single backslash or unknown char'
 test = run_tests.TTest(b'test-run-test.t', b'.', b'.')
-match = test.linematch(expected, output)
+match, exact = test.linematch(expected, output)
 if isinstance(match, str):
 return 'special: ' + match
 elif isinstance(match, bytes):
diff --git a/tests/run-tests.py b/tests/run-tests.py
--- a/tests/run-tests.py
+++ b/tests/run-tests.py
@@ -1484,7 +1484,7 @@
 for i, el in enumerate(els):
 r = False
 if el:
-r = self.linematch(el, lout)
+r, exact = self.linematch(el, lout)
 if isinstance(r, str):
 if r == '-glob':
 lout = ''.join(el.rsplit(' (glob)', 1))
@@ -1508,6 +1508,11 @@
 
 if not self._iftest(conditions):
 optional.append(i)
+if exact:
+# Don't allow line to be matches against a later
+# line in the output
+els.pop(i)
+break
 
 if r:
 if r == "retry":
@@ -1608,7 +1613,7 @@
 
 def linematch(self, el, l):
 if el == l: # perfect match (fast)
-return True
+return True, True
 retry = False
 if el.endswith(b" (?)\n"):
 retry = "retry"
@@ -1629,19 +1634,19 @@
 else:
 el = el[:-7].decode('string-escape') + '\n'
 if el == l or os.name == 'nt' and el[:-1] + b'\r\n' == l:
-return True
+return True, True
 if el.endswith(b" (re)\n"):
-return TTest.rematch(el[:-6], l) or retry
+return (TTest.rematch(el[:-6], l) or retry), False
 if el.endswith(b" (glob)\n"):
 # ignore '(glob)' added to l by 'replacements'
 if l.endswith(b" (glob)\n"):
 l = l[:-8] + b"\n"
-return TTest.globmatch(el[:-8], l) or retry
+return (TTest.globmatch(el[:-8], l) or retry), False
 if os.altsep:
 _l = l.replace(b'\\', b'/')
 if el == _l or os.name == 'nt' and el[:-1] + b'\r\n' == _l:
-return True
-return retry
+return True, True
+return retry, True
 
 @staticmethod
 def parsehghaveoutput(lines):



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


D3877: tests: don't reimplement enumerate() in run-tests

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

REPOSITORY
  rHG Mercurial

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

AFFECTED FILES
  tests/run-tests.py

CHANGE DETAILS

diff --git a/tests/run-tests.py b/tests/run-tests.py
--- a/tests/run-tests.py
+++ b/tests/run-tests.py
@@ -1480,10 +1480,8 @@
 if expected.get(pos, None):
 els = expected[pos]
 
-i = 0
 optional = []
-while i < len(els):
-el = els[i]
+for i, el in enumerate(els):
 
 r = self.linematch(el, lout)
 if isinstance(r, str):
@@ -1512,8 +1510,6 @@
 if not self._iftest(conditions):
 optional.append(i)
 
-i += 1
-
 if r:
 if r == "retry":
 continue



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


D3878: tests: remove some redundant code in run-tests

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

REVISION SUMMARY
  These two lines also happen below if "r" is truthy, which it is in
  this case since it's equal to "retry".

REPOSITORY
  rHG Mercurial

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

AFFECTED FILES
  tests/run-tests.py

CHANGE DETAILS

diff --git a/tests/run-tests.py b/tests/run-tests.py
--- a/tests/run-tests.py
+++ b/tests/run-tests.py
@@ -1490,8 +1490,6 @@
 r = '' # Warn only this line.
 elif r == "retry":
 postout.append(b'  ' + el)
-els.pop(i)
-break
 else:
 log('\ninfo, unknown linematch result: %r\n' % r)
 r = False



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


D3879: tests: move handling of None "el" out of linematch()

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

REVISION SUMMARY
  It just seems odd for linematch() to know what None means.

REPOSITORY
  rHG Mercurial

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

AFFECTED FILES
  tests/run-tests.py

CHANGE DETAILS

diff --git a/tests/run-tests.py b/tests/run-tests.py
--- a/tests/run-tests.py
+++ b/tests/run-tests.py
@@ -1482,8 +1482,9 @@
 
 optional = []
 for i, el in enumerate(els):
-
-r = self.linematch(el, lout)
+r = False
+if el:
+r = self.linematch(el, lout)
 if isinstance(r, str):
 if r == '-glob':
 lout = ''.join(el.rsplit(' (glob)', 1))
@@ -1606,41 +1607,40 @@
 return TTest.rematch(res, l)
 
 def linematch(self, el, l):
-retry = False
 if el == l: # perfect match (fast)
 return True
-if el:
-if el.endswith(b" (?)\n"):
-retry = "retry"
-el = el[:-5] + b"\n"
+retry = False
+if el.endswith(b" (?)\n"):
+retry = "retry"
+el = el[:-5] + b"\n"
+else:
+m = optline.match(el)
+if m:
+conditions = [c for c in m.group(2).split(b' ')]
+
+el = m.group(1) + b"\n"
+if not self._iftest(conditions):
+retry = "retry"# Not required by listed features
+
+if el.endswith(b" (esc)\n"):
+if PYTHON3:
+el = el[:-7].decode('unicode_escape') + '\n'
+el = el.encode('utf-8')
 else:
-m = optline.match(el)
-if m:
-conditions = [c for c in m.group(2).split(b' ')]
-
-el = m.group(1) + b"\n"
-if not self._iftest(conditions):
-retry = "retry"# Not required by listed features
-
-if el.endswith(b" (esc)\n"):
-if PYTHON3:
-el = el[:-7].decode('unicode_escape') + '\n'
-el = el.encode('utf-8')
-else:
-el = el[:-7].decode('string-escape') + '\n'
-if el == l or os.name == 'nt' and el[:-1] + b'\r\n' == l:
+el = el[:-7].decode('string-escape') + '\n'
+if el == l or os.name == 'nt' and el[:-1] + b'\r\n' == l:
+return True
+if el.endswith(b" (re)\n"):
+return TTest.rematch(el[:-6], l) or retry
+if el.endswith(b" (glob)\n"):
+# ignore '(glob)' added to l by 'replacements'
+if l.endswith(b" (glob)\n"):
+l = l[:-8] + b"\n"
+return TTest.globmatch(el[:-8], l) or retry
+if os.altsep:
+_l = l.replace(b'\\', b'/')
+if el == _l or os.name == 'nt' and el[:-1] + b'\r\n' == _l:
 return True
-if el.endswith(b" (re)\n"):
-return TTest.rematch(el[:-6], l) or retry
-if el.endswith(b" (glob)\n"):
-# ignore '(glob)' added to l by 'replacements'
-if l.endswith(b" (glob)\n"):
-l = l[:-8] + b"\n"
-return TTest.globmatch(el[:-8], l) or retry
-if os.altsep:
-_l = l.replace(b'\\', b'/')
-if el == _l or os.name == 'nt' and el[:-1] + b'\r\n' == _l:
-return True
 return retry
 
 @staticmethod



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


D3845: worker: support more return types in posix worker

2018-07-03 Thread hooper (Danny Hooper)
hooper added a comment.


  Yuya, it had passed tests for me with cbor, so is that a portability issue?
  
  One of the benefits of pickle/marshal is that we don't lose information, like 
when tuples become lists. That would be an insidious problem for callers.
  
  Also, in case it wasn't obvious, we'll need another patch to add some 
handling of len(dumps(result)) > PIPE_BUF (which was an existing issue).

REPOSITORY
  rHG Mercurial

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

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


D3845: worker: support more return types in posix worker

2018-07-03 Thread hooper (Danny Hooper)
hooper updated this revision to Diff 9418.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D3845?vs=9401=9418

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

AFFECTED FILES
  mercurial/worker.py

CHANGE DETAILS

diff --git a/mercurial/worker.py b/mercurial/worker.py
--- a/mercurial/worker.py
+++ b/mercurial/worker.py
@@ -155,8 +155,8 @@
 
 def workerfunc():
 os.close(rfd)
-for i, item in func(*(staticargs + (pargs,))):
-os.write(wfd, '%d %s\n' % (i, item))
+for result in func(*(staticargs + (pargs,))):
+os.write(wfd, util.pickle.dumps(result))
 return 0
 
 ret = scmutil.callcatch(ui, workerfunc)
@@ -187,9 +187,15 @@
 os.kill(os.getpid(), -status)
 sys.exit(status)
 try:
-for line in util.iterfile(fp):
-l = line.split(' ', 1)
-yield int(l[0]), l[1][:-1]
+while True:
+try:
+yield util.pickle.load(fp)
+except EOFError:
+break
+except IOError as e:
+if e.errno == errno.EINTR:
+continue
+raise
 except: # re-raises
 killworkers()
 cleanup()



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


D3701: run-tests: extract onStart and onEnd into the test result

2018-07-03 Thread lothiraldan (Boris Feld)
lothiraldan updated this revision to Diff 9417.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D3701?vs=9032=9417

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

AFFECTED FILES
  tests/run-tests.py

CHANGE DETAILS

diff --git a/tests/run-tests.py b/tests/run-tests.py
--- a/tests/run-tests.py
+++ b/tests/run-tests.py
@@ -1711,6 +1711,14 @@
 else: # 'always', for testing purposes
 self.color = pygmentspresent
 
+def onStart(self, test):
+""" Can be overriden by custom TestResult
+"""
+
+def onEnd(self):
+""" Can be overriden by custom TestResult
+"""
+
 def addFailure(self, test, reason):
 self.failures.append((test, reason))
 
@@ -2099,71 +2107,73 @@
 super(TextTestRunner, self).__init__(*args, **kwargs)
 
 self._runner = runner
+self._result = getTestResult()(self._runner.options, self.stream,
+   self.descriptions, 0)
 
 def listtests(self, test):
-result = getTestResult()(self._runner.options, self.stream,
- self.descriptions, 0)
 test = sorted(test, key=lambda t: t.name)
+
+self._result.onStart(test)
+
 for t in test:
 print(t.name)
-result.addSuccess(t)
+self._result.addSuccess(t)
 
 if self._runner.options.xunit:
 with open(self._runner.options.xunit, "wb") as xuf:
-self._writexunit(result, xuf)
+self._writexunit(self._result, xuf)
 
 if self._runner.options.json:
 jsonpath = os.path.join(self._runner._outputdir, b'report.json')
 with open(jsonpath, 'w') as fp:
-self._writejson(result, fp)
-
-return result
+self._writejson(self._result, fp)
+
+return self._result
 
 def run(self, test):
-result = getTestResult()(self._runner.options, self.stream,
- self.descriptions, self.verbosity)
-test(result)
-
-failed = len(result.failures)
-skipped = len(result.skipped)
-ignored = len(result.ignored)
+self._result.onStart(test)
+test(self._result)
+
+failed = len(self._result.failures)
+skipped = len(self._result.skipped)
+ignored = len(self._result.ignored)
 
 with iolock:
 self.stream.writeln('')
 
 if not self._runner.options.noskips:
-for test, msg in result.skipped:
+for test, msg in self._result.skipped:
 formatted = 'Skipped %s: %s\n' % (test.name, msg)
-self.stream.write(highlightmsg(formatted, result.color))
-for test, msg in result.failures:
+self.stream.write(highlightmsg(formatted, 
self._result.color))
+for test, msg in self._result.failures:
 formatted = 'Failed %s: %s\n' % (test.name, msg)
-self.stream.write(highlightmsg(formatted, result.color))
-for test, msg in result.errors:
+self.stream.write(highlightmsg(formatted, self._result.color))
+for test, msg in self._result.errors:
 self.stream.writeln('Errored %s: %s' % (test.name, msg))
 
 if self._runner.options.xunit:
 with open(self._runner.options.xunit, "wb") as xuf:
-self._writexunit(result, xuf)
+self._writexunit(self._result, xuf)
 
 if self._runner.options.json:
 jsonpath = os.path.join(self._runner._outputdir, 
b'report.json')
 with open(jsonpath, 'w') as fp:
-self._writejson(result, fp)
+self._writejson(self._result, fp)
 
 self._runner._checkhglib('Tested')
 
-savetimes(self._runner._outputdir, result)
+savetimes(self._runner._outputdir, self._result)
 
 if failed and self._runner.options.known_good_rev:
-self._bisecttests(t for t, m in result.failures)
+self._bisecttests(t for t, m in self._result.failures)
 self.stream.writeln(
 '# Ran %d tests, %d skipped, %d failed.'
-% (result.testsRun, skipped + ignored, failed))
+% (self._result.testsRun, skipped + ignored, failed))
 if failed:
 self.stream.writeln('python hash seed: %s' %
 os.environ['PYTHONHASHSEED'])
 if self._runner.options.time:
-self.printtimes(result.times)
+self.printtimes(self._result.times)
 
 if self._runner.options.exceptions:
 exceptions = aggregateexceptions(
@@ -2186,7 +2196,7 @@
 
 self.stream.flush()
 
-return result
+return self._result
 
 def _bisecttests(self, tests):

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

2018-07-03 Thread Sangeet Kumar Mishra
Yeah

On Tue, Jul 3, 2018 at 11:39 PM durin42 (Augie Fackler) <
phabrica...@mercurial-scm.org> wrote:

> durin42 added a comment.
>
>
>   It looks like this is obsoleted by https://phab.mercurial-scm.org/D3826?
>
> REPOSITORY
>   rHG Mercurial
>
> REVISION DETAIL
>   https://phab.mercurial-scm.org/D2938
>
> To: sangeet259, #hg-reviewers
> Cc: durin42, martinvonz, av6, yuja, pulkit, mercurial-devel
> ___
> Mercurial-devel mailing list
> Mercurial-devel@mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
>


-- 
Sangeet Kumar Mishra

2nd Year Undergraduate,
Indian Institute of Technology, Kharagpur

GitHub  : LinkedIn
 : Facebook

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


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

2018-07-03 Thread durin42 (Augie Fackler)
durin42 added a comment.


  It looks like this is obsoleted by https://phab.mercurial-scm.org/D3826?

REPOSITORY
  rHG Mercurial

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

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


D3701: run-tests: extract onStart and onEnd into the test result

2018-07-03 Thread durin42 (Augie Fackler)
durin42 added inline comments.

INLINE COMMENTS

> run-tests.py:1717
> +"""
> +pass
> +

omit superfluous pass

REPOSITORY
  rHG Mercurial

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

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


D3700: run-tests: add support for external test result

2018-07-03 Thread durin42 (Augie Fackler)
durin42 accepted this revision as: durin42.
durin42 added a comment.


  I guess I can live with that.

INLINE COMMENTS

> basic_test_result.py:37
> +def addSkip(self, test, reason):
> +print("ERR!", test, reason)
> +

shouldn't this say "SKIP!"?

REPOSITORY
  rHG Mercurial

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

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


D3869: repository: define manifest interfaces

2018-07-03 Thread indygreg (Gregory Szorc)
This revision was automatically updated to reflect the committed changes.
Closed by commit rHGc82ea938efbb: repository: define manifest interfaces 
(authored by indygreg, committed by ).

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D3869?vs=9383=9415

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

AFFECTED FILES
  mercurial/manifest.py
  mercurial/repository.py
  tests/test-check-interfaces.py

CHANGE DETAILS

diff --git a/tests/test-check-interfaces.py b/tests/test-check-interfaces.py
--- a/tests/test-check-interfaces.py
+++ b/tests/test-check-interfaces.py
@@ -25,6 +25,7 @@
 filelog,
 httppeer,
 localrepo,
+manifest,
 pycompat,
 repository,
 sshpeer,
@@ -164,9 +165,35 @@
 checkzobject(httpv2)
 
 ziverify.verifyClass(repository.ifilestorage, filelog.filelog)
+ziverify.verifyClass(repository.imanifestdict, manifest.manifestdict)
+ziverify.verifyClass(repository.imanifestrevisionstored,
+ manifest.manifestctx)
+ziverify.verifyClass(repository.imanifestrevisionwritable,
+ manifest.memmanifestctx)
+ziverify.verifyClass(repository.imanifestrevisionstored,
+ manifest.treemanifestctx)
+ziverify.verifyClass(repository.imanifestrevisionwritable,
+ manifest.memtreemanifestctx)
+ziverify.verifyClass(repository.imanifestlog, manifest.manifestlog)
 
 vfs = vfsmod.vfs(b'.')
 fl = filelog.filelog(vfs, b'dummy.i')
 checkzobject(fl, allowextra=True)
 
+# Conforms to imanifestlog.
+ml = manifest.manifestlog(vfs, repo)
+checkzobject(ml)
+checkzobject(repo.manifestlog)
+
+# Conforms to imanifestrevision.
+mctx = ml[repo[0].manifestnode()]
+checkzobject(mctx)
+
+# Conforms to imanifestrevisionwritable.
+checkzobject(mctx.new())
+checkzobject(mctx.copy())
+
+# Conforms to imanifestdict.
+checkzobject(mctx.read())
+
 main()
diff --git a/mercurial/repository.py b/mercurial/repository.py
--- a/mercurial/repository.py
+++ b/mercurial/repository.py
@@ -642,6 +642,286 @@
 TODO this is used by verify and it should not be part of the interface.
 """
 
+class idirs(interfaceutil.Interface):
+"""Interface representing a collection of directories from paths.
+
+This interface is essentially a derived data structure representing
+directories from a collection of paths.
+"""
+
+def addpath(path):
+"""Add a path to the collection.
+
+All directories in the path will be added to the collection.
+"""
+
+def delpath(path):
+"""Remove a path from the collection.
+
+If the removal was the last path in a particular directory, the
+directory is removed from the collection.
+"""
+
+def __iter__():
+"""Iterate over the directories in this collection of paths."""
+
+def __contains__(path):
+"""Whether a specific directory is in this collection."""
+
+class imanifestdict(interfaceutil.Interface):
+"""Interface representing a manifest data structure.
+
+A manifest is effectively a dict mapping paths to entries. Each entry
+consists of a binary node and extra flags affecting that entry.
+"""
+
+def __getitem__(path):
+"""Returns the binary node value for a path in the manifest.
+
+Raises ``KeyError`` if the path does not exist in the manifest.
+
+Equivalent to ``self.find(path)[0]``.
+"""
+
+def find(path):
+"""Returns the entry for a path in the manifest.
+
+Returns a 2-tuple of (node, flags).
+
+Raises ``KeyError`` if the path does not exist in the manifest.
+"""
+
+def __len__():
+"""Return the number of entries in the manifest."""
+
+def __nonzero__():
+"""Returns True if the manifest has entries, False otherwise."""
+
+__bool__ = __nonzero__
+
+def __setitem__(path, node):
+"""Define the node value for a path in the manifest.
+
+If the path is already in the manifest, its flags will be copied to
+the new entry.
+"""
+
+def __contains__(path):
+"""Whether a path exists in the manifest."""
+
+def __delitem__(path):
+"""Remove a path from the manifest.
+
+Raises ``KeyError`` if the path is not in the manifest.
+"""
+
+def __iter__():
+"""Iterate over paths in the manifest."""
+
+def iterkeys():
+"""Iterate over paths in the manifest."""
+
+def keys():
+"""Obtain a list of paths in the manifest."""
+
+def filesnotin(other, match=None):
+"""Obtain the set of paths in this manifest but not in another.
+
+``match`` is an optional matcher function to be applied to both
+manifests.
+
+Returns a set of paths.
+"""
+
+def dirs():
+"""Returns an object implementing the ``idirs`` interface."""
+
+

[PATCH 2 of 2] debug: process --debug flag earlier

2018-07-03 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1529432311 -3600
#  Tue Jun 19 19:18:31 2018 +0100
# Node ID 53221514bc635fc3b8687db48de3e948b075e84c
# Parent  d283976aa9a2b35631c749facc0290dd9ea11c30
# EXP-Topic earlydebug
# Available At https://bitbucket.org/octobus/mercurial-devel/
#  hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 
53221514bc63
debug: process --debug flag earlier

This allow the verbosity level to be set correctly during extension
initialization.

diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py
--- a/mercurial/dispatch.py
+++ b/mercurial/dispatch.py
@@ -811,6 +811,13 @@ def _dispatch(req):
 if req.repo:
 uis.add(req.repo.ui)
 
+if (req.earlyoptions['verbose'] or req.earlyoptions['debug']
+or req.earlyoptions['quiet']):
+for opt in ('verbose', 'debug', 'quiet'):
+val = pycompat.bytestr(bool(req.earlyoptions[opt]))
+for ui_ in uis:
+ui_.setconfig('ui', opt, val, '--' + opt)
+
 if req.earlyoptions['profile']:
 for ui_ in uis:
 ui_.setconfig('profiling', 'enabled', 'true', '--profile')
@@ -876,8 +883,11 @@ def _dispatch(req):
 if options["profile"]:
 profiler.start()
 
+# if abbreviated version of this were used, take them in account, now
 if options['verbose'] or options['debug'] or options['quiet']:
 for opt in ('verbose', 'debug', 'quiet'):
+if options[opt] == req.earlyoptions[opt]:
+continue
 val = pycompat.bytestr(bool(options[opt]))
 for ui_ in uis:
 ui_.setconfig('ui', opt, val, '--' + opt)
diff --git a/tests/test-extension.t b/tests/test-extension.t
--- a/tests/test-extension.t
+++ b/tests/test-extension.t
@@ -9,7 +9,9 @@ Test basic extension support
   > configitem = registrar.configitem(configtable)
   > configitem(b'tests', b'foo', default=b"Foo")
   > def uisetup(ui):
+  > ui.debug(b"uisetup called [debug]\\n")
   > ui.write(b"uisetup called\\n")
+  > ui.status(b"uisetup called [status]\\n")
   > ui.flush()
   > def reposetup(ui, repo):
   > ui.write(b"reposetup called for %s\\n" % os.path.basename(repo.root))
@@ -40,15 +42,29 @@ Test basic extension support
   $ echo "foobar = $abspath" >> $HGRCPATH
   $ hg foo
   uisetup called
+  uisetup called [status]
   reposetup called for a
   ui == repo.ui
   reposetup called for a (chg !)
   ui == repo.ui (chg !)
   Foo
+  $ hg foo --quiet
+  uisetup called (no-chg !)
+  reposetup called for a (chg !)
+  ui == repo.ui
+  Foo
+  $ hg foo --debug
+  uisetup called [debug] (no-chg !)
+  uisetup called (no-chg !)
+  uisetup called [status] (no-chg !)
+  reposetup called for a (chg !)
+  ui == repo.ui
+  Foo
 
   $ cd ..
   $ hg clone a b
   uisetup called (no-chg !)
+  uisetup called [status] (no-chg !)
   reposetup called for a
   ui == repo.ui
   reposetup called for b
@@ -58,6 +74,7 @@ Test basic extension support
 
   $ hg bar
   uisetup called (no-chg !)
+  uisetup called [status] (no-chg !)
   Bar
   $ echo 'foobar = !' >> $HGRCPATH
 
@@ -67,6 +84,7 @@ module/__init__.py-style
   $ cd a
   $ hg foo
   uisetup called
+  uisetup called [status]
   reposetup called for a
   ui == repo.ui
   reposetup called for a (chg !)
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 1 of 2] test: stop passing --quiet in a run dedicated to debug output

2018-07-03 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1529431831 -3600
#  Tue Jun 19 19:10:31 2018 +0100
# Node ID d283976aa9a2b35631c749facc0290dd9ea11c30
# Parent  1cac2e8c76242e16c2da5f8e6d6efb76be592eba
# EXP-Topic earlydebug
# Available At https://bitbucket.org/octobus/mercurial-devel/
#  hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 
d283976aa9a2
test: stop passing --quiet in a run dedicated to debug output

The goal of the run is to display some debug output. Passing --quiet in this
case is strange.

diff --git a/tests/test-bad-extension.t b/tests/test-bad-extension.t
--- a/tests/test-bad-extension.t
+++ b/tests/test-bad-extension.t
@@ -75,7 +75,7 @@ names of extensions failed to load can b
 show traceback for ImportError of hgext.name if debug is set
 (note that --debug option isn't applied yet when loading extensions)
 
-  $ (hg -q help help --traceback --config ui.debug=True 2>&1) \
+  $ (hg help help --traceback --config ui.debug=yes 2>&1) \
   > | grep -v '^ ' \
   > | egrep 'extension..[^p]|^Exception|Traceback|ImportError|not import'
   *** failed to import extension badext from $TESTTMP/badext.py: bit bucket 
overflow
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


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

2018-07-03 Thread durin42 (Augie Fackler)
This revision was automatically updated to reflect the committed changes.
Closed by commit rHGa1d5951efce7: narrow: mark the critical chunks of 
narrowing/widening as unsafe (authored by durin42, committed by ).

REPOSITORY
  rHG Mercurial

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

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()}
-

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

2018-07-03 Thread durin42 (Augie Fackler)
This revision was automatically updated to reflect the committed changes.
Closed by commit rHG6e0c66ef8cd0: repair: mark the critical section of strip() 
as unsafe (authored by durin42, committed by ).

REPOSITORY
  rHG Mercurial

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

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

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

2018-07-03 Thread durin42 (Augie Fackler)
This revision was automatically updated to reflect the committed changes.
Closed by commit rHG1ad873c3e4a4: narrowbundle2: when we handle a widen, mark 
the operation as unsafe (authored by durin42, committed by ).

REPOSITORY
  rHG Mercurial

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

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


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

2018-07-03 Thread durin42 (Augie Fackler)
This revision was automatically updated to reflect the committed changes.
Closed by commit rHG313a940d49a3: ui: add an uninterruptable context manager 
that can block SIGINT (authored by durin42, committed by ).

CHANGED PRIOR TO COMMIT
  https://phab.mercurial-scm.org/D3716?vs=9410=9411#toc

REPOSITORY
  rHG Mercurial

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

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
@@ -415,3 +415,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 = 

mercurial@38525: 3 new changesets (2 on stable)

2018-07-03 Thread Mercurial Commits
3 new changesets (2 on stable) in mercurial:

https://www.mercurial-scm.org/repo/hg/rev/77d1fa0fa2e1
changeset:   38523:77d1fa0fa2e1
branch:  stable
parent:  38455:0b63a6743010
user:Augie Fackler 
date:Tue Jul 03 12:10:21 2018 -0400
summary: Added tag 4.6.2 for changeset 0b63a6743010

https://www.mercurial-scm.org/repo/hg/rev/173cfdde0c86
changeset:   38524:173cfdde0c86
branch:  stable
user:Augie Fackler 
date:Tue Jul 03 12:10:22 2018 -0400
summary: Added signature for changeset 0b63a6743010

https://www.mercurial-scm.org/repo/hg/rev/c153f440682f
changeset:   38525:c153f440682f
bookmark:@
tag: tip
parent:  38522:54d7aaa243cc
parent:  38524:173cfdde0c86
user:Augie Fackler 
date:Tue Jul 03 12:22:37 2018 -0400
summary: merge with stable

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


[Bug 5933] New: Errors updating to branch when cloning

2018-07-03 Thread mercurial-bugs
https://bz.mercurial-scm.org/show_bug.cgi?id=5933

Bug ID: 5933
   Summary: Errors updating to branch when cloning
   Product: Mercurial
   Version: 4.5.3
  Hardware: PC
OS: Windows
Status: UNCONFIRMED
  Severity: bug
  Priority: wish
 Component: Mercurial
  Assignee: bugzi...@mercurial-scm.org
  Reporter: m...@colorado.edu
CC: mercurial-devel@mercurial-scm.org

Cloning my repository with the -r option and a branch tag fails with a
TypeError:
 hg clone -r IMOD_4-9 http://bio3d.colorado.edu/imod/nightlyBuilds/IMOD
IMOD-hgtest
adding changesets
adding manifests
adding file changes
added 31946 changesets with 48532 changes to 5434 files
new changesets 14fb4137f74b:8e6f39ae0115
updating to branch IMOD_4-9
Exception in thread Thread-8:
Traceback (most recent call last):
  File "threading.pyc", line 801, in __bootstrap_inner
  File "mercurial\worker.pyc", line 231, in run
  File "mercurial\merge.pyc", line 1380, in batchget
  File "mercurial\context.pyc", line 1282, in data
  File "hgext\keyword.pyc", line 368, in read
  File "hgext\keyword.pyc", line 273, in expand
  File "hgext\keyword.pyc", line 263, in substitute
  File "hgext\keyword.pyc", line 260, in kwsub
  File "mercurial\cmdutil.pyc", line 1695, in show
  File "mercurial\cmdutil.pyc", line 2007, in _show
  File "mercurial\templatefilters.pyc", line 372, in stringify
  File "mercurial\util.pyc", line 1017, in increasingchunks
  File "mercurial\templater.pyc", line 1272, in _flatten
  File "mercurial\templater.pyc", line 413, in runtemplate
  File "mercurial\templater.pyc", line 311, in evalrawexp
  File "mercurial\templater.pyc", line 429, in runfilter
  File "mercurial\templater.pyc", line 315, in evalfuncarg
  File "mercurial\templater.pyc", line 311, in evalrawexp
  File "mercurial\templater.pyc", line 404, in runsymbol
  File "mercurial\templatekw.pyc", line 355, in showauthor
  File "mercurial\context.pyc", line 619, in user
  File "mercurial\util.pyc", line 933, in __get__
  File "mercurial\context.pyc", line 583, in _changeset
  File "mercurial\changelog.pyc", line 481, in changelogrevision
  File "mercurial\revlog.pyc", line 1723, in revision
TypeError: 'NoneType' object has no attribute '__getitem__'

** unknown exception encountered, please report by visiting
** https://mercurial-scm.org/wiki/BugTracker
** Python 2.7.13 (v2.7.13:a06454b1afa1, Dec 17 2016, 20:53:40) [MSC v.1500 64
bit (AMD64)]
** Mercurial Distributed SCM (version 4.5.3)
** Extensions loaded: fetch, extdiff, hgk, keyword, transplant
Traceback (most recent call last):
  File "hg", line 41, in 
  File "mercurial\dispatch.pyc", line 88, in run
  File "mercurial\dispatch.pyc", line 183, in dispatch
  File "mercurial\dispatch.pyc", line 324, in _runcatch
  File "mercurial\dispatch.pyc", line 332, in _callcatch
  File "mercurial\scmutil.pyc", line 154, in callcatch
  File "mercurial\dispatch.pyc", line 314, in _runcatchfunc
  File "mercurial\dispatch.pyc", line 918, in _dispatch
  File "mercurial\dispatch.pyc", line 673, in runcommand
  File "mercurial\dispatch.pyc", line 926, in _runcommand
  File "mercurial\dispatch.pyc", line 915, in 
  File "mercurial\util.pyc", line 1195, in check
  File "mercurial\commands.pyc", line 1449, in clone
  File "mercurial\hg.pyc", line 716, in clone
  File "mercurial\hg.pyc", line 745, in update
  File "mercurial\hg.pyc", line 741, in updaterepo
  File "mercurial\merge.pyc", line 2013, in update
  File "mercurial\merge.pyc", line 1492, in applyupdates
  File "mercurial\worker.pyc", line 283, in _windowsworker
TypeError: 'NoneType' object has no attribute '__getitem__'

while cloning without -r gives an IndexError:

requesting all changes
adding changesets
adding manifests
adding file changes
added 34792 changesets with 52210 changes to 5614 files
new changesets 14fb4137f74b:bdefdee51641
updating to branch default
Exception in thread Thread-6:
Traceback (most recent call last):
  File "threading.pyc", line 801, in __bootstrap_inner
  File "mercurial\worker.pyc", line 231, in run
  File "mercurial\merge.pyc", line 1380, in batchget
  File "mercurial\context.pyc", line 1282, in data
  File "hgext\keyword.pyc", line 368, in read
  File "hgext\keyword.pyc", line 273, in expand
  File "hgext\keyword.pyc", line 263, in substitute
  File "hgext\keyword.pyc", line 261, in kwsub
  File "mercurial\ui.pyc", line 875, in popbuffer
IndexError: list index out of range

** unknown exception encountered, please report by visiting
** https://mercurial-scm.org/wiki/BugTracker
** Python 2.7.13 (v2.7.13:a06454b1afa1, Dec 17 2016, 20:53:40) [MSC v.1500 64
bit (AMD64)]
** Mercurial Distributed SCM (version 4.5.3)
** Extensions loaded: fetch, extdiff, hgk, keyword, transplant
Traceback (most recent call last):
  File "hg", line 41, in 
  File "mercurial\dispatch.pyc", line 88, in run
  File "mercurial\dispatch.pyc", line 183, in dispatch
  File 

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

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

INLINE COMMENTS

> ui.py:369
> +
> +
>  def formatter(self, topic, opts):

dropping this line (or maybe it was the one above, I'm not sure ;)) in flight

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-07-03 Thread durin42 (Augie Fackler)
durin42 updated this revision to Diff 9410.

REPOSITORY
  rHG Mercurial

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

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
@@ -415,3 +415,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,38 @@
 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', 'nointerrupt')
+if (enabled and
+self.configbool('experimental', 'nointerrupt-interactiveonly')):
+enabled = self.interactive()
+if self._uninterruptible or not enabled:
+# if 

mercurial@38522: 32 new changesets

2018-07-03 Thread Mercurial Commits
32 new changesets in mercurial:

https://www.mercurial-scm.org/repo/hg/rev/72286f9e324f
changeset:   38491:72286f9e324f
user:Matt Harbison 
date:Thu Jun 28 22:23:08 2018 -0400
summary: procutil: add a shim for translating shell commands to native 
commands

https://www.mercurial-scm.org/repo/hg/rev/2394cd58b81f
changeset:   38492:2394cd58b81f
user:Pulkit Goyal <7895pul...@gmail.com>
date:Thu Jun 28 21:24:47 2018 +0530
summary: py3: convert opts keys to bytes using pycompat.byteskwargs()

https://www.mercurial-scm.org/repo/hg/rev/da2a7d8354b2
changeset:   38493:da2a7d8354b2
user:Kyle Lippincott 
date:Thu Jun 28 18:07:22 2018 -0700
summary: unlinkpath: make empty directory removal optional (issue5901) 
(issue5826)

https://www.mercurial-scm.org/repo/hg/rev/d4be8ea8f22d
changeset:   38494:d4be8ea8f22d
user:Boris Feld 
date:Tue May 29 00:26:20 2018 +0200
summary: merge: add a 'keepconflictparent' argument to graft

https://www.mercurial-scm.org/repo/hg/rev/ba6d2c32f34a
changeset:   38495:ba6d2c32f34a
user:Sushil khanchi 
date:Thu Jun 28 23:36:45 2018 +0530
summary: rebase: add lock to cover whole dryrun process

https://www.mercurial-scm.org/repo/hg/rev/c92fdc27cbdd
changeset:   38496:c92fdc27cbdd
user:Sushil khanchi 
date:Thu Jun 28 23:57:15 2018 +0530
summary: rebase: extract dryrun as a function

https://www.mercurial-scm.org/repo/hg/rev/9c3b48fb7ac5
changeset:   38497:9c3b48fb7ac5
user:Sushil khanchi 
date:Fri Jun 29 00:22:50 2018 +0530
summary: rebase: split _origrebase() for conveniece in dryrun

https://www.mercurial-scm.org/repo/hg/rev/c892a30bafb9
changeset:   38498:c892a30bafb9
user:Sushil khanchi 
date:Fri Jun 29 00:47:33 2018 +0530
summary: rebase: no need to store backup in case of dryrun

https://www.mercurial-scm.org/repo/hg/rev/999e5c218daf
changeset:   38499:999e5c218daf
user:Sushil khanchi 
date:Fri Jun 29 01:05:08 2018 +0530
summary: rebase: suppress warning thrown when aborting rebase in case of 
dryrun

https://www.mercurial-scm.org/repo/hg/rev/02004e5c6b56
changeset:   38500:02004e5c6b56
user:Yuya Nishihara 
date:Sat Jun 30 11:29:48 2018 +0900
summary: rebase: isolate command options from internal flags

https://www.mercurial-scm.org/repo/hg/rev/53800d6eed26
changeset:   38501:53800d6eed26
user:Yuya Nishihara 
date:Sat Jun 30 11:33:05 2018 +0900
summary: rebase: convert opts dict to bytes at once

https://www.mercurial-scm.org/repo/hg/rev/2279d90eed9a
changeset:   38502:2279d90eed9a
user:Martin von Zweigbergk 
date:Fri Jun 29 14:14:35 2018 -0700
summary: httppeer: fix use of uninitialized variable with devel logging

https://www.mercurial-scm.org/repo/hg/rev/077301ac69dc
changeset:   38503:077301ac69dc
user:Danny Hooper 
date:Fri Jun 29 14:43:41 2018 -0700
summary: scmutil: fix __enter__ in progress context manager

https://www.mercurial-scm.org/repo/hg/rev/3beb0ea083df
changeset:   38504:3beb0ea083df
user:Pulkit Goyal <7895pul...@gmail.com>
date:Sat Jun 30 07:05:36 2018 +0530
summary: histedit: use hg.updaterepo() to avoid ui.{push|pop}buffer() hack

https://www.mercurial-scm.org/repo/hg/rev/c6a2ce82e60b
changeset:   38505:c6a2ce82e60b
user:Pulkit Goyal <7895pul...@gmail.com>
date:Sat Jun 30 07:10:49 2018 +0530
summary: histedit: factor out logic of processing state data in separate fn

https://www.mercurial-scm.org/repo/hg/rev/18f348e035fb
changeset:   38506:18f348e035fb
user:Pulkit Goyal <7895pul...@gmail.com>
date:Sat Jun 30 07:21:21 2018 +0530
summary: histedit: add a stateobj variable to histeditstate class

https://www.mercurial-scm.org/repo/hg/rev/03e7ec8180f0
changeset:   38507:03e7ec8180f0
user:Pulkit Goyal <7895pul...@gmail.com>
date:Sat Jun 30 07:23:02 2018 +0530
summary: histedit: use self.stateobj to check whether interrupted histedit 
exists

https://www.mercurial-scm.org/repo/hg/rev/39db5a01cd53
changeset:   38508:39db5a01cd53
user:Yuya Nishihara 
date:Sun Jul 01 21:40:55 2018 +0900
summary: cleanup: pass in overwrite flag to hg.updaterepo() as named 
argument

https://www.mercurial-scm.org/repo/hg/rev/5cfb01d5ff26
changeset:   38509:5cfb01d5ff26
user:Gregory Szorc 
date:Sat Jun 30 15:51:04 2018 -0700
summary: repository: document that file() return value conforms to interface

https://www.mercurial-scm.org/repo/hg/rev/561a450c7b64
changeset:   38510:561a450c7b64
user:Gregory Szorc 
date:Sat Jun 30 16:06:05 2018 -0700
summary: manifest: make cachesize a private attribute

https://www.mercurial-scm.org/repo/hg/rev/879cbdde63df
changeset:   38511:879cbdde63df
user:Boris Feld 
date:Thu Jun 21 23:53:43 2018 +0100
summary: revlog: do inclusive descendant testing 

D3845: worker: support more return types in posix worker

2018-07-03 Thread durin42 (Augie Fackler)
durin42 added a comment.


  >   This makes me feel that pickle is "okay" tool. @durin42, any idea?
  
  I can live with pickle in that case, I guess. Sigh.

REPOSITORY
  rHG Mercurial

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

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


[PATCH 7 of 8] resolve: add support for log-like template keywords and functions

2018-07-03 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1530450683 -32400
#  Sun Jul 01 22:11:23 2018 +0900
# Node ID c5970d8c9a15a4d4fbc1562d819e5aef4186ef84
# Parent  367bf34872603a7c006c104b3cab8de1fba99077
resolve: add support for log-like template keywords and functions

It uses wctx as the associated revision since "hg resolve" is the command
to manipulate the working directory files.

diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -4534,7 +4534,8 @@ def resolve(ui, repo, *pats, **opts):
 ui.pager('resolve')
 fm = ui.formatter('resolve', opts)
 ms = mergemod.mergestate.read(repo)
-m = scmutil.match(repo[None], pats, opts)
+wctx = repo[None]
+m = scmutil.match(wctx, pats, opts)
 
 # Labels and keys based on merge state.  Unresolved path conflicts show
 # as 'P'.  Resolved path conflicts show as 'R', the same as normal
@@ -4554,6 +4555,7 @@ def resolve(ui, repo, *pats, **opts):
 
 label, key = mergestateinfo[ms[f]]
 fm.startitem()
+fm.context(ctx=wctx)
 fm.condwrite(not nostatus, 'status', '%s ', key, label=label)
 fm.write('path', '%s\n', f, label=label)
 fm.end()
diff --git a/tests/test-resolve.t b/tests/test-resolve.t
--- a/tests/test-resolve.t
+++ b/tests/test-resolve.t
@@ -162,6 +162,10 @@ resolve -l should show resolved file as 
}
   ]
 
+  $ hg resolve -l -T '{path} {status} {p1rev} {p2rev}\n'
+  file1 R 2 1
+  file2 U 2 1
+
 resolve -m without paths should mark all resolved
 
   $ hg resolve -m
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 3 of 8] grep: add support for log-like template keywords and functions

2018-07-03 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1530450173 -32400
#  Sun Jul 01 22:02:53 2018 +0900
# Node ID 32caef1aff8134dc1ca37a7da9129fc865a4329d
# Parent  e86b388c13242726e2734a92e3b5ebaf6f6e6e48
grep: add support for log-like template keywords and functions

diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -2634,6 +2634,7 @@ def grep(ui, repo, pattern, *pats, **opt
 iter = [('', l) for l in states]
 for change, l in iter:
 fm.startitem()
+fm.context(ctx=ctx)
 fm.data(node=fm.hexfunc(scmutil.binnode(ctx)))
 
 cols = [
diff --git a/tests/test-grep.t b/tests/test-grep.t
--- a/tests/test-grep.t
+++ b/tests/test-grep.t
@@ -53,6 +53,11 @@ simple templated
   port:4:vaportight
   port:4:import/export
 
+  $ hg grep port -T '{file}:{tags}:{texts}\n'
+  port:tip:export
+  port:tip:vaportight
+  port:tip:import/export
+
 simple JSON (no "change" field)
 
   $ hg grep -Tjson port
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 5 of 8] files: add support for log-like template keywords and functions

2018-07-03 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1530450080 -32400
#  Sun Jul 01 22:01:20 2018 +0900
# Node ID 28b59a68d834e996fb00fafcae48f7bf7d5226bc
# Parent  9afe500ac808e74f2d1535ffc44d089b7cd729e5
files: add support for log-like template keywords and functions

Note that the ctx does not point to the revision where the file was
last changed, but the revision specified by -rREV option.

diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -2144,6 +2144,7 @@ def files(ui, ctx, m, fm, fmt, subrepos)
 needsfctx = ui.verbose or {'size', 'flags'} & fm.datahint()
 for f in ctx.matches(m):
 fm.startitem()
+fm.context(ctx=ctx)
 if needsfctx:
 fc = ctx[f]
 fm.write('size flags', '% 10d % 1s ', fc.size(), fc.flags())
diff --git a/tests/test-manifest.t b/tests/test-manifest.t
--- a/tests/test-manifest.t
+++ b/tests/test-manifest.t
@@ -41,6 +41,10 @@ The next call is expected to return noth
   a 2 
   b/a 2 x
   l 1 l
+  $ hg files -T '{path} {node|shortest}\n' -r.
+  a 5bdc
+  b/a 5bdc
+  l 5bdc
 
   $ hg manifest -v
   644   a
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 6 of 8] manifest: add support for log-like template keywords and functions

2018-07-03 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1530450413 -32400
#  Sun Jul 01 22:06:53 2018 +0900
# Node ID 367bf34872603a7c006c104b3cab8de1fba99077
# Parent  28b59a68d834e996fb00fafcae48f7bf7d5226bc
manifest: add support for log-like template keywords and functions

"hg manifest --all" isn't supported since it has no single associated
revision.

diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -3683,6 +3683,7 @@ def manifest(ui, repo, node=None, rev=No
 ui.pager('manifest')
 for f in ctx:
 fm.startitem()
+fm.context(ctx=ctx)
 fl = ctx[f].flags()
 fm.condwrite(ui.debugflag, 'hash', '%s ', hex(mf[f]))
 fm.condwrite(ui.verbose, 'mode type', '%s %1s ', mode[fl], char[fl])
diff --git a/tests/test-manifest.t b/tests/test-manifest.t
--- a/tests/test-manifest.t
+++ b/tests/test-manifest.t
@@ -50,6 +50,10 @@ The next call is expected to return noth
   644   a
   755 * b/a
   644 @ l
+  $ hg manifest -T '{path} {rev}\n'
+  a 1
+  b/a 1
+  l 1
 
   $ hg manifest --debug
   b789fdd96dc2f3bd229c1dd8eedf0fc60e2b68e3 644   a
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 4 of 8] files: automatically populate fields referenced from template

2018-07-03 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1530449737 -32400
#  Sun Jul 01 21:55:37 2018 +0900
# Node ID 9afe500ac808e74f2d1535ffc44d089b7cd729e5
# Parent  32caef1aff8134dc1ca37a7da9129fc865a4329d
files: automatically populate fields referenced from template

diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -2141,9 +2141,10 @@ def forget(ui, repo, match, prefix, expl
 def files(ui, ctx, m, fm, fmt, subrepos):
 ret = 1
 
+needsfctx = ui.verbose or {'size', 'flags'} & fm.datahint()
 for f in ctx.matches(m):
 fm.startitem()
-if ui.verbose:
+if needsfctx:
 fc = ctx[f]
 fm.write('size flags', '% 10d % 1s ', fc.size(), fc.flags())
 fm.data(abspath=f)
diff --git a/tests/test-manifest.t b/tests/test-manifest.t
--- a/tests/test-manifest.t
+++ b/tests/test-manifest.t
@@ -37,6 +37,10 @@ The next call is expected to return noth
   $ hg files -r . -X b
   a
   l
+  $ hg files -T '{path} {size} {flags}\n'
+  a 2 
+  b/a 2 x
+  l 1 l
 
   $ hg manifest -v
   644   a
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 8 of 8] status: add support for log-like template keywords and functions

2018-07-03 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1530451126 -32400
#  Sun Jul 01 22:18:46 2018 +0900
# Node ID 3b536d74a296aadb1e8b15edb446ed7709b8e5ec
# Parent  c5970d8c9a15a4d4fbc1562d819e5aef4186ef84
status: add support for log-like template keywords and functions

It's bound to ctx2 since "hg status" can be considered to show the status
of the files at ctx2 given ctx1 as the base.

diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -5117,6 +5117,7 @@ def status(ui, repo, *pats, **opts):
 label = 'status.' + state
 for f in files:
 fm.startitem()
+fm.context(ctx=ctx2)
 fm.condwrite(showchar, 'status', '%s ', char, label=label)
 fm.write('path', fmt, repo.pathto(f, cwd), label=label)
 if f in copy:
diff --git a/tests/test-status.t b/tests/test-status.t
--- a/tests/test-status.t
+++ b/tests/test-status.t
@@ -213,6 +213,16 @@ hg status -A:
   C .hgignore
   C modified
 
+  $ hg status -A -T '{status} {path} {node|shortest}\n'
+  A added 
+  A copied 
+  R removed 
+  ! deleted 
+  ? unknown 
+  I ignored 
+  C .hgignore 
+  C modified 
+
   $ hg status -A -Tjson
   [
{
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 8] cat: add support for log-like template keywords and functions

2018-07-03 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1530449263 -32400
#  Sun Jul 01 21:47:43 2018 +0900
# Node ID e86b388c13242726e2734a92e3b5ebaf6f6e6e48
# Parent  65ebef5548276d61a95e949d8ef2fd1b82947bc6
cat: add support for log-like template keywords and functions

diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -2290,6 +2290,7 @@ def _updatecatformatter(fm, ctx, matcher
 if decode:
 data = ctx.repo().wwritedata(path, data)
 fm.startitem()
+fm.context(ctx=ctx)
 fm.write('data', '%s', data)
 fm.data(abspath=path, path=matcher.rel(path))
 
diff --git a/tests/test-cat.t b/tests/test-cat.t
--- a/tests/test-cat.t
+++ b/tests/test-cat.t
@@ -65,10 +65,10 @@ Test fileset
 
 Test template output
 
-  $ hg --cwd tmp cat ../b ../c -T '== {path} ({abspath}) ==\n{data}'
-  == ../b (b) ==
+  $ hg --cwd tmp cat ../b ../c -T '== {path} ({abspath}) r{rev} ==\n{data}'
+  == ../b (b) r2 ==
   1
-  == ../c (c) ==
+  == ../c (c) r2 ==
   3
 
   $ hg cat b c -Tjson --output -
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 1 of 8] bookmarks: add support for log-like template keywords and functions

2018-07-03 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1530451327 -32400
#  Sun Jul 01 22:22:07 2018 +0900
# Node ID 65ebef5548276d61a95e949d8ef2fd1b82947bc6
# Parent  c1a7bbf9984d2614bfac478d42c86377a84641ba
bookmarks: add support for log-like template keywords and functions

This is basically the same as 5d9b765dbe15 "tags: unblock log-like template
keywords and functions."

diff --git a/mercurial/bookmarks.py b/mercurial/bookmarks.py
--- a/mercurial/bookmarks.py
+++ b/mercurial/bookmarks.py
@@ -923,11 +923,14 @@ def _printbookmarks(ui, repo, bmarks, **
 """
 opts = pycompat.byteskwargs(opts)
 fm = ui.formatter('bookmarks', opts)
+contexthint = fm.contexthint('bookmark rev node active')
 hexfn = fm.hexfunc
 if len(bmarks) == 0 and fm.isplain():
 ui.status(_("no bookmarks set\n"))
 for bmark, (n, prefix, label) in sorted(bmarks.iteritems()):
 fm.startitem()
+if 'ctx' in contexthint:
+fm.context(ctx=repo[n])
 if not ui.quiet:
 fm.plain(' %s ' % prefix, label=label)
 fm.write('bookmark', '%s', bmark, label=label)
diff --git a/tests/test-bookmarks.t b/tests/test-bookmarks.t
--- a/tests/test-bookmarks.t
+++ b/tests/test-bookmarks.t
@@ -77,6 +77,11 @@ list bookmarks
   $ hg commit -m 1 --config "$TESTHOOK"
   test-hook-bookmark: X2:  f7b1eb17ad24730a1651fccd46c43826d1bbc2ac -> 
925d80f479bb026b0fb3deb27503780b13f74123
 
+  $ hg bookmarks -T '{rev}:{node|shortest} {bookmark} {desc|firstline}\n'
+  0:f7b1 X 0
+  1:925d X2 1
+  -1: Y 
+
   $ hg bookmarks -Tjson
   [
{
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 4 of 4] revlog: reuse 'descendant' implemention in 'isancestor'

2018-07-03 Thread Martin von Zweigbergk via Mercurial-devel
On Tue, Jul 3, 2018 at 3:05 AM Boris FELD  wrote:

> On 02/07/2018 18:37, Martin von Zweigbergk via Mercurial-devel wrote:
>
>
>
> On Mon, Jul 2, 2018 at 5:05 AM Yuya Nishihara  wrote:
>
>> On Sun, 01 Jul 2018 08:38:42 +0200, Paul Morelle wrote:
>> > # HG changeset patch
>> > # User Boris Feld 
>> > # Date 1529622442 -3600
>> > #  Fri Jun 22 00:07:22 2018 +0100
>> > # Node ID 6bfe8fc36b4e20fcdf6cc49fe9ddb6e79bcf213f
>> > # Parent  5ea9c5d20ecc1aac2aecdd4c0902b3cd470b04d5
>> > # EXP-Topic descendant
>> > # Available At https://bitbucket.org/octobus/mercurial-devel/
>> > #  hg pull https://bitbucket.org/octobus/mercurial-devel/
>> -r 6bfe8fc36b4e
>> > revlog: reuse 'descendant' implemention in 'isancestor'
>>
>> Queued the series, thanks.
>>
>> > We should probably cleanup the API at some point to avoid having so
>> many similar
>> > functions. However, we focus on an efficient implementation for now.
>>
>> Yeah.
>>
>
> Perhaps we should rename "descendant" to "isdescendant" to match
> "isancestor" then.
>
>
> Having `isdescendant` and `isancestor` sharing the same signature and
> behavior except for their arguments types (one accepting revs and the other
> accepting nodes) seems confusing.
>

Of course (but I'm not sure it's much more confusing than having descendant
and isancestor work on different types). I didn't mean to suggest that they
should be different, I had just not checked. I actually had felt like the
new isancestor should have been called isancestorrev or isrevancestor or
revisancestor, but I didn't bother suggesting it.


> We could maybe use the `rev(s)` prefix, giving for example `isancestorrev`
> and `commonancestorheadrevs`. This prefix is already used in the code base:
>
> * revlog.parentrevs
> * revlog.findcommonmissing vs revlog.findmissingrevs
> * revlog.heads vs revlog.headrevs
> * revlog.incrementalmissingrevs
>
>
>
>
> ___
> Mercurial-devel mailing 
> listMercurial-devel@mercurial-scm.orghttps://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: D3845: worker: support more return types in posix worker

2018-07-03 Thread Yuya Nishihara
> +while True:
> +try:
> +yield cbor.load(fp)
> +except EOFError:
> +break

Unfortunately this doesn't work because the cbor decoder doesn't care for
EOF. It tries to raise CBORDEcodeError and fail at `fp.tell()`. We'll have
to either fix the upstream cbor library or duplicate some parts to cborutil.
(or add an extra length field to feed a single chunk to `cbor.loads()`.)

This makes me feel that pickle is "okay" tool. @durin42, any idea?
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D3845: worker: support more return types in posix worker

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


  > +while True:
  >  +try:
  >  +yield cbor.load(fp)
  >  +except EOFError:
  >  +break
  
  Unfortunately this doesn't work because the cbor decoder doesn't care for
  EOF. It tries to raise CBORDEcodeError and fail at `fp.tell()`. We'll have
  to either fix the upstream cbor library or duplicate some parts to cborutil.
  (or add an extra length field to feed a single chunk to `cbor.loads()`.)
  
  This makes me feel that pickle is "okay" tool. @durin42, any idea?

REPOSITORY
  rHG Mercurial

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

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


Re: [PATCH] revset: add partial support for ancestor(wdir())

2018-07-03 Thread Pulkit Goyal
On Sun, Jul 1, 2018 at 7:06 AM Yuya Nishihara  wrote:

> On Sat, 30 Jun 2018 23:49:55 +0530, Pulkit Goyal wrote:
> > On Sat, Jun 30, 2018 at 8:24 AM Yuya Nishihara  wrote:
> >
> > > # HG changeset patch
> > > # User Yuya Nishihara 
> > > # Date 1530281603 -32400
> > > #  Fri Jun 29 23:13:23 2018 +0900
> > > # Node ID 1a8d711aa48c9f42fdb6b66886685b5d035e7d1e
> > > # Parent  70f7552b82e5f30f9016de57bcd217dc8061c859
> > > revset: add partial support for ancestor(wdir())
> > >
> > > It's easy, so let's make it happen. I'm not certain if 'wdir() &'
> should
> > > be required.
> >
> > ancestors(wdir()) works without it, but ancestor(wdir()) doesn't
> > > as of now.
> >
> >
> > ​Did you mean ancestor(wdir()) works and ancestors(wdir()) does not?
>
> No.
>
>   'wdir() & ancestor(wdir())' => [wdir()]
>   'wdir() & ancestors(wdir())' => [wdir()]
>   'ancestors(wdir())' => [... wdir()]
>
> but
>
>   'ancestor(wdir())' => []
>

​Oh, thanks for the explanation. Queued this, many thanks!​
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D3873: rebase: refactor logic to read rebasestate in a separate function

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


  >   > FWIW, I don't have any better idea to keep old hg not crash with new 
state
  >   >  file, other than:
  >   >
  >   >   a. use separate file (e.g. "rebasestate2") and leave "rebasestate" in 
old
  >   >  format (or make it an empty file to trigger error.)
  >   
  >   
  >   Yeah, I was preventing this for a long time but feels like I can't 
anymore.
  >   How about having a `.hg/state/` where we will have our new histedit and
  >   rebase state files?
  
  A separate directory wouldn't make the situation better. We can't stop writing
  a v1 state file anyway since missing v1 state file means "no rebase in 
progress"
  in old hg versions.

REPOSITORY
  rHG Mercurial

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

To: pulkit, #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: D3873: rebase: refactor logic to read rebasestate in a separate function

2018-07-03 Thread Yuya Nishihara
>   > FWIW, I don't have any better idea to keep old hg not crash with new state
>   >  file, other than:
>   >
>   >   a. use separate file (e.g. "rebasestate2") and leave "rebasestate" in 
> old
>   >  format (or make it an empty file to trigger error.)
>   
>   
>   Yeah, I was preventing this for a long time but feels like I can't anymore.
>   How about having a `.hg/state/` where we will have our new histedit and
>   rebase state files?

A separate directory wouldn't make the situation better. We can't stop writing
a v1 state file anyway since missing v1 state file means "no rebase in progress"
in old hg versions.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 04 of 12 V2] diffutil: extract diff options code into a dedicated util-module

2018-07-03 Thread Yuya Nishihara
On Tue, 03 Jul 2018 12:32:23 +0200, Boris Feld wrote:
> # HG changeset patch
> # User Boris Feld 
> # Date 1530195073 -7200
> #  Thu Jun 28 16:11:13 2018 +0200
> # Node ID 2885f27ab442bf42ad8c21c47f4304132a62f59a
> # Parent  9d94a3118a9c253a09bdf48258548dca92e35018
> # EXP-Topic diff-cleanup
> # Available At https://bitbucket.org/octobus/mercurial-devel/
> #  hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 
> 2885f27ab442
> diffutil: extract diff options code into a dedicated util-module

This can't be applied. Can you rebase?

> copy from mercurial/patch.py
> copy to mercurial/utils/diffutil.py
> --- a/mercurial/patch.py
> +++ b/mercurial/utils/diffutil.py

My two cents. It's probably better to not put diffutil under the utils package
because util* is a set of classes/functions not depending on ui, repo, etc.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 03 of 12 V2] context: also accept diff option directly

2018-07-03 Thread Yuya Nishihara
On Tue, 03 Jul 2018 12:32:22 +0200, Boris Feld wrote:
> # HG changeset patch
> # User Boris Feld 
> # Date 1529756343 -3600
> #  Sat Jun 23 13:19:03 2018 +0100
> # Node ID 9d94a3118a9c253a09bdf48258548dca92e35018
> # Parent  e6ba698b9c7354f21e2ae764a11e043872990d79
> # EXP-Topic diff-cleanup
> # Available At https://bitbucket.org/octobus/mercurial-devel/
> #  hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 
> 9d94a3118a9c
> context: also accept diff option directly

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


Re: [PATCH 4 of 4] revlog: reuse 'descendant' implemention in 'isancestor'

2018-07-03 Thread Boris FELD

On 02/07/2018 18:37, Martin von Zweigbergk via Mercurial-devel wrote:



On Mon, Jul 2, 2018 at 5:05 AM Yuya Nishihara > wrote:


On Sun, 01 Jul 2018 08:38:42 +0200, Paul Morelle wrote:
> # HG changeset patch
> # User Boris Feld mailto:boris.f...@octobus.net>>
> # Date 1529622442 -3600
> #      Fri Jun 22 00:07:22 2018 +0100
> # Node ID 6bfe8fc36b4e20fcdf6cc49fe9ddb6e79bcf213f
> # Parent  5ea9c5d20ecc1aac2aecdd4c0902b3cd470b04d5
> # EXP-Topic descendant
> # Available At https://bitbucket.org/octobus/mercurial-devel/
> #              hg pull
https://bitbucket.org/octobus/mercurial-devel/ -r 6bfe8fc36b4e
> revlog: reuse 'descendant' implemention in 'isancestor'

Queued the series, thanks.

> We should probably cleanup the API at some point to avoid having
so many similar
> functions. However, we focus on an efficient implementation for now.

Yeah.


Perhaps we should rename "descendant" to "isdescendant" to match 
"isancestor" then.


Having `isdescendant` and `isancestor` sharing the same signature and 
behavior except for their arguments types (one accepting revs and the 
other accepting nodes) seems confusing.


We could maybe use the `rev(s)` prefix, giving for example 
`isancestorrev` and `commonancestorheadrevs`. This prefix is already 
used in the code base:


* revlog.parentrevs
* revlog.findcommonmissing vs revlog.findmissingrevs
* revlog.heads vs revlog.headrevs
* revlog.incrementalmissingrevs





___
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


[PATCH 05 of 12 V2] tests: update test-context.py to use diffopts as diff argument

2018-07-03 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1529756783 -3600
#  Sat Jun 23 13:26:23 2018 +0100
# Node ID 0d2b1cf8cd7ecf81984253ac1e5142f35a53eaa6
# Parent  2885f27ab442bf42ad8c21c47f4304132a62f59a
# EXP-Topic diff-cleanup
# Available At https://bitbucket.org/octobus/mercurial-devel/
#  hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 
0d2b1cf8cd7e
tests: update test-context.py to use diffopts as diff argument

diff --git a/tests/test-context.py b/tests/test-context.py
--- a/tests/test-context.py
+++ b/tests/test-context.py
@@ -10,6 +10,7 @@ from mercurial import (
 scmutil,
 ui as uimod,
 )
+from mercurial.utils import diffutil
 
 print_ = print
 def print(*args, **kwargs):
@@ -76,8 +77,8 @@ ctxb = context.memctx(repo, [ctxa.node()
 print(ctxb.status(ctxa))
 
 # test performing a diff on a memctx
-
-for d in ctxb.diff(ctxa, opts={'git': True}):
+diffopts = diffutil.diffopts(repo.ui, {'git': True})
+for d in ctxb.diff(ctxa, opts=diffopts):
 printb(d, end=b'')
 
 # test safeness and correctness of "ctx.status()"
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 12 of 12 V2] diff: use `context.diff` to produce diff

2018-07-03 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1527082304 -7200
#  Wed May 23 15:31:44 2018 +0200
# Node ID 9023a46c916c103ebafba08e16e7c029c79a7137
# Parent  f323b9631f290ec68d5e5322eedf4b86676a1113
# EXP-Topic diff-cleanup
# Available At https://bitbucket.org/octobus/mercurial-devel/
#  hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 
9023a46c916c
diff: use `context.diff` to produce diff

We want to make sure `context.diff` if full featured. Using it in the main
diff code path is a good way to do so.

The end goal is to be able to easily compute diff between in-memory context.

diff --git a/mercurial/logcmdutil.py b/mercurial/logcmdutil.py
--- a/mercurial/logcmdutil.py
+++ b/mercurial/logcmdutil.py
@@ -76,9 +76,9 @@ def diffordiffstat(ui, repo, diffopts, n
 if not ui.plain():
 width = ui.termwidth()
 
-chunks = patch.diff(repo, node1, node2, match, changes, opts=diffopts,
-prefix=prefix, relroot=relroot,
-hunksfilterfn=hunksfilterfn)
+chunks = repo[node2].diff(repo[node1], match, changes, opts=diffopts,
+  prefix=prefix, relroot=relroot,
+  hunksfilterfn=hunksfilterfn)
 
 if fp is not None or ui.canwritewithoutlabels():
 out = fp or ui
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 04 of 12 V2] diffutil: extract diff options code into a dedicated util-module

2018-07-03 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1530195073 -7200
#  Thu Jun 28 16:11:13 2018 +0200
# Node ID 2885f27ab442bf42ad8c21c47f4304132a62f59a
# Parent  9d94a3118a9c253a09bdf48258548dca92e35018
# EXP-Topic diff-cleanup
# Available At https://bitbucket.org/octobus/mercurial-devel/
#  hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 
2885f27ab442
diffutil: extract diff options code into a dedicated util-module

We want to be able to create and use diffoptions in more places. Currently the
official function to instantiate diffoptions live into `mercurial.patch`. A
module too high level to be easily imported in some places.

So we extract the diff options related function in their own utility module.

diff --git a/mercurial/patch.py b/mercurial/patch.py
--- a/mercurial/patch.py
+++ b/mercurial/patch.py
@@ -41,6 +41,7 @@ from . import (
 )
 from .utils import (
 dateutil,
+diffutil,
 procutil,
 stringutil,
 )
@@ -2231,95 +2232,9 @@ def changedfiles(ui, repo, patchpath, st
 class GitDiffRequired(Exception):
 pass
 
-def diffallopts(ui, opts=None, untrusted=False, section='diff'):
-'''return diffopts with all features supported and parsed'''
-return difffeatureopts(ui, opts=opts, untrusted=untrusted, section=section,
-   git=True, whitespace=True, formatchanging=True)
-
-diffopts = diffallopts
-
-def difffeatureopts(ui, opts=None, untrusted=False, section='diff', git=False,
-whitespace=False, formatchanging=False):
-'''return diffopts with only opted-in features parsed
-
-Features:
-- git: git-style diffs
-- whitespace: whitespace options like ignoreblanklines and ignorews
-- formatchanging: options that will likely break or cause correctness 
issues
-  with most diff parsers
-'''
-def get(key, name=None, getter=ui.configbool, forceplain=None):
-if opts:
-v = opts.get(key)
-# diffopts flags are either None-default (which is passed
-# through unchanged, so we can identify unset values), or
-# some other falsey default (eg --unified, which defaults
-# to an empty string). We only want to override the config
-# entries from hgrc with command line values if they
-# appear to have been set, which is any truthy value,
-# True, or False.
-if v or isinstance(v, bool):
-return v
-if forceplain is not None and ui.plain():
-return forceplain
-return getter(section, name or key, untrusted=untrusted)
-
-# core options, expected to be understood by every diff parser
-buildopts = {
-'nodates': get('nodates'),
-'showfunc': get('show_function', 'showfunc'),
-'context': get('unified', getter=ui.config),
-}
-buildopts['worddiff'] = ui.configbool('experimental', 'worddiff')
-buildopts['xdiff'] = ui.configbool('experimental', 'xdiff')
-
-if git:
-buildopts['git'] = get('git')
-
-# since this is in the experimental section, we need to call
-# ui.configbool directory
-buildopts['showsimilarity'] = ui.configbool('experimental',
-
'extendedheader.similarity')
-
-# need to inspect the ui object instead of using get() since we want to
-# test for an int
-hconf = ui.config('experimental', 'extendedheader.index')
-if hconf is not None:
-hlen = None
-try:
-# the hash config could be an integer (for length of hash) or a
-# word (e.g. short, full, none)
-hlen = int(hconf)
-if hlen < 0 or hlen > 40:
-msg = _("invalid length for extendedheader.index: '%d'\n")
-ui.warn(msg % hlen)
-except ValueError:
-# default value
-if hconf == 'short' or hconf == '':
-hlen = 12
-elif hconf == 'full':
-hlen = 40
-elif hconf != 'none':
-msg = _("invalid value for extendedheader.index: '%s'\n")
-ui.warn(msg % hconf)
-finally:
-buildopts['index'] = hlen
-
-if whitespace:
-buildopts['ignorews'] = get('ignore_all_space', 'ignorews')
-buildopts['ignorewsamount'] = get('ignore_space_change',
-  'ignorewsamount')
-buildopts['ignoreblanklines'] = get('ignore_blank_lines',
-'ignoreblanklines')
-buildopts['ignorewseol'] = get('ignore_space_at_eol', 'ignorewseol')
-if formatchanging:
-buildopts['text'] = opts and opts.get('text')
-binary = None if opts is None else opts.get('binary')
-buildopts['nobinary'] = (not binary if binary is not None
-  

[PATCH 01 of 12 V2] context: explicitly take diffopts in `context.diff` (API)

2018-07-03 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1526994172 -7200
#  Tue May 22 15:02:52 2018 +0200
# Node ID ba68e0459f1fc2d1d86496c4ae42ab99adf08d11
# Parent  1a05e205832a929374c010b2dc6a1c65a60186a3
# EXP-Topic diff-cleanup
# Available At https://bitbucket.org/octobus/mercurial-devel/
#  hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 
ba68e0459f1f
context: explicitly take diffopts in `context.diff` (API)

To provide a proper replacement for the `patch.diff(…)` function, the
`context.diff(…)` method needs to be able to take more parameters. To
distinguish the diff options from the new other arguments, we upgrade the diff
options to its own explicit argument.

diff --git a/contrib/synthrepo.py b/contrib/synthrepo.py
--- a/contrib/synthrepo.py
+++ b/contrib/synthrepo.py
@@ -196,7 +196,8 @@ def analyze(ui, repo, *revs, **opts):
 if lastctx.rev() != nullrev:
 timedelta = ctx.date()[0] - lastctx.date()[0]
 interarrival[roundto(timedelta, 300)] += 1
-diff = sum((d.splitlines() for d in ctx.diff(pctx, git=True)), [])
+diff = sum((d.splitlines()
+   for d in ctx.diff(pctx, opts={'git': True})), [])
 fileadds, diradds, fileremoves, filechanges = 0, 0, 0, 0
 for filename, mar, lineadd, lineremove, isbin in 
parsegitdiff(diff):
 if isbin:
diff --git a/mercurial/context.py b/mercurial/context.py
--- a/mercurial/context.py
+++ b/mercurial/context.py
@@ -294,13 +294,13 @@ class basectx(object):
   auditor=r.nofsauditor, ctx=self,
   listsubrepos=listsubrepos, badfn=badfn)
 
-def diff(self, ctx2=None, match=None, **opts):
+def diff(self, ctx2=None, match=None, opts=None):
 """Returns a diff generator for the given contexts and matcher"""
 if ctx2 is None:
 ctx2 = self.p1()
 if ctx2 is not None:
 ctx2 = self._repo[ctx2]
-diffopts = patch.diffopts(self._repo.ui, pycompat.byteskwargs(opts))
+diffopts = patch.diffopts(self._repo.ui, opts)
 return patch.diff(self._repo, ctx2, self, match=match, opts=diffopts)
 
 def dirs(self):
diff --git a/mercurial/hgweb/webutil.py b/mercurial/hgweb/webutil.py
--- a/mercurial/hgweb/webutil.py
+++ b/mercurial/hgweb/webutil.py
@@ -658,7 +658,7 @@ def diffstatgen(ctx, basectx):
 '''Generator function that provides the diffstat data.'''
 
 stats = patch.diffstatdata(
-util.iterlines(ctx.diff(basectx, noprefix=False)))
+util.iterlines(ctx.diff(basectx, opts={'noprefix': False})))
 maxname, maxtotal, addtotal, removetotal, binary = patch.diffstatsum(stats)
 while True:
 yield stats, maxname, maxtotal, addtotal, removetotal, binary
diff --git a/mercurial/obsutil.py b/mercurial/obsutil.py
--- a/mercurial/obsutil.py
+++ b/mercurial/obsutil.py
@@ -396,9 +396,9 @@ def _cmpdiff(leftctx, rightctx):
 # Leftctx or right ctx might be filtered, so we need to use the contexts
 # with an unfiltered repository to safely compute the diff
 leftunfi = leftctx._repo.unfiltered()[leftctx.rev()]
-leftdiff = leftunfi.diff(git=1)
+leftdiff = leftunfi.diff(opts={'git': True})
 rightunfi = rightctx._repo.unfiltered()[rightctx.rev()]
-rightdiff = rightunfi.diff(git=1)
+rightdiff = rightunfi.diff(opts={'git': True})
 
 left, right = (0, 0)
 while None not in (left, right):
diff --git a/mercurial/revset.py b/mercurial/revset.py
--- a/mercurial/revset.py
+++ b/mercurial/revset.py
@@ -1802,7 +1802,7 @@ def matching(repo, subset, x):
 'phase': lambda r: repo[r].phase(),
 'substate': lambda r: repo[r].substate,
 'summary': lambda r: repo[r].description().splitlines()[0],
-'diff': lambda r: list(repo[r].diff(git=True),)
+'diff': lambda r: list(repo[r].diff(opts={'git': True}),)
 }
 for info in fields:
 getfield = _funcs.get(info, None)
diff --git a/mercurial/templatekw.py b/mercurial/templatekw.py
--- a/mercurial/templatekw.py
+++ b/mercurial/templatekw.py
@@ -262,7 +262,8 @@ def showdiffstat(context, mapping):
 "modified files: +added/-removed lines"
 """
 ctx = context.resource(mapping, 'ctx')
-stats = patch.diffstatdata(util.iterlines(ctx.diff(noprefix=False)))
+diff = ctx.diff(opts={'noprefix': False})
+stats = patch.diffstatdata(util.iterlines(diff))
 maxname, maxtotal, adds, removes, binary = patch.diffstatsum(stats)
 return '%d: +%d/-%d' % (len(stats), adds, removes)
 
diff --git a/tests/test-context.py b/tests/test-context.py
--- a/tests/test-context.py
+++ b/tests/test-context.py
@@ -77,7 +77,7 @@ print(ctxb.status(ctxa))
 
 # test performing a diff on a memctx
 
-for d in ctxb.diff(ctxa, git=True):
+for d in ctxb.diff(ctxa, opts={'git': True}):
 printb(d, end=b'')
 
 # test safeness and correctness of "ctx.status()"

[PATCH 09 of 12 V2] synthrepo: pass a diffopts object to context.diff

2018-07-03 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1529757988 -7200
#  Sat Jun 23 14:46:28 2018 +0200
# Node ID d05882e5af1a7d482eedea7aebc7eb1cba000643
# Parent  d2d2b80cc405fdb1e93c257e7290851069040ca8
# EXP-Topic diff-cleanup
# Available At https://bitbucket.org/octobus/mercurial-devel/
#  hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 
d05882e5af1a
synthrepo: pass a diffopts object to context.diff

diff --git a/contrib/synthrepo.py b/contrib/synthrepo.py
--- a/contrib/synthrepo.py
+++ b/contrib/synthrepo.py
@@ -60,7 +60,10 @@ from mercurial import (
 registrar,
 scmutil,
 )
-from mercurial.utils import dateutil
+from mercurial.utils import (
+dateutil,
+diffutil,
+)
 
 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' 
for
 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
@@ -196,8 +199,9 @@ def analyze(ui, repo, *revs, **opts):
 if lastctx.rev() != nullrev:
 timedelta = ctx.date()[0] - lastctx.date()[0]
 interarrival[roundto(timedelta, 300)] += 1
+diffopts = diffutil.diffopts(ctx._repo.ui, {'git': True})
 diff = sum((d.splitlines()
-   for d in ctx.diff(pctx, opts={'git': True})), [])
+   for d in ctx.diff(pctx, opts=diffopts)), [])
 fileadds, diradds, fileremoves, filechanges = 0, 0, 0, 0
 for filename, mar, lineadd, lineremove, isbin in 
parsegitdiff(diff):
 if isbin:
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 07 of 12 V2] revset: pass an explicit `diffopts` objet to context.diff

2018-07-03 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1529757430 -7200
#  Sat Jun 23 14:37:10 2018 +0200
# Node ID 6f1fd2975f98351086353b56ff4e9dfb54421648
# Parent  de55d9d098b8166d5826a2c77c5c34c1f94672c9
# EXP-Topic diff-cleanup
# Available At https://bitbucket.org/octobus/mercurial-devel/
#  hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 
6f1fd2975f98
revset: pass an explicit `diffopts` objet to context.diff

diff --git a/mercurial/revset.py b/mercurial/revset.py
--- a/mercurial/revset.py
+++ b/mercurial/revset.py
@@ -33,6 +33,7 @@ from . import (
 )
 from .utils import (
 dateutil,
+diffutil,
 stringutil,
 )
 
@@ -1802,7 +1803,8 @@ def matching(repo, subset, x):
 'phase': lambda r: repo[r].phase(),
 'substate': lambda r: repo[r].substate,
 'summary': lambda r: repo[r].description().splitlines()[0],
-'diff': lambda r: list(repo[r].diff(opts={'git': True}),)
+'diff': lambda r: list(repo[r].diff(
+opts=diffutil.diffopts(repo.ui, {'git': True}))),
 }
 for info in fields:
 getfield = _funcs.get(info, None)
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 10 of 12 V2] obsutil: pass a diffopts object to context.diff

2018-07-03 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1529758816 -7200
#  Sat Jun 23 15:00:16 2018 +0200
# Node ID 8c1405ef2dd9a1bf82dc320b39ee6a359240a088
# Parent  d05882e5af1a7d482eedea7aebc7eb1cba000643
# EXP-Topic diff-cleanup
# Available At https://bitbucket.org/octobus/mercurial-devel/
#  hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 
8c1405ef2dd9
obsutil: pass a diffopts object to context.diff

diff --git a/mercurial/obsutil.py b/mercurial/obsutil.py
--- a/mercurial/obsutil.py
+++ b/mercurial/obsutil.py
@@ -15,7 +15,10 @@ from . import (
 phases,
 util,
 )
-from .utils import dateutil
+from .utils import (
+dateutil,
+diffutil,
+)
 
 ### obsolescence marker flag
 
@@ -392,13 +395,13 @@ def _cmpdiff(leftctx, rightctx):
 
 This is a first and basic implementation, with many shortcoming.
 """
-
+diffopts = diffutil.diffopts(leftctx._repo.ui, {'git': True})
 # Leftctx or right ctx might be filtered, so we need to use the contexts
 # with an unfiltered repository to safely compute the diff
 leftunfi = leftctx._repo.unfiltered()[leftctx.rev()]
-leftdiff = leftunfi.diff(opts={'git': True})
+leftdiff = leftunfi.diff(opts=diffopts)
 rightunfi = rightctx._repo.unfiltered()[rightctx.rev()]
-rightdiff = rightunfi.diff(opts={'git': True})
+rightdiff = rightunfi.diff(opts=diffopts)
 
 left, right = (0, 0)
 while None not in (left, right):
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 08 of 12 V2] webutil: pass a diffopts object to context.diff

2018-07-03 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1529757778 -7200
#  Sat Jun 23 14:42:58 2018 +0200
# Node ID d2d2b80cc405fdb1e93c257e7290851069040ca8
# Parent  6f1fd2975f98351086353b56ff4e9dfb54421648
# EXP-Topic diff-cleanup
# Available At https://bitbucket.org/octobus/mercurial-devel/
#  hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 
d2d2b80cc405
webutil: pass a diffopts object to context.diff

diff --git a/mercurial/hgweb/webutil.py b/mercurial/hgweb/webutil.py
--- a/mercurial/hgweb/webutil.py
+++ b/mercurial/hgweb/webutil.py
@@ -41,6 +41,7 @@ from .. import (
 )
 
 from ..utils import (
+diffutil,
 stringutil,
 )
 
@@ -206,8 +207,8 @@ def _siblings(siblings=None, hiderev=Non
 return templateutil.mappinggenerator(_ctxsgen, args=(siblings,))
 
 def difffeatureopts(req, ui, section):
-diffopts = patch.difffeatureopts(ui, untrusted=True,
- section=section, whitespace=True)
+diffopts = diffutil.difffeatureopts(ui, untrusted=True,
+section=section, whitespace=True)
 
 for k in ('ignorews', 'ignorewsamount', 'ignorewseol', 'ignoreblanklines'):
 v = req.qsparams.get(k)
@@ -657,8 +658,9 @@ def compare(contextnum, leftlines, right
 def diffstatgen(ctx, basectx):
 '''Generator function that provides the diffstat data.'''
 
+diffopts = patch.diffopts(ctx._repo.ui, {'noprefix': False})
 stats = patch.diffstatdata(
-util.iterlines(ctx.diff(basectx, opts={'noprefix': False})))
+util.iterlines(ctx.diff(basectx, opts=diffopts)))
 maxname, maxtotal, addtotal, removetotal, binary = patch.diffstatsum(stats)
 while True:
 yield stats, maxname, maxtotal, addtotal, removetotal, binary
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 11 of 12 V2] context: no longer accept diff options as dictionnary

2018-07-03 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1529758985 -7200
#  Sat Jun 23 15:03:05 2018 +0200
# Node ID f323b9631f290ec68d5e5322eedf4b86676a1113
# Parent  8c1405ef2dd9a1bf82dc320b39ee6a359240a088
# EXP-Topic diff-cleanup
# Available At https://bitbucket.org/octobus/mercurial-devel/
#  hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 
f323b9631f29
context: no longer accept diff options as dictionnary

Since we already broke the API earlier in this stack, there are no point to
introducing a new deprecation warning.

diff --git a/mercurial/context.py b/mercurial/context.py
--- a/mercurial/context.py
+++ b/mercurial/context.py
@@ -30,7 +30,6 @@ from . import (
 error,
 fileset,
 match as matchmod,
-mdiff,
 obsolete as obsmod,
 patch,
 pathutil,
@@ -304,10 +303,7 @@ class basectx(object):
 if ctx2 is not None:
 ctx2 = self._repo[ctx2]
 
-if isinstance(opts, mdiff.diffopts):
-diffopts = opts
-else:
-diffopts = patch.diffopts(self._repo.ui, opts)
+diffopts = opts
 return patch.diff(self._repo, ctx2, self, match=match, changes=changes,
   opts=diffopts, losedatafn=losedatafn, prefix=prefix,
   relroot=relroot, copy=copy,
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 02 of 12 V2] context: also take all other arguments than `patch.diff` accept

2018-07-03 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1527082300 -7200
#  Wed May 23 15:31:40 2018 +0200
# Node ID e6ba698b9c7354f21e2ae764a11e043872990d79
# Parent  ba68e0459f1fc2d1d86496c4ae42ab99adf08d11
# EXP-Topic diff-cleanup
# Available At https://bitbucket.org/octobus/mercurial-devel/
#  hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 
e6ba698b9c73
context: also take all other arguments than `patch.diff` accept

This is needed to use `context.diff` as a full replacement of `patch.diff`

diff --git a/mercurial/context.py b/mercurial/context.py
--- a/mercurial/context.py
+++ b/mercurial/context.py
@@ -294,14 +294,19 @@ class basectx(object):
   auditor=r.nofsauditor, ctx=self,
   listsubrepos=listsubrepos, badfn=badfn)
 
-def diff(self, ctx2=None, match=None, opts=None):
+def diff(self, ctx2=None, match=None, changes=None, opts=None,
+losedatafn=None, prefix='', relroot='', copy=None,
+hunksfilterfn=None):
 """Returns a diff generator for the given contexts and matcher"""
 if ctx2 is None:
 ctx2 = self.p1()
 if ctx2 is not None:
 ctx2 = self._repo[ctx2]
 diffopts = patch.diffopts(self._repo.ui, opts)
-return patch.diff(self._repo, ctx2, self, match=match, opts=diffopts)
+return patch.diff(self._repo, ctx2, self, match=match, changes=changes,
+  opts=diffopts, losedatafn=losedatafn, prefix=prefix,
+  relroot=relroot, copy=copy,
+  hunksfilterfn=hunksfilterfn)
 
 def dirs(self):
 return self._manifest.dirs()
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 03 of 12 V2] context: also accept diff option directly

2018-07-03 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1529756343 -3600
#  Sat Jun 23 13:19:03 2018 +0100
# Node ID 9d94a3118a9c253a09bdf48258548dca92e35018
# Parent  e6ba698b9c7354f21e2ae764a11e043872990d79
# EXP-Topic diff-cleanup
# Available At https://bitbucket.org/octobus/mercurial-devel/
#  hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 
9d94a3118a9c
context: also accept diff option directly

For now we accept both diff option and dictionary. This will let us upgrade
internal users gradually before we drop the old API at the end of this series.

diff --git a/mercurial/context.py b/mercurial/context.py
--- a/mercurial/context.py
+++ b/mercurial/context.py
@@ -30,6 +30,7 @@ from . import (
 error,
 fileset,
 match as matchmod,
+mdiff,
 obsolete as obsmod,
 patch,
 pathutil,
@@ -302,7 +303,11 @@ class basectx(object):
 ctx2 = self.p1()
 if ctx2 is not None:
 ctx2 = self._repo[ctx2]
-diffopts = patch.diffopts(self._repo.ui, opts)
+
+if isinstance(opts, mdiff.diffopts):
+diffopts = opts
+else:
+diffopts = patch.diffopts(self._repo.ui, opts)
 return patch.diff(self._repo, ctx2, self, match=match, changes=changes,
   opts=diffopts, losedatafn=losedatafn, prefix=prefix,
   relroot=relroot, copy=copy,
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel