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

2017-08-17 Thread quark (Jun Wu)
quark updated this revision to Diff 1059.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D441?vs=1058&id=1059

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

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

CHANGE DETAILS

diff --git a/tests/test-revset.t b/tests/test-revset.t
--- a/tests/test-revset.t
+++ b/tests/test-revset.t
@@ -4511,3 +4511,173 @@
 
   $ hg log -r 'successors(B+A)-contentdivergent()-obsolete()' -T '{desc}\n'
   Z
+
+Test `draft() & ::x` optimization
+
+  $ hg init $TESTTMP/repo2
+  $ cd $TESTTMP/repo2
+  $ hg debugdrawdag <<'EOS'
+  >   P5 S1
+  >|  |
+  > S2 | D3
+  >   \|/
+  >   P4
+  >|
+  >   P3 D2
+  >|  |
+  >   P2 D1
+  >|/
+  >   P1
+  >|
+  >   P0
+  > EOS
+  $ hg phase --public -r P4+P5
+  $ hg phase --force --secret -r S1+S2
+  $ hg log -G -T '{rev} {desc} {phase}' -r 'sort(all(), topo, 
topo.firstbranch=P5)'
+  o  8 P5 public
+  |
+  | o  10 S1 secret
+  | |
+  | o  7 D3 draft
+  |/
+  | o  9 S2 secret
+  |/
+  o  6 P4 public
+  |
+  o  5 P3 public
+  |
+  o  3 P2 public
+  |
+  | o  4 D2 draft
+  | |
+  | o  2 D1 draft
+  |/
+  o  1 P1 public
+  |
+  o  0 P0 public
+  
+  $ hg debugrevspec --verify -p analyzed -p optimized 'draft() & 
::(((S1+D1+P5)-D3)+S2)'
+  * analyzed:
+  (and
+(func
+  ('symbol', 'draft')
+  None
+  define)
+(func
+  ('symbol', 'ancestors')
+  (or
+(list
+  (and
+(or
+  (list
+('symbol', 'S1')
+('symbol', 'D1')
+('symbol', 'P5'))
+  define)
+(not
+  ('symbol', 'D3')
+  follow)
+define)
+  ('symbol', 'S2'))
+define)
+  follow)
+define)
+  * optimized:
+  (func
+('symbol', '_phaseandancestors')
+(list
+  ('string', 'draft')
+  (or
+(list
+  (difference
+(func
+  ('symbol', '_list')
+  ('string', 'S1\x00D1\x00P5')
+  define)
+('symbol', 'D3')
+define)
+  ('symbol', 'S2'))
+define))
+define)
+  $ hg debugrevspec --verify -p analyzed -p optimized 'secret() & ::9'
+  * analyzed:
+  (and
+(func
+  ('symbol', 'secret')
+  None
+  define)
+(func
+  ('symbol', 'ancestors')
+  ('symbol', '9')
+  follow)
+define)
+  * optimized:
+  (func
+('symbol', '_phaseandancestors')
+(list
+  ('string', 'secret')
+  ('symbol', '9'))
+define)
+  $ hg debugrevspec --verify -p analyzed -p optimized '(not public()) & 
::(tag())'
+  * analyzed:
+  (and
+(not
+  (func
+('symbol', 'public')
+None
+any)
+  define)
+(func
+  ('symbol', 'ancestors')
+  (func
+('symbol', 'tag')
+None
+define)
+  follow)
+define)
+  * optimized:
+  (func
+('symbol', '_phaseandancestors')
+(list
+  ('string', '_notpublic')
+  (func
+('symbol', 'tag')
+None
+define))
+define)
+  $ hg debugrevspec --verify -p optimized '(not public()) & 
ancestors(S1+D2+P5, 1)'
+  * optimized:
+  (and
+(func
+  ('symbol', '_notpublic')
+  None
+  any)
+(func
+  ('symbol', 'ancestors')
+  (list
+(func
+  ('symbol', '_list')
+  ('string', 'S1\x00D2\x00P5')
+  define)
+('symbol', '1'))
+  follow)
+define)
+  $ hg debugrevspec --verify -p optimized '(not public()) & 
ancestors(S1+D2+P5, depth=1)'
+  * optimized:
+  (and
+(func
+  ('symbol', '_notpublic')
+  None
+  any)
+(func
+  ('symbol', 'ancestors')
+  (list
+(func
+  ('symbol', '_list')
+  ('string', 'S1\x00D2\x00P5')
+  define)
+(keyvalue
+  ('symbol', 'depth')
+  ('symbol', '1')))
+  follow)
+define)
diff --git a/mercurial/revsetlang.py b/mercurial/revsetlang.py
--- a/mercurial/revsetlang.py
+++ b/mercurial/revsetlang.py
@@ -313,6 +313,49 @@
 if _isposargs(ta, 1) and _isposargs(tb, 1):
 return ('list', ta, tb)
 
+def _matchtree(tree, pattern):
+"""like re.match, return matched patterns or None if not matched
+
+A fixed string matches a fixed string. A lambda matches and captures things
+if it returns True. A tuple will trigger a recursive match on its elements.
+Return a list of captured subtrees.
+
+>>> t = lambda x: True
+>>> _matchtree(parse('A'), ('symbol', 'A'))
+[]
+>>> _matchtree(parse('A'), ('symbol', ('A',)))
+>>> _matchtree(parse('A'), ('symbol', 'A', 'B'))
+>>> _matchtree(parse('A'), ('func', 'A'))
+>>> _matchtree(parse('A'), ('symbol'))
+>>> _matchtree(parse('A'), 'A')
+>>> _matchtree(parse('A'), t)
+[('symbol', 'A')]
+>>> _matchtree(parse('A'), (t, lambda x: x == 'A'))
+['symbol', 'A']
+>>> _ma

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

2017-08-17 Thread martinvonz (Martin von Zweigbergk)
martinvonz added a comment.


  I'll review in more detail later, but just a quick comment for now

INLINE COMMENTS

> revset.py:1554
> +def keepfunc(rev):
> +return getphase(repo, rev) in selectedphases
> +

Isn't "getphase(repo,rev) >= keepphase" more natural? You'd then replace 
phasenamemap by something like

  minphase = {
  '_notpublic': draft,
  'draft': draft,
  'secret': secret,
  }

REPOSITORY
  rHG Mercurial

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

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


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

2017-08-17 Thread quark (Jun Wu)
quark updated this revision to Diff 1058.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D441?vs=1057&id=1058

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

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

CHANGE DETAILS

diff --git a/tests/test-revset.t b/tests/test-revset.t
--- a/tests/test-revset.t
+++ b/tests/test-revset.t
@@ -4511,3 +4511,165 @@
 
   $ hg log -r 'successors(B+A)-contentdivergent()-obsolete()' -T '{desc}\n'
   Z
+
+Test `draft() & ::x` optimization
+
+  $ hg init $TESTTMP/repo2
+  $ cd $TESTTMP/repo2
+  $ hg debugdrawdag <<'EOS'
+  >   P5 S1
+  >|  |
+  > S2 | D3
+  >   \|/
+  >   P4
+  >|
+  >   P3 D2
+  >|  |
+  >   P2 D1
+  >|/
+  >   P1
+  >|
+  >   P0
+  > EOS
+  $ hg phase --public -r P4+P5
+  $ hg phase --force --secret -r S1+S2
+  $ hg log -G -T '{rev} {desc} {phase}' -r 'sort(all(), topo, 
topo.firstbranch=P5)'
+  o  8 P5 public
+  |
+  | o  10 S1 secret
+  | |
+  | o  7 D3 draft
+  |/
+  | o  9 S2 secret
+  |/
+  o  6 P4 public
+  |
+  o  5 P3 public
+  |
+  o  3 P2 public
+  |
+  | o  4 D2 draft
+  | |
+  | o  2 D1 draft
+  |/
+  o  1 P1 public
+  |
+  o  0 P0 public
+  
+  $ hg debugrevspec --verify -p analyzed -p optimized 'draft() & 
::((S1+D1+P5)-D3)'
+  * analyzed:
+  (and
+(func
+  ('symbol', 'draft')
+  None
+  define)
+(func
+  ('symbol', 'ancestors')
+  (and
+(or
+  (list
+('symbol', 'S1')
+('symbol', 'D1')
+('symbol', 'P5'))
+  define)
+(not
+  ('symbol', 'D3')
+  follow)
+define)
+  follow)
+define)
+  * optimized:
+  (func
+('symbol', '_phaseandancestors')
+(list
+  ('string', 'draft')
+  (difference
+(func
+  ('symbol', '_list')
+  ('string', 'S1\x00D1\x00P5')
+  define)
+('symbol', 'D3')
+define))
+define)
+  $ hg debugrevspec --verify -p analyzed -p optimized 'secret() & ::(7::)'
+  * analyzed:
+  (and
+(func
+  ('symbol', 'secret')
+  None
+  define)
+(func
+  ('symbol', 'ancestors')
+  (func
+('symbol', 'descendants')
+('symbol', '7')
+define)
+  follow)
+define)
+  * optimized:
+  (func
+('symbol', '_phaseandancestors')
+(list
+  ('string', 'secret')
+  (func
+('symbol', 'descendants')
+('symbol', '7')
+define))
+define)
+  $ hg debugrevspec --verify -p analyzed -p optimized '(not public()) & ::(S1)'
+  * analyzed:
+  (and
+(not
+  (func
+('symbol', 'public')
+None
+any)
+  define)
+(func
+  ('symbol', 'ancestors')
+  ('symbol', 'S1')
+  follow)
+define)
+  * optimized:
+  (func
+('symbol', '_phaseandancestors')
+(list
+  ('string', '_notpublic')
+  ('symbol', 'S1'))
+define)
+  $ hg debugrevspec --verify -p optimized '(not public()) & 
ancestors(S1+D2+P5, 1)'
+  * optimized:
+  (and
+(func
+  ('symbol', '_notpublic')
+  None
+  any)
+(func
+  ('symbol', 'ancestors')
+  (list
+(func
+  ('symbol', '_list')
+  ('string', 'S1\x00D2\x00P5')
+  define)
+('symbol', '1'))
+  follow)
+define)
+  $ hg debugrevspec --verify -p optimized '(not public()) & 
ancestors(S1+D2+P5, depth=1)'
+  * optimized:
+  (and
+(func
+  ('symbol', '_notpublic')
+  None
+  any)
+(func
+  ('symbol', 'ancestors')
+  (list
+(func
+  ('symbol', '_list')
+  ('string', 'S1\x00D2\x00P5')
+  define)
+(keyvalue
+  ('symbol', 'depth')
+  ('symbol', '1')))
+  follow)
+define)
diff --git a/mercurial/revsetlang.py b/mercurial/revsetlang.py
--- a/mercurial/revsetlang.py
+++ b/mercurial/revsetlang.py
@@ -313,6 +313,49 @@
 if _isposargs(ta, 1) and _isposargs(tb, 1):
 return ('list', ta, tb)
 
+def _matchtree(tree, pattern):
+"""like re.match, return matched patterns or None if not matched
+
+A fixed string matches a fixed string. A lambda matches and captures things
+if it returns True. A tuple will trigger a recursive match on its elements.
+Return a list of captured subtrees.
+
+>>> t = lambda x: True
+>>> _matchtree(parse('A'), ('symbol', 'A'))
+[]
+>>> _matchtree(parse('A'), ('symbol', ('A',)))
+>>> _matchtree(parse('A'), ('symbol', 'A', 'B'))
+>>> _matchtree(parse('A'), ('func', 'A'))
+>>> _matchtree(parse('A'), ('symbol'))
+>>> _matchtree(parse('A'), 'A')
+>>> _matchtree(parse('A'), t)
+[('symbol', 'A')]
+>>> _matchtree(parse('A'), (t, lambda x: x == 'A'))
+['symbol', 'A']
+>>> _matchtree(parse('A'), (t, lambda x: x == 'B'))
+>>> _matchtree(parse('A+B'), ('or', ('list', t, ('symbol', t
+[('symbol', 'A'), 'B']
+"""
+matchedlist = []
+if

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

2017-08-17 Thread quark (Jun Wu)
quark updated this revision to Diff 1057.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D441?vs=1056&id=1057

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

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

CHANGE DETAILS

diff --git a/tests/test-revset.t b/tests/test-revset.t
--- a/tests/test-revset.t
+++ b/tests/test-revset.t
@@ -4511,3 +4511,165 @@
 
   $ hg log -r 'successors(B+A)-contentdivergent()-obsolete()' -T '{desc}\n'
   Z
+
+Test `draft() & ::x` optimization
+
+  $ hg init $TESTTMP/repo2
+  $ cd $TESTTMP/repo2
+  $ hg debugdrawdag <<'EOS'
+  >   P5 S1
+  >|  |
+  > S2 | D3
+  >   \|/
+  >   P4
+  >|
+  >   P3 D2
+  >|  |
+  >   P2 D1
+  >|/
+  >   P1
+  >|
+  >   P0
+  > EOS
+  $ hg phase --public -r P4+P5
+  $ hg phase --force --secret -r S1+S2
+  $ hg log -G -T '{rev} {desc} {phase}' -r 'sort(all(), topo, 
topo.firstbranch=P5)'
+  o  8 P5 public
+  |
+  | o  10 S1 secret
+  | |
+  | o  7 D3 draft
+  |/
+  | o  9 S2 secret
+  |/
+  o  6 P4 public
+  |
+  o  5 P3 public
+  |
+  o  3 P2 public
+  |
+  | o  4 D2 draft
+  | |
+  | o  2 D1 draft
+  |/
+  o  1 P1 public
+  |
+  o  0 P0 public
+  
+  $ hg debugrevspec --verify -p analyzed -p optimized 'draft() & 
::((S1+D1+P5)-D3)'
+  * analyzed:
+  (and
+(func
+  ('symbol', 'draft')
+  None
+  define)
+(func
+  ('symbol', 'ancestors')
+  (and
+(or
+  (list
+('symbol', 'S1')
+('symbol', 'D1')
+('symbol', 'P5'))
+  define)
+(not
+  ('symbol', 'D3')
+  follow)
+define)
+  follow)
+define)
+  * optimized:
+  (func
+('symbol', '_phaseandancestors')
+(list
+  ('string', 'draft')
+  (difference
+(func
+  ('symbol', '_list')
+  ('string', 'S1\x00D1\x00P5')
+  define)
+('symbol', 'D3')
+define))
+define)
+  $ hg debugrevspec --verify -p analyzed -p optimized 'secret() & ::(7::)'
+  * analyzed:
+  (and
+(func
+  ('symbol', 'secret')
+  None
+  define)
+(func
+  ('symbol', 'ancestors')
+  (func
+('symbol', 'descendants')
+('symbol', '7')
+define)
+  follow)
+define)
+  * optimized:
+  (func
+('symbol', '_phaseandancestors')
+(list
+  ('string', 'secret')
+  (func
+('symbol', 'descendants')
+('symbol', '7')
+define))
+define)
+  $ hg debugrevspec --verify -p analyzed -p optimized '(not public()) & ::(S1)'
+  * analyzed:
+  (and
+(not
+  (func
+('symbol', 'public')
+None
+any)
+  define)
+(func
+  ('symbol', 'ancestors')
+  ('symbol', 'S1')
+  follow)
+define)
+  * optimized:
+  (func
+('symbol', '_phaseandancestors')
+(list
+  ('string', '_notpublic')
+  ('symbol', 'S1'))
+define)
+  $ hg debugrevspec --verify -p optimized '(not public()) & 
ancestors(S1+D2+P5, 1)'
+  * optimized:
+  (and
+(func
+  ('symbol', '_notpublic')
+  None
+  any)
+(func
+  ('symbol', 'ancestors')
+  (list
+(func
+  ('symbol', '_list')
+  ('string', 'S1\x00D2\x00P5')
+  define)
+('symbol', '1'))
+  follow)
+define)
+  $ hg debugrevspec --verify -p optimized '(not public()) & 
ancestors(S1+D2+P5, depth=1)'
+  * optimized:
+  (and
+(func
+  ('symbol', '_notpublic')
+  None
+  any)
+(func
+  ('symbol', 'ancestors')
+  (list
+(func
+  ('symbol', '_list')
+  ('string', 'S1\x00D2\x00P5')
+  define)
+(keyvalue
+  ('symbol', 'depth')
+  ('symbol', '1')))
+  follow)
+define)
diff --git a/mercurial/revsetlang.py b/mercurial/revsetlang.py
--- a/mercurial/revsetlang.py
+++ b/mercurial/revsetlang.py
@@ -313,6 +313,32 @@
 if _isposargs(ta, 1) and _isposargs(tb, 1):
 return ('list', ta, tb)
 
+def _matchtree(tree, pattern):
+"""like re.match, return matched patterns or None if not matched
+
+A fixed string matches a fixed string. A lambda matches and captures things
+if it returns True. A tuple will trigger a recursive match on its elements.
+"""
+matchedlist = []
+if util.safehasattr(pattern, '__call__'):
+matched = pattern(tree)
+if matched:
+return [tree]
+else:
+return None
+else:
+if isinstance(tree, tuple):
+if not isinstance(pattern, tuple) or len(tree) != len(pattern):
+return None
+for i, t in enumerate(tree):
+matched = _matchtree(t, pattern[i])
+if matched is None:
+return None
+matchedlist.extend(matched)
+elif tree != pattern:
+return None
+return matchedlist
+
 def _fixops(x):
 """Rewrite raw parsed tr

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

2017-08-17 Thread quark (Jun Wu)
quark created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  The `draft() & ::x` type query could be common for selecting one or more
  draft feature branches being worked on.
  
  Before this patch, `::x` may travel though the changelog DAG for a long
  distance until it gets a smaller revision number than `min(draft())`, which
  means the smallest revision in `draft()` basically decides the time needed
  to calculate the revset. It could be slow on long changelog with distant
  drafts.
  
  This patch adds a fast path for this situation, and will stop traveling the
  changelog DAG once `::x` hits a non-draft revision.
  
  The fast path also works for `secret()` and `not public()`.
  
  To measure the performance difference, I used drawdag to create a repo that
  emulates distant drafts:
  
DRAFT4
 |
DRAFT3 # draft
/
PUBLIC # public
|
PUBLIC9998
|
.   DRAFT2
.|
.   DRAFT1 # draft
|   /
PUBLIC0001 # public
  
  And measured the performance using the repo:
  
  1. before $ hg perfrevset 'draft() & ::(DRAFT2+DRAFT4)' ! wall 0.017132 comb 
0.01 user 0.01 sys 0.00 (best of 156) $ hg perfrevset 'draft() & 
::(all())' ! wall 0.024221 comb 0.03 user 0.03 sys 0.00 (best of 
113)
  2. after $ hg perfrevset 'draft() & ::(DRAFT2+DRAFT4)' ! wall 0.000243 comb 
0.00 user 0.00 sys 0.00 (best of 9303) $ hg perfrevset 'draft() & 
::(all())' ! wall 0.004319 comb 0.00 user 0.00 sys 0.00 (best of 
655)

REPOSITORY
  rHG Mercurial

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

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

CHANGE DETAILS

diff --git a/tests/test-revset.t b/tests/test-revset.t
--- a/tests/test-revset.t
+++ b/tests/test-revset.t
@@ -4511,3 +4511,177 @@
 
   $ hg log -r 'successors(B+A)-contentdivergent()-obsolete()' -T '{desc}\n'
   Z
+
+Test `draft() & ::x` optimization
+
+  $ hg init $TESTTMP/repo2
+  $ cd $TESTTMP/repo2
+  $ hg debugdrawdag <<'EOS'
+  >   P5 S1
+  >|  |
+  > S2 | D3
+  >   \|/
+  >   P4
+  >|
+  >   P3 D2
+  >|  |
+  >   P2 D1
+  >|/
+  >   P1
+  >|
+  >   P0
+  > EOS
+  $ hg phase --public -r P4+P5
+  $ hg phase --force --secret -r S1+S2
+  $ hg log -G -T '{rev} {desc} {phase}' -r 'sort(all(), topo, 
topo.firstbranch=P5)'
+  o  8 P5 public
+  |
+  | o  10 S1 secret
+  | |
+  | o  7 D3 draft
+  |/
+  | o  9 S2 secret
+  |/
+  o  6 P4 public
+  |
+  o  5 P3 public
+  |
+  o  3 P2 public
+  |
+  | o  4 D2 draft
+  | |
+  | o  2 D1 draft
+  |/
+  o  1 P1 public
+  |
+  o  0 P0 public
+  
+  $ hg debugrevspec --verify -p analyzed -p optimized 'draft() & 
::((S1+D1+P5)-D3)'
+  * analyzed:
+  (and
+(func
+  ('symbol', 'draft')
+  None
+  define)
+(func
+  ('symbol', 'ancestors')
+  (and
+(or
+  (list
+('symbol', 'S1')
+('symbol', 'D1')
+('symbol', 'P5'))
+  define)
+(not
+  ('symbol', 'D3')
+  follow)
+define)
+  follow)
+define)
+  * optimized:
+  (func
+('symbol', '_phaseandancestors')
+(list
+  ('string', 'draft')
+  (difference
+(func
+  ('symbol', '_list')
+  ('string', 'S1\x00D1\x00P5')
+  define)
+('symbol', 'D3')
+define))
+define)
+  $ hg debugrevspec --verify -p analyzed -p optimized 'secret() & 
::(S2+S1+D2+P5)'
+  * analyzed:
+  (and
+(func
+  ('symbol', 'secret')
+  None
+  define)
+(func
+  ('symbol', 'ancestors')
+  (or
+(list
+  ('symbol', 'S2')
+  ('symbol', 'S1')
+  ('symbol', 'D2')
+  ('symbol', 'P5'))
+define)
+  follow)
+define)
+  * optimized:
+  (func
+('symbol', '_phaseandancestors')
+(list
+  ('string', 'secret')
+  (func
+('symbol', '_list')
+('string', 'S2\x00S1\x00D2\x00P5')
+define))
+define)
+  $ hg debugrevspec --verify -p analyzed -p optimized '(not public()) & 
::(S2+S1+D2+P5)'
+  * analyzed:
+  (and
+(not
+  (func
+('symbol', 'public')
+None
+any)
+  define)
+(func
+  ('symbol', 'ancestors')
+  (or
+(list
+  ('symbol', 'S2')
+  ('symbol', 'S1')
+  ('symbol', 'D2')
+  ('symbol', 'P5'))
+define)
+  follow)
+define)
+  * optimized:
+  (func
+('symbol', '_phaseandancestors')
+(list
+  ('string', '_notpublic')
+  (func
+('symbol', '_list')
+('string', 'S2\x00S1\x00D2\x00P5')
+define))
+define)
+  $ hg debugrevspec --verify -p optimized '(not public()) & 
ancestors(S1+D2+P5, 1)'
+  * optimized:
+  (and
+(func
+  ('symbol', '_notpublic')
+  None
+  any)
+(func
+  ('

D440: exchange: don't attempt phase exchange if phase-heads was in bundle

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

REVISION SUMMARY
  The Mercurial core server doesn't yet include phase-heads parts in the
  bundle, but our Google-internal server wants to do
  that. Unfortunately, the usual exchange still happens even if
  phase-heads part is included (including the short-circuited one for
  old/publishing servers). That means that even if our server (again,
  the Google-internal one, but also future Mercurial core servers)
  includes a phase-heads part to indicate that some heads should be
  drafts, that would still get overwritten by the phase updating that
  happens after. So let's fix that by marking the phase step done if we
  receive at least one phase-heads part in the bundle.

REPOSITORY
  rHG Mercurial

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

AFFECTED FILES
  mercurial/bundle2.py
  mercurial/exchange.py

CHANGE DETAILS

diff --git a/mercurial/exchange.py b/mercurial/exchange.py
--- a/mercurial/exchange.py
+++ b/mercurial/exchange.py
@@ -1389,6 +1389,10 @@
 if pullop.fetch:
 pullop.cgresult = bundle2.combinechangegroupresults(op)
 
+# If the bundle had a phase-heads part, then phase exchange is already done
+if op.records['phase-heads']:
+pullop.stepsdone.add('phases')
+
 # processing phases change
 for namespace, value in op.records['listkeys']:
 if namespace == 'phases':
diff --git a/mercurial/bundle2.py b/mercurial/bundle2.py
--- a/mercurial/bundle2.py
+++ b/mercurial/bundle2.py
@@ -1815,6 +1815,7 @@
 """apply phases from bundle part to repo"""
 headsbyphase = _readphaseheads(inpart)
 phases.updatephases(op.repo.unfiltered(), op.gettransaction(), 
headsbyphase)
+op.records.add('phase-heads', {})
 
 @parthandler('reply:pushkey', ('return', 'in-reply-to'))
 def handlepushkeyreply(op, inpart):



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


Re: Fwd: Dropping Support for Python 2.6

2017-08-17 Thread Mathias De Maré
(Adding Mercurial-devel mailing list, as I'm not sure if anyone is 
actually using mercurial-infrastructure@)



On 08-08-17 09:21, Mathias De Maré wrote:



On 04-05-17 16:36, Anton Shestakov wrote:

On Tue, 2 May 2017 20:30:07 +0200
Pierre-Yves David  wrote:


So, we are already operating a repository at:

https://www.mercurial-scm.org/release/

And we already have all the necessary bits in our current make file to
create and update it such repository. As pointed in the previous
section, these repositories have users, since they complains when it 
broke.


The builder use to run on some of my hardware in the USA, the thing 
when
down for some time when I moved back to France (since the hardward 
spent

months in cardbox). It went back online a bit last year but the build
broken again a handful of month ago.
I did not had time to fix it for good since then. I've been running 
this
in pure good will for a couple of year but I'm not a user of it. I 
would

also be happy to free the hardware for other usage. So I'm not planning
to fix this short terms.

Other member of the community (Anton for one, in CC) have expressed
interested in resurrecting the builder. Maybe it is time to officially
hand the thing to whoever wants to do it.

Well, it would be good to resurrect it indeed, even if because not
building RPMs anymore is clearly a step backwards.

We have a wiki page for people who want to help with running tests on
different platforms: https://www.mercurial-scm.org/wiki/Buildbot, maybe
having some clear instructions on how to set up an RPM builder would
inspire someone.

I wouldn't mind setting it up on my makeshift home server (an old
netbook with Atom CPU), the problem with that is that I don't use
RPM-based distros and don't know much about them, and dogfooding is
kinda important (e.g. people would need to ping me every time something
goes wrong, and probably include a recipe of how to fix it).

Incidentally, can't it be done on the current m-s.o infrastructure and
not by volunteers?
I would be willing to set this up on the existing infrastructure, if I 
can get access to it. The CentOS builds all work now (once my CentOS 5 
patches are in), and we are dogfooding these (not yet on a regular 
basis, but I hope to change that). Normally, any recent Linux with 
Docker should be enough to build these.
I would very much like to see these builds appear in 
https://www.mercurial-scm.org/downloads .


If it's not possible to do this on the existing infrastructure, I can 
try to set up a buildbot worker on a server in our company (but since 
it contacts 'the world', it may take some time to get that accepted).


Greetings,
Mathias

___
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


D426: obsutil: correct deprecation warning message

2017-08-17 Thread ryanmce (Ryan McElroy)
ryanmce abandoned this revision.
ryanmce added a comment.


  I don't pull from committed usually.

REPOSITORY
  rHG Mercurial

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

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


D379: simplemerge: use context paths for default labels instead of file paths

2017-08-17 Thread phillco (Phil Cohen)
phillco added a comment.


  Blocked on https://phab.mercurial-scm.org/D378.

REPOSITORY
  rHG Mercurial

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

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


D379: simplemerge: use context paths for default labels instead of file paths

2017-08-17 Thread phillco (Phil Cohen)
phillco updated this revision to Diff 1039.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D379?vs=860&id=1039

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

AFFECTED FILES
  mercurial/simplemerge.py

CHANGE DETAILS

diff --git a/mercurial/simplemerge.py b/mercurial/simplemerge.py
--- a/mercurial/simplemerge.py
+++ b/mercurial/simplemerge.py
@@ -461,8 +461,8 @@
 mode = opts.get('mode','merge')
 name_a, name_b, name_base = None, None, None
 if mode != 'union':
-name_a, name_b, name_base = _picklabels([localfile,
- otherfile, None],
+name_a, name_b, name_base = _picklabels([localctx.path(),
+ otherctx.path(), None],
 opts.get('label', []))
 
 try:



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


D383: simplemerge: simplify code now that we always write to a context

2017-08-17 Thread phillco (Phil Cohen)
phillco updated this revision to Diff 1043.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D383?vs=864&id=1043

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

AFFECTED FILES
  mercurial/simplemerge.py

CHANGE DETAILS

diff --git a/mercurial/simplemerge.py b/mercurial/simplemerge.py
--- a/mercurial/simplemerge.py
+++ b/mercurial/simplemerge.py
@@ -436,17 +436,6 @@
 # repository usually sees) might be more useful.
 return _verifytext(ctx.decodeddata(), ctx.path(), ui, opts)
 
-class ctxwriter(object):
-def __init__(self, ctx):
-self.ctx = ctx
-self.text = ""
-
-def write(self, text):
-self.text += text
-
-def close(self):
-self.ctx.write(self.text, self.ctx.flags())
-
 mode = opts.get('mode','merge')
 name_a, name_b, name_base = None, None, None
 if mode != 'union':
@@ -461,11 +450,6 @@
 except error.Abort:
 return 1
 
-if opts.get('print'):
-out = ui.fout
-else:
-out = ctxwriter(localctx)
-
 m3 = Merge3Text(basetext, localtext, othertext)
 extrakwargs = {
 "localorother": opts.get("localorother", None),
@@ -479,12 +463,17 @@
 extrakwargs['base_marker'] = '|||'
 extrakwargs['name_base'] = name_base
 extrakwargs['minimize'] = False
+
+mergedtext = ""
 for line in m3.merge_lines(name_a=name_a, name_b=name_b,
**pycompat.strkwargs(extrakwargs)):
-out.write(line)
+if opts.get('print'):
+ui.fout.write(line)
+else:
+mergedtext += line
 
 if not opts.get('print'):
-out.close()
+localctx.write(mergedtext, localctx.flags())
 
 if m3.conflicts and not mode == 'union':
 return 1



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


D381: simplemerge: stop accepting, and passing, file parameters

2017-08-17 Thread phillco (Phil Cohen)
phillco updated this revision to Diff 1041.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D381?vs=862&id=1041

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

AFFECTED FILES
  contrib/simplemerge
  mercurial/filemerge.py
  mercurial/simplemerge.py

CHANGE DETAILS

diff --git a/mercurial/simplemerge.py b/mercurial/simplemerge.py
--- a/mercurial/simplemerge.py
+++ b/mercurial/simplemerge.py
@@ -419,8 +419,8 @@
 
 return [name_a, name_b, name_base]
 
-def simplemerge(ui, localfile, basefile, otherfile,
-localctx=None, basectx=None, otherctx=None, repo=None, **opts):
+def simplemerge(ui, localctx=None, basectx=None, otherctx=None, repo=None,
+**opts):
 """Performs the simplemerge algorithm.
 
 {local|base|other}ctx are optional. If passed, they (local/base/other) will
diff --git a/mercurial/filemerge.py b/mercurial/filemerge.py
--- a/mercurial/filemerge.py
+++ b/mercurial/filemerge.py
@@ -353,7 +353,7 @@
 labels = _defaultconflictlabels
 if len(labels) < 3:
 labels.append('base')
-r = simplemerge.simplemerge(ui, a, b, c, fcd, fca, fco,
+r = simplemerge.simplemerge(ui, fcd, fca, fco,
 quiet=True, label=labels, repo=repo)
 if not r:
 ui.debug(" premerge successful\n")
@@ -384,7 +384,7 @@
 
 ui = repo.ui
 
-r = simplemerge.simplemerge(ui, a, b, c, fcd, fca, fco,
+r = simplemerge.simplemerge(ui, fcd, fca, fco,
 label=labels, mode=mode, repo=repo)
 return True, r, False
 
@@ -437,7 +437,7 @@
 assert localorother is not None
 tool, toolpath, binary, symlink = toolconf
 a, b, c, back = files
-r = simplemerge.simplemerge(repo.ui, a, b, c, fcd, fca, fco,
+r = simplemerge.simplemerge(repo.ui, fcd, fca, fco,
 label=labels, localorother=localorother,
 repo=repo)
 return True, r
diff --git a/contrib/simplemerge b/contrib/simplemerge
--- a/contrib/simplemerge
+++ b/contrib/simplemerge
@@ -77,9 +77,6 @@
 raise ParseError(_('wrong number of arguments'))
 local, base, other = args
 sys.exit(simplemerge.simplemerge(ui.ui.load(),
- local,
- base,
- other,
  filebackedctx(local),
  filebackedctx(base),
  filebackedctx(other),



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


D382: simplemerge: make context parameters non-optional

2017-08-17 Thread phillco (Phil Cohen)
phillco updated this revision to Diff 1042.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D382?vs=863&id=1042

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

AFFECTED FILES
  mercurial/simplemerge.py

CHANGE DETAILS

diff --git a/mercurial/simplemerge.py b/mercurial/simplemerge.py
--- a/mercurial/simplemerge.py
+++ b/mercurial/simplemerge.py
@@ -419,13 +419,10 @@
 
 return [name_a, name_b, name_base]
 
-def simplemerge(ui, localctx=None, basectx=None, otherctx=None, repo=None,
-**opts):
+def simplemerge(ui, localctx, basectx, otherctx, repo=None, **opts):
 """Performs the simplemerge algorithm.
 
-{local|base|other}ctx are optional. If passed, they (local/base/other) will
-be read from and the merge result written to (local). You should pass
-explicit labels in this mode since the default is to use the file paths.
+The merged result is written into `localctx`.
 """
 def readctx(ctx):
 if not ctx:



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


D380: simplemerge: stop reading from, and writing to, files

2017-08-17 Thread phillco (Phil Cohen)
phillco updated this revision to Diff 1040.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D380?vs=861&id=1040

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

AFFECTED FILES
  mercurial/simplemerge.py

CHANGE DETAILS

diff --git a/mercurial/simplemerge.py b/mercurial/simplemerge.py
--- a/mercurial/simplemerge.py
+++ b/mercurial/simplemerge.py
@@ -18,15 +18,12 @@
 
 from __future__ import absolute_import
 
-import os
-
 from .i18n import _
 from . import (
 error,
 mdiff,
 pycompat,
 util,
-vfs as vfsmod,
 )
 
 class CantReprocessAndShowBase(Exception):
@@ -428,13 +425,8 @@
 
 {local|base|other}ctx are optional. If passed, they (local/base/other) will
 be read from and the merge result written to (local). You should pass
-explicit labels in this mode since the default is to use the file paths."""
-def readfile(filename):
-f = open(filename, "rb")
-text = f.read()
-f.close()
-return _verifytext(text, filename, ui, opts)
-
+explicit labels in this mode since the default is to use the file paths.
+"""
 def readctx(ctx):
 if not ctx:
 return None
@@ -466,20 +458,16 @@
 opts.get('label', []))
 
 try:
-localtext = readctx(localctx) if localctx else readfile(localfile)
-basetext = readctx(basectx) if basectx else readfile(basefile)
-othertext = readctx(otherctx) if otherctx else readfile(otherfile)
+localtext = readctx(localctx)
+basetext = readctx(basectx)
+othertext = readctx(otherctx)
 except error.Abort:
 return 1
 
 if opts.get('print'):
 out = ui.fout
-elif localctx:
+else:
 out = ctxwriter(localctx)
-else:
-localfile = os.path.realpath(localfile)
-opener = vfsmod.vfs(os.path.dirname(localfile))
-out = opener(os.path.basename(localfile), "w", atomictemp=True)
 
 m3 = Merge3Text(basetext, localtext, othertext)
 extrakwargs = {



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


D377: simplemerge: add `filtereddata=False` to simplemerge()

2017-08-17 Thread phillco (Phil Cohen)
phillco abandoned this revision.
phillco added a comment.


  Abandoned in favor of https://phab.mercurial-scm.org/D434's approach.

REPOSITORY
  rHG Mercurial

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

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


D434: context: add `decodeddata()` to basefilectx

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

REVISION SUMMARY
  This will be used as an abstraction by simplemerge to get the data it used to
  read off the filesystem.

REPOSITORY
  rHG Mercurial

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

AFFECTED FILES
  mercurial/context.py

CHANGE DETAILS

diff --git a/mercurial/context.py b/mercurial/context.py
--- a/mercurial/context.py
+++ b/mercurial/context.py
@@ -1056,6 +1056,13 @@
 c = visit.pop(max(visit))
 yield c
 
+def decodeddata(self):
+"""Returns `data()` after running repository decoding filters.
+
+This is often equivalent to how the data would be expressed on disk.
+"""
+return self._repo.wwritedata(self.path(), self.data())
+
 def _annotatepair(parents, childfctx, child, skipchild, diffopts):
 r'''
 Given parent and child fctxes and annotate data for parents, for all lines



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


D378: contrib: make simplemerge script pass context-like objects

2017-08-17 Thread phillco (Phil Cohen)
phillco updated this revision to Diff 1038.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D378?vs=859&id=1038

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

AFFECTED FILES
  contrib/simplemerge

CHANGE DETAILS

diff --git a/contrib/simplemerge b/contrib/simplemerge
--- a/contrib/simplemerge
+++ b/contrib/simplemerge
@@ -41,6 +41,26 @@
 for first, second in out_opts:
 sys.stdout.write(' %-*s  %s\n' % (opts_len, first, second))
 
+class filebackedctx(object):
+"""simplemerge requires context-like objects"""
+def __init__(self, path):
+self._path = path
+
+def decodeddata(self):
+with open(self._path, "rb") as f:
+return f.read()
+
+def flags(self):
+return ''
+
+def path(self):
+return self._path
+
+def write(self, data, flags):
+assert not flags
+with open(self._path, "w") as f:
+f.write(data)
+
 try:
 for fp in (sys.stdin, sys.stdout, sys.stderr):
 util.setbinary(fp)
@@ -55,7 +75,16 @@
 sys.exit(0)
 if len(args) != 3:
 raise ParseError(_('wrong number of arguments'))
-sys.exit(simplemerge.simplemerge(ui.ui.load(), *args, **opts))
+local, base, other = args
+sys.exit(simplemerge.simplemerge(ui.ui.load(),
+ local,
+ base,
+ other,
+ filebackedctx(local),
+ filebackedctx(base),
+ filebackedctx(other),
+ filtereddata=True,
+ **opts))
 except ParseError as e:
 sys.stdout.write("%s: %s\n" % (sys.argv[0], e))
 showhelp()



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


D435: simplemerge: use `ctx.decoddeddata()` instead of `repo.wreaddata`

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

REVISION SUMMARY
  This eliminates the need for the `repo` object.

REPOSITORY
  rHG Mercurial

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

AFFECTED FILES
  mercurial/simplemerge.py

CHANGE DETAILS

diff --git a/mercurial/simplemerge.py b/mercurial/simplemerge.py
--- a/mercurial/simplemerge.py
+++ b/mercurial/simplemerge.py
@@ -438,15 +438,14 @@
 def readctx(ctx):
 if not ctx:
 return None
-if not repo:
-raise error.ProgrammingError('simplemerge: repo must be passed if '
- 'using contexts')
-# `wwritedata` is used to get the post-filter data from `ctx` (i.e.,
-# what would have been in the working copy). Since merges were run in
-# the working copy, and thus used post-filter data, we do the same to
-# maintain behavior.
-return repo.wwritedata(ctx.path(),
-   _verifytext(ctx.data(), ctx.path(), ui, opts))
+# Merges were always run in the working copy before, which means
+# they used decoded data, if the user defined any repository
+# filters.
+#
+# Maintain that behavior today for BC, though perhaps in the future
+# it'd be worth considering whether merging encoded data (what the
+# repository usually sees) might be more useful.
+return _verifytext(ctx.decodeddata(), ctx.path(), ui, opts)
 
 class ctxwriter(object):
 def __init__(self, ctx):



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


[Bug 5662] New: file copied onto existing file becomes just modified on commit

2017-08-17 Thread mercurial-bugs
https://bz.mercurial-scm.org/show_bug.cgi?id=5662

Bug ID: 5662
   Summary: file copied onto existing file becomes just modified
on commit
   Product: Mercurial
   Version: 4.3-rc
  Hardware: PC
OS: Linux
Status: UNCONFIRMED
  Severity: feature
  Priority: wish
 Component: Mercurial
  Assignee: bugzi...@mercurial-scm.org
  Reporter: martinv...@google.com
CC: mercurial-devel@mercurial-scm.org

$ echo a > a
$ echo b > b
$ hg ci -Am initial
$ hg cp -f a b
$ hg st -C
M b
  a
$ hg ci -m 'copy a onto b'
$ hg st -C --change .
M b

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


D351: demandimport: disable if chg is being used

2017-08-17 Thread quark (Jun Wu)
quark added a comment.


  How about using `sys.argv[0]` to test if chg is being used?
  
  Instead of running `hg serve --cmdserver chgunix ...`, chg client executes 
`chgserve ...`. And the hg script could notice that by checking `sys.argv[0]` 
and does some special handling (expand it to `hg serve --cmdserver chgunix` for 
now, but we might want to use a different entry point in the future).

REPOSITORY
  rHG Mercurial

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

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


D421: hg: move part of top-level logic to dispatch.run

2017-08-17 Thread quark (Jun Wu)
quark added inline comments.

INLINE COMMENTS

> yuja wrote in hg:30
> This makes the import of `dispatch` non-lazy, right?

I thought demandimport was per module, non-recursive. It's obviously recursive. 
Will change.

REPOSITORY
  rHG Mercurial

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

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


Re: [PATCH 4 of 8] template: add minimal obsfate template function

2017-08-17 Thread Boris Feld
On Wed, 2017-08-09 at 22:42 +0900, Yuya Nishihara wrote:
> On Tue, 08 Aug 2017 18:48:08 +0200, Boris Feld wrote:
> > On Wed, 2017-08-09 at 00:19 +0900, Yuya Nishihara wrote:
> > > On Mon, 07 Aug 2017 16:56:23 +0200, Boris Feld wrote:
> > > > +@templatekeyword("succsandmarkers")
> > > > +def showsuccsandmarkers(repo, ctx, **args):
> > > > +"""Returns a list of dict for each final successor of ctx.
> > > > +
> > > > +The dict contains successors node id in "successors" keys
> > > > and
> > > > the list of
> > > > +obs-markers from ctx to the set of successors in "markers"
> > > > +"""
> > > > +
> > > > +values = obsutil.successorsandmarkers(repo, ctx)
> > > > +
> > > > +if values is None:
> > > > +values = []
> > > > +
> > > > +return showlist('succsandmarkers', values, args)
> > > 
> > > I think returning a list of successor nodes is more natural.
> > > 
> > > Can we theoretically gather the relevant markers from successor
> > > nodes?
> > > If the "markers" field serves just as a cache, it could be stored
> > > in
> > > revcache[] and passed to obsfate() under the hood.
> > 
> > The current algorithm for computing the successors sets of a
> > changeset
> > is this one:
> > 
> > Walk the obs-marker graph starting at a given revision. Follow
> > successors of each revisions walked until revisions has no more
> > successors, they are stable and they are the tip-most successor of
> > the
> > initial revision.
> > 
> > Having the sets of successors doesn't helps because a successor
> > could
> > be successor for more than one obsolete revision (fold for
> > example).
> 
> Thanks for clarifying that. So markers are tied to each successorset?
> 
>   successorssets(rev) -> [(succs0, markers0), (succs1, markers1),
> ...]

Yes markers are tied to each successorset.

> 
> In which case, {successorsset} could populate markers by makemap(),
> 
>   successorssets % "{successorset} {obsmarkers}"
>    
>    no idea how this should be rendered,
> but
>    let's revisit it later.

I tried modifying successorssets to smuggle the markers via makemap but
it has one limitation.

In the case of pruned commits, we would have an empty successorsset but
at least one marker (the marker for pruning). Adding markers via
makemap would make the following condition: if(succsandmarkers, ...)
false for pruned markers.

I propose to keep succsandmarkers but hex all node ids so we would
never see binary information.

> 
> and perhaps obsfate could take the pair explicitly or implicitly.
> 
>   successorsets % "{obsfate(successorset, obsmarkers)}"  # a function
>   successorsets % "{obsfate}"  # a keyword available only in
> successorsets
> 
> obsfate could be even split to verb/users/mindate/maxdate.
> 
>   successorsets % "{obsverb} {obsusers} ..."
>    
>  these keyword functions may be populated by
> makemap(), too.

I tried splitting obsfate into several functions and it looks nicer. I
prefer functions instead of keywords because keywords feels too magic,
do we have already some keywords that are similar (not taking context
as inputs) in core?

I have a rough series splitting obsfate(succsandmarkers) into
obsfateverb(successorset, markers), obsfateusers(successorset,
markers), ... Should I finish it and send a V2?
> 
> > The list of markers between a revisions and its successors could be
> > cached, I'm not sure how to use revcache for that. Did you meant
> > returning a hybrid object like this one, with a non-null revcache
> > parameter: https://www.mercurial-scm.org/repo/hg/file/tip/mercurial
> > /tem
> > platekw.py#l641?
> 
> Something like showlatesttag() or showfile*() was in mind, but
> "revcache"
> seems not the right tool as the markers aren't bound to the current
> rev.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D426: obsutil: correct deprecation warning message

2017-08-17 Thread lothiraldan (Boris Feld)
lothiraldan added a comment.


  Thx @ryanmce, the fix (https://phab.mercurial-scm.org/D413) should already 
been pushed to hg-commited, could you try pulling and see if you have it?

REPOSITORY
  rHG Mercurial

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

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


D426: obsutil: correct deprecation warning message

2017-08-17 Thread ryanmce (Ryan McElroy)
ryanmce created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REPOSITORY
  rHG Mercurial

BRANCH
  default

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

AFFECTED FILES
  mercurial/obsutil.py

CHANGE DETAILS

diff --git a/mercurial/obsutil.py b/mercurial/obsutil.py
--- a/mercurial/obsutil.py
+++ b/mercurial/obsutil.py
@@ -31,7 +31,7 @@
 
 def precnode(self):
 msg = ("'marker.precnode' is deprecated, "
-   "use 'marker.precnode'")
+   "use 'marker.prednode'")
 util.nouideprecwarn(msg, '4.4')
 return self.prednode()
 



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


D360: log: add a "graphwidth" template variable

2017-08-17 Thread hooper (Danny Hooper)
This revision was automatically updated to reflect the committed changes.
Closed by commit rHG6f6c87888b22: log: add a "graphwidth" template variable 
(authored by hooper).

CHANGED PRIOR TO COMMIT
  https://phab.mercurial-scm.org/D360?vs=1009&id=1026#toc

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D360?vs=1009&id=1026

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

AFFECTED FILES
  mercurial/cmdutil.py
  mercurial/graphmod.py
  mercurial/templatekw.py
  tests/test-command-template.t

CHANGE DETAILS

diff --git a/tests/test-command-template.t b/tests/test-command-template.t
--- a/tests/test-command-template.t
+++ b/tests/test-command-template.t
@@ -4319,3 +4319,155 @@
   custom
 
   $ cd ..
+
+Test 'graphwidth' in 'hg log' on various topologies. The key here is that the
+printed graphwidths 3, 5, 7, etc. should all line up in their respective
+columns. We don't care about other aspects of the graph rendering here.
+
+  $ hg init graphwidth
+  $ cd graphwidth
+
+  $ wrappabletext="a a a a a a a a a a a a"
+
+  $ printf "first\n" > file
+  $ hg add file
+  $ hg commit -m "$wrappabletext"
+
+  $ printf "first\nsecond\n" > file
+  $ hg commit -m "$wrappabletext"
+
+  $ hg checkout 0
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ printf "third\nfirst\n" > file
+  $ hg commit -m "$wrappabletext"
+  created new head
+
+  $ hg merge
+  merging file
+  0 files updated, 1 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+
+  $ hg log --graph -T "{graphwidth}"
+  @  3
+  |
+  | @  5
+  |/
+  o  3
+  
+  $ hg commit -m "$wrappabletext"
+
+  $ hg log --graph -T "{graphwidth}"
+  @5
+  |\
+  | o  5
+  | |
+  o |  5
+  |/
+  o  3
+  
+
+  $ hg checkout 0
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ printf "third\nfirst\nsecond\n" > file
+  $ hg commit -m "$wrappabletext"
+  created new head
+
+  $ hg log --graph -T "{graphwidth}"
+  @  3
+  |
+  | o7
+  | |\
+  +---o  7
+  | |
+  | o  5
+  |/
+  o  3
+  
+
+  $ hg log --graph -T "{graphwidth}" -r 3
+  o5
+  |\
+  ~ ~
+
+  $ hg log --graph -T "{graphwidth}" -r 1
+  o  3
+  |
+  ~
+
+  $ hg merge
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ hg commit -m "$wrappabletext"
+
+  $ printf "seventh\n" >> file
+  $ hg commit -m "$wrappabletext"
+
+  $ hg log --graph -T "{graphwidth}"
+  @  3
+  |
+  o5
+  |\
+  | o  5
+  | |
+  o |7
+  |\ \
+  | o |  7
+  | |/
+  o /  5
+  |/
+  o  3
+  
+
+The point of graphwidth is to allow wrapping that accounts for the space taken
+by the graph.
+
+  $ COLUMNS=10 hg log --graph -T "{fill(desc, termwidth - graphwidth)}"
+  @  a a a a
+  |  a a a a
+  |  a a a a
+  oa a a
+  |\   a a a
+  | |  a a a
+  | |  a a a
+  | o  a a a
+  | |  a a a
+  | |  a a a
+  | |  a a a
+  o |a a
+  |\ \   a a
+  | | |  a a
+  | | |  a a
+  | | |  a a
+  | | |  a a
+  | o |  a a
+  | |/   a a
+  | |a a
+  | |a a
+  | |a a
+  | |a a
+  o |  a a a
+  |/   a a a
+  |a a a
+  |a a a
+  o  a a a a
+ a a a a
+ a a a a
+
+Something tricky happens when there are elided nodes; the next drawn row of
+edges can be more than one column wider, but the graph width only increases by
+one column. The remaining columns are added in between the nodes.
+
+  $ hg log --graph -T "{graphwidth}" -r "0|2|4|5"
+  o5
+  |\
+  | \
+  | :\
+  o : :  7
+  :/ /
+  : o  5
+  :/
+  o  3
+  
+
+  $ cd ..
+
diff --git a/mercurial/templatekw.py b/mercurial/templatekw.py
--- a/mercurial/templatekw.py
+++ b/mercurial/templatekw.py
@@ -469,6 +469,13 @@
 else:
 return 'o'
 
+@templatekeyword('graphwidth')
+def showgraphwidth(repo, ctx, templ, **args):
+"""Integer. The width of the graph drawn by 'log --graph' or zero."""
+# The value args['graphwidth'] will be this function, so we use an internal
+# name to pass the value through props into this function.
+return args.get('_graphwidth', 0)
+
 @templatekeyword('index')
 def showindex(**args):
 """Integer. The current iteration of the loop. (0 indexed)"""
diff --git a/mercurial/graphmod.py b/mercurial/graphmod.py
--- a/mercurial/graphmod.py
+++ b/mercurial/graphmod.py
@@ -172,7 +172,7 @@
 yield (cur, type, data, (col, color), edges)
 seen = next
 
-def asciiedges(type, char, lines, state, rev, parents):
+def asciiedges(type, char, state, rev, parents):
 """adds edge info to changelog DAG walk suitable for ascii()"""
 seen = state['seen']
 if rev not in seen:
@@ -192,6 +192,7 @@
 state['edges'][parent] = state['styles'].get(ptype, '|')
 
 ncols = len(seen)
+width = 1 + ncols * 2
 nextseen = seen[:]
 nextseen[nodeidx:nodeidx + 1] = newparents
 edges = [(nodeidx, nextseen.index(p)) for p in knownparents]
@@ -205,9 +206,9 @@
 edges.append((nodeidx, nodeidx))
 ed

D351: demandimport: disable if chg is being used

2017-08-17 Thread yuja (Yuya Nishihara)
yuja added a comment.


  Can you update the comment in chgserver.py in new series? It says
  "CHGINTERNALMARK is temporarily set by chg client to detect if chg will start 
another chg."

REPOSITORY
  rHG Mercurial

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

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


D360: log: add a "graphwidth" template variable

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


  Slightly adjusted the commit message for new version, and queued, thanks.

INLINE COMMENTS

> hooper wrote in cmdutil.py:2557
> There can be many of them.  E.g. in the hg repo it looks like a couple 
> hundred with "hg log --graph -r 'tag()'". It just seems easy enough to hedge 
> against it being expensive, though you might argue premature optimization.

Okay, I guess using a list would be slightly faster in common scenario, but I
have no strong opinion about this.

> graphmod.py:212
>  char = '\\'
>  lines = []
>  nodeidx += 1

Removed this `lines` in flight.

> graphmod.py:227
>  state['edges'].pop(rev, None)
> -yield (type, char, lines, (nodeidx, edges, ncols, nmorecols))
> +yield (type, char, width, (nodeidx, edges, ncols, nmorecols))
>  

Perhaps the `width` can be computed from the `coldata` afterwards, but
that wouldn't make much difference.

`width = indentation_level * 2 + 1`

  # graphmod.ascii()
  indentation_level = max(ncols, ncols + coldiff)
  for (line, logstr) in zip(lines, text):
  ln = "%-*s %s" % (2 * indentation_level, "".join(line), logstr)

REPOSITORY
  rHG Mercurial

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

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


D352: chgserver: special handle __version__ in mtimehash (issue5653)

2017-08-17 Thread yuja (Yuya Nishihara)
yuja added a comment.


  I'll drop this per your comment on the issue5653. Thanks for investigating it 
further.
  
  https://bz.mercurial-scm.org/show_bug.cgi?id=5653#c4

REPOSITORY
  rHG Mercurial

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

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


D421: hg: move part of top-level logic to dispatch.run

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

INLINE COMMENTS

> hg:30
>  try:
> -if sys.version_info[0] < 3 or sys.version_info >= (3, 6):
> -import hgdemandimport; hgdemandimport.enable()
> +import mercurial.dispatch
>  except ImportError:

This makes the import of `dispatch` non-lazy, right?

REPOSITORY
  rHG Mercurial

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

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


Re: [PATCH 1 of 2 STABLE V2] tests: test behavior of IOError during transactions (issue5658)

2017-08-17 Thread Yuya Nishihara
On Tue, 15 Aug 2017 13:55:01 -0700, Gregory Szorc wrote:
> # HG changeset patch
> # User Gregory Szorc 
> # Date 1502741560 25200
> #  Mon Aug 14 13:12:40 2017 -0700
> # Branch stable
> # Node ID 0d5b565629f0491a7673fcfdd9c02cbc1a4b
> # Parent  7686cbb0ba4138c56d038d8d82ccc052bf9b60d7
> tests: test behavior of IOError during transactions (issue5658)

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