D447: templatekw: choose {latesttag} by len(changes), not date (issue5659)

2017-08-21 Thread martinvonz (Martin von Zweigbergk)
This revision was automatically updated to reflect the committed changes.
Closed by commit rHGfb672eac2702: templatekw: choose {latesttag} by 
len(changes), not date (issue5659) (authored by martinvonz).

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D447?vs=1089=1152

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

AFFECTED FILES
  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
@@ -2885,7 +2885,7 @@
   o  0: null+1
   
 
-One common tag: longest path wins:
+One common tag: longest path wins for {latesttagdistance}:
 
   $ hg tag -r 1 -m t1 -d '6 0' t1
   $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
@@ -2904,7 +2904,7 @@
   o  0: null+1
   
 
-One ancestor tag: more recent wins:
+One ancestor tag: closest wins:
 
   $ hg tag -r 2 -m t2 -d '7 0' t2
   $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
@@ -2925,7 +2925,7 @@
   o  0: null+1
   
 
-Two branch tags: more recent wins:
+Two branch tags: more recent wins if same number of changes:
 
   $ hg tag -r 3 -m t3 -d '8 0' t3
   $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
@@ -2948,12 +2948,39 @@
   o  0: null+1
   
 
+Two branch tags: fewest changes wins:
+
+  $ hg tag -r 4 -m t4 -d '4 0' t4 # older than t2, but should not matter
+  $ hg log -G --template "{rev}: {latesttag % '{tag}+{distance},{changes} '}\n"
+  @  9: t4+5,6
+  |
+  o  8: t4+4,5
+  |
+  o  7: t4+3,4
+  |
+  o  6: t4+2,3
+  |
+  o5: t4+1,2
+  |\
+  | o  4: t4+0,0
+  | |
+  | o  3: t3+0,0
+  | |
+  o |  2: t2+0,0
+  |/
+  o  1: t1+0,0
+  |
+  o  0: null+1,1
+  
+
 Merged tag overrides:
 
   $ hg tag -r 5 -m t5 -d '9 0' t5
   $ hg tag -r 3 -m at3 -d '10 0' at3
   $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
-  @  10: t5+5
+  @  11: t5+6
+  |
+  o  10: t5+5
   |
   o  9: t5+4
   |
@@ -2965,7 +2992,7 @@
   |
   o5: t5+0
   |\
-  | o  4: at3:t3+1
+  | o  4: t4+0
   | |
   | o  3: at3:t3+0
   | |
@@ -2977,7 +3004,9 @@
   
 
   $ hg log -G --template "{rev}: {latesttag % '{tag}+{distance},{changes} '}\n"
-  @  10: t5+5,5
+  @  11: t5+6,6
+  |
+  o  10: t5+5,5
   |
   o  9: t5+4,4
   |
@@ -2989,7 +3018,7 @@
   |
   o5: t5+0,0
   |\
-  | o  4: at3+1,1 t3+1,1
+  | o  4: t4+0,0
   | |
   | o  3: at3+0,0 t3+0,0
   | |
@@ -3001,7 +3030,9 @@
   
 
   $ hg log -G --template "{rev}: {latesttag('re:^t[13]$') % '{tag}, C: 
{changes}, D: {distance}'}\n"
-  @  10: t3, C: 8, D: 7
+  @  11: t3, C: 9, D: 8
+  |
+  o  10: t3, C: 8, D: 7
   |
   o  9: t3, C: 7, D: 6
   |
@@ -3044,7 +3075,7 @@
   > EOF
 
   $ hg -R latesttag tip
-  test 10:9b4a630e5f5f
+  test 11:97e5943b523a
 
 Test recursive showlist template (issue1989):
 
@@ -3057,7 +3088,7 @@
 
   $ hg -R latesttag log -r tip --style=style1989
   M|test
-  10,test
+  11,test
   branch: test
 
 Test new-style inline templating:
@@ -3090,6 +3121,7 @@
   $ hg log -R latesttag --template '{desc}\n'
   at3
   t5
+  t4
   t3
   t2
   t1
@@ -3103,6 +3135,7 @@
   $ hg log -R latesttag --template '{strip(desc, "te")}\n'
   at3
   5
+  4
   3
   2
   1
@@ -3118,6 +3151,7 @@
   $ hg log -R latesttag --template 'date: {date(date, "%y %m %d %S %z")}\n'
   date: 70 01 01 10 +
   date: 70 01 01 09 +
+  date: 70 01 01 04 +
   date: 70 01 01 08 +
   date: 70 01 01 07 +
   date: 70 01 01 06 +
diff --git a/mercurial/templatekw.py b/mercurial/templatekw.py
--- a/mercurial/templatekw.py
+++ b/mercurial/templatekw.py
@@ -208,10 +208,22 @@
 latesttags[rev] = ctx.date()[0], 0, [t for t in sorted(tags)]
 continue
 try:
-# The tuples are laid out so the right one can be found by
-# comparison.
-pdate, pdist, ptag = max(
-latesttags[p.rev()] for p in ctx.parents())
+ptags = [latesttags[p.rev()] for p in ctx.parents()]
+if len(ptags) > 1:
+if ptags[0][2] == ptags[1][2]:
+# The tuples are laid out so the right one can be found by
+# comparison in this case.
+pdate, pdist, ptag = max(ptags)
+else:
+def key(x):
+changessincetag = len(repo.revs('only(%d, %s)',
+ctx.rev(), x[2][0]))
+# Smallest number of changes since tag wins. Date is
+# used as tiebreaker.
+return [-changessincetag, x[0]]
+pdate, pdist, ptag = max(ptags, key=key)
+else:
+pdate, pdist, ptag = ptags[0]
 except KeyError:
 # Cache miss - recurse
 todo.append(rev)



To: martinvonz, #hg-reviewers, yuja
Cc: yuja, mercurial-devel

D446: tests: use graph log in {latesttag} tests

2017-08-21 Thread martinvonz (Martin von Zweigbergk)
This revision was automatically updated to reflect the committed changes.
Closed by commit rHG0e15d5ae52cf: tests: use graph log in {latesttag} tests 
(authored by martinvonz).

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D446?vs=1079=1151

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

AFFECTED FILES
  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
@@ -2871,95 +2871,158 @@
 
 No tag set:
 
-  $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
-  5: null+5
-  4: null+4
-  3: null+3
-  2: null+3
-  1: null+2
-  0: null+1
+  $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
+  @5: null+5
+  |\
+  | o  4: null+4
+  | |
+  | o  3: null+3
+  | |
+  o |  2: null+3
+  |/
+  o  1: null+2
+  |
+  o  0: null+1
+  
 
 One common tag: longest path wins:
 
   $ hg tag -r 1 -m t1 -d '6 0' t1
-  $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
-  6: t1+4
-  5: t1+3
-  4: t1+2
-  3: t1+1
-  2: t1+1
-  1: t1+0
-  0: null+1
+  $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
+  @  6: t1+4
+  |
+  o5: t1+3
+  |\
+  | o  4: t1+2
+  | |
+  | o  3: t1+1
+  | |
+  o |  2: t1+1
+  |/
+  o  1: t1+0
+  |
+  o  0: null+1
+  
 
 One ancestor tag: more recent wins:
 
   $ hg tag -r 2 -m t2 -d '7 0' t2
-  $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
-  7: t2+3
-  6: t2+2
-  5: t2+1
-  4: t1+2
-  3: t1+1
-  2: t2+0
-  1: t1+0
-  0: null+1
+  $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
+  @  7: t2+3
+  |
+  o  6: t2+2
+  |
+  o5: t2+1
+  |\
+  | o  4: t1+2
+  | |
+  | o  3: t1+1
+  | |
+  o |  2: t2+0
+  |/
+  o  1: t1+0
+  |
+  o  0: null+1
+  
 
 Two branch tags: more recent wins:
 
   $ hg tag -r 3 -m t3 -d '8 0' t3
-  $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
-  8: t3+5
-  7: t3+4
-  6: t3+3
-  5: t3+2
-  4: t3+1
-  3: t3+0
-  2: t2+0
-  1: t1+0
-  0: null+1
+  $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
+  @  8: t3+5
+  |
+  o  7: t3+4
+  |
+  o  6: t3+3
+  |
+  o5: t3+2
+  |\
+  | o  4: t3+1
+  | |
+  | o  3: t3+0
+  | |
+  o |  2: t2+0
+  |/
+  o  1: t1+0
+  |
+  o  0: null+1
+  
 
 Merged tag overrides:
 
   $ hg tag -r 5 -m t5 -d '9 0' t5
   $ hg tag -r 3 -m at3 -d '10 0' at3
-  $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
-  10: t5+5
-  9: t5+4
-  8: t5+3
-  7: t5+2
-  6: t5+1
-  5: t5+0
-  4: at3:t3+1
-  3: at3:t3+0
-  2: t2+0
-  1: t1+0
-  0: null+1
-
-  $ hg log --template "{rev}: {latesttag % '{tag}+{distance},{changes} '}\n"
-  10: t5+5,5 
-  9: t5+4,4 
-  8: t5+3,3 
-  7: t5+2,2 
-  6: t5+1,1 
-  5: t5+0,0 
-  4: at3+1,1 t3+1,1 
-  3: at3+0,0 t3+0,0 
-  2: t2+0,0 
-  1: t1+0,0 
-  0: null+1,1 
-
-  $ hg log --template "{rev}: {latesttag('re:^t[13]$') % '{tag}, C: {changes}, 
D: {distance}'}\n"
-  10: t3, C: 8, D: 7
-  9: t3, C: 7, D: 6
-  8: t3, C: 6, D: 5
-  7: t3, C: 5, D: 4
-  6: t3, C: 4, D: 3
-  5: t3, C: 3, D: 2
-  4: t3, C: 1, D: 1
-  3: t3, C: 0, D: 0
-  2: t1, C: 1, D: 1
-  1: t1, C: 0, D: 0
-  0: null, C: 1, D: 1
+  $ hg log -G --template '{rev}: {latesttag}+{latesttagdistance}\n'
+  @  10: t5+5
+  |
+  o  9: t5+4
+  |
+  o  8: t5+3
+  |
+  o  7: t5+2
+  |
+  o  6: t5+1
+  |
+  o5: t5+0
+  |\
+  | o  4: at3:t3+1
+  | |
+  | o  3: at3:t3+0
+  | |
+  o |  2: t2+0
+  |/
+  o  1: t1+0
+  |
+  o  0: null+1
+  
+
+  $ hg log -G --template "{rev}: {latesttag % '{tag}+{distance},{changes} '}\n"
+  @  10: t5+5,5
+  |
+  o  9: t5+4,4
+  |
+  o  8: t5+3,3
+  |
+  o  7: t5+2,2
+  |
+  o  6: t5+1,1
+  |
+  o5: t5+0,0
+  |\
+  | o  4: at3+1,1 t3+1,1
+  | |
+  | o  3: at3+0,0 t3+0,0
+  | |
+  o |  2: t2+0,0
+  |/
+  o  1: t1+0,0
+  |
+  o  0: null+1,1
+  
+
+  $ hg log -G --template "{rev}: {latesttag('re:^t[13]$') % '{tag}, C: 
{changes}, D: {distance}'}\n"
+  @  10: t3, C: 8, D: 7
+  |
+  o  9: t3, C: 7, D: 6
+  |
+  o  8: t3, C: 6, D: 5
+  |
+  o  7: t3, C: 5, D: 4
+  |
+  o  6: t3, C: 4, D: 3
+  |
+  o5: t3, C: 3, D: 2
+  |\
+  | o  4: t3, C: 1, D: 1
+  | |
+  | o  3: t3, C: 0, D: 0
+  | |
+  o |  2: t1, C: 1, D: 1
+  |/
+  o  1: t1, C: 0, D: 0
+  |
+  o  0: null, C: 1, D: 1
+  
 
   $ cd ..
 



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


D471: run-tests: also highlight .py test files in summary messages

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

REVISION SUMMARY
  With the .t files highlighted, it's very easy to not even notice
  failed .py tests.

REPOSITORY
  rHG Mercurial

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

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
@@ -127,11 +127,11 @@
 (r'^ERROR: ', token.Generic.Failed, 'failed'),
 ],
 'skipped': [
-(r'[\w-]+\.t', token.Generic.SName),
+(r'[\w-]+\.(t|py)', token.Generic.SName),
 (r':.*', token.Generic.Skipped),
 ],
 'failed': [
-(r'[\w-]+\.t', token.Generic.FName),
+(r'[\w-]+\.(t|py)', token.Generic.FName),
 (r'(:| ).*', token.Generic.Failed),
 ]
 }



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


D469: rebase: initial support for multiple destinations

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

REVISION SUMMARY
  This patch defines `SRC` (a single source revision) and `ALLSRC` (all source
  revisions) to be valid names in  `--dest` revset if `--src` or `--rev` is
  used. So destination could be defined differently according to source
  revisions. The names are capitalized to make it clear they are "dynamically
  defined", distinguishable from normal revsets (Thanks Augie for the
  suggestion).
  
  This is useful, for example, `-r 'orphan()' -d 'calc-dest(SRC)'` to solve
  instability, which is a highly wanted feature.
  
  The feature is not completed, namely if `-d` overlaps with `-r`, things
  could go wrong. A later patch will handle that case.

REPOSITORY
  rHG Mercurial

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

AFFECTED FILES
  hgext/rebase.py
  tests/test-rebase-dest.t

CHANGE DETAILS

diff --git a/tests/test-rebase-dest.t b/tests/test-rebase-dest.t
--- a/tests/test-rebase-dest.t
+++ b/tests/test-rebase-dest.t
@@ -76,3 +76,236 @@
   (use hg pull followed by hg rebase -d DEST)
   [255]
 
+Setup rebase with multiple destinations
+
+  $ cd $TESTTMP
+
+  $ cat >> $TESTTMP/maprevset.py < from __future__ import absolute_import
+  > from mercurial import registrar, revset, revsetlang, smartset
+  > revsetpredicate = registrar.revsetpredicate()
+  > cache = {}
+  > @revsetpredicate('map')
+  > def map(repo, subset, x):
+  > """(set, mapping)"""
+  > setarg, maparg = revsetlang.getargs(x, 2, 2, '')
+  > rset = revset.getset(repo, smartset.fullreposet(repo), setarg)
+  > mapstr = revsetlang.getstring(maparg, '')
+  > map = dict(a.split(':') for a in mapstr.split(','))
+  > rev = rset.first()
+  > desc = repo[rev].description()
+  > newdesc = map.get(desc)
+  > if newdesc == 'null':
+  > revs = [-1]
+  > else:
+  > query = revsetlang.formatspec('desc(%s)', newdesc)
+  > revs = repo.revs(query)
+  > return smartset.baseset(revs)
+  > EOF
+
+  $ cat >> $HGRCPATH < [ui]
+  > allowemptycommit=1
+  > [extensions]
+  > drawdag=$TESTDIR/drawdag.py
+  > [phases]
+  > publish=False
+  > [alias]
+  > tglog = log -G --template "{rev}: {desc} {instabilities}" -r 'sort(all(), 
topo)'
+  > [extensions]
+  > maprevset=$TESTTMP/maprevset.py
+  > [experimental]
+  > stabilization=all
+  > EOF
+
+  $ rebasewithdag() {
+  >   N=`$PYTHON -c "print($N+1)"`
+  >   hg init repo$N && cd repo$N
+  >   hg debugdrawdag
+  >   hg rebase "$@" > _rebasetmp
+  >   r=$?
+  >   grep -v 'saved backup bundle' _rebasetmp
+  >   [ $r -eq 0 ] && rm -f .hg/localtags && hg tglog
+  >   cd ..
+  >   return $r
+  > }
+
+Destination resolves to an empty set:
+
+  $ rebasewithdag -s B -d 'SRC - SRC' <<'EOS'
+  > C
+  > |
+  > B
+  > |
+  > A
+  > EOS
+  nothing to rebase - empty destination
+  [1]
+
+Multiple destinations and --collapse are not compatible:
+
+  $ rebasewithdag -s C+E -d 'SRC^^' --collapse <<'EOS'
+  > C F
+  > | |
+  > B E
+  > | |
+  > A D
+  > EOS
+  abort: --collapse does not work with multiple destinations
+  [255]
+
+Multiple destinations cannot be used with --base:
+
+  $ rebasewithdag -b B+E -d 'SRC^^' --collapse <<'EOS'
+  > B E
+  > | |
+  > A D
+  > EOS
+  abort: unknown revision 'SRC'!
+  [255]
+
+Rebase to null should work:
+
+  $ rebasewithdag -r A+C+D -d 'null' <<'EOS'
+  > C D
+  > | |
+  > A B
+  > EOS
+  already rebased 0:426bada5c675 "A" (A)
+  already rebased 2:dc0947a82db8 "C" (C)
+  rebasing 3:004dc1679908 "D" (D tip)
+  o  4: D
+  
+  o  2: C
+  |
+  | o  1: B
+  |
+  o  0: A
+  
+Destination resolves to multiple changesets:
+
+  $ rebasewithdag -s B -d 'ALLSRC' <<'EOS'
+  > C
+  > |
+  > B
+  > |
+  > Z
+  > EOS
+  abort: rebase destination for f0a671a46792 is not unique
+  [255]
+
+Destination is an ancestor of source:
+
+  $ rebasewithdag -s B -d 'SRC' <<'EOS'
+  > C
+  > |
+  > B
+  > |
+  > Z
+  > EOS
+  abort: source is ancestor of destination
+  [255]
+
+Switch roots:
+
+  $ rebasewithdag -s 'all() - roots(all())' -d 'roots(all()) - ::SRC' <<'EOS'
+  > C  F
+  > |  |
+  > B  E
+  > |  |
+  > A  D
+  > EOS
+  rebasing 2:112478962961 "B" (B)
+  rebasing 4:26805aba1e60 "C" (C)
+  rebasing 3:cd488e83d208 "E" (E)
+  rebasing 5:0069ba24938a "F" (F tip)
+  o  9: F
+  |
+  o  8: E
+  |
+  | o  7: C
+  | |
+  | o  6: B
+  | |
+  | o  1: D
+  |
+  o  0: A
+  
+Different destinations for merge changesets with a same root:
+
+  $ rebasewithdag -s B -d '((parents(SRC)-B-A)::) - (::ALLSRC)' <<'EOS'
+  > C G
+  > |\|
+  > | F
+  > |
+  > B E
+  > |\|
+  > A D
+  > EOS
+  rebasing 3:a4256619d830 "B" (B)
+  rebasing 6:8e139e245220 "C" (C tip)
+  o8: C
+  |\
+  | o7: B
+  | |\
+  o | |  5: G
+  | | |
+  | | o  4: E
+  | | |
+  o | |  2: F
+   / /
+  | o  1: D
+  |
+  o  0: A
+  
+Move to a previous parent:
+
+  $ rebasewithdag -s E+F+G -d 'SRC^^' <<'EOS'
+  > H
+  > |
+  >   D G
+  >   |/
+  >   C F
+  >   

D470: rebase: sort destmap topologically

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

REVISION SUMMARY
  Previously rebase source and destination could not overlap. But with the
  multi-destination support, source and destination could reasonably partially
  overlap. That requires another topological sort on `{sourcerev: destrev}`
  graph (destmap). This patch implements that.
  
  If a revision's destination is itself, the error message gets changed from
  "source is ancestor of destination" to "source and destination form a
  cycle". Not marking as BC since automation should depend on exit code, not
  error message.
  
  The multi-destination feature seems quite usable now so its documentation
  was formally added.
  
  .. feature:: Rebase now supports defining destination per source revision
  
Previously, rebase only supports one unique destination. Now ``SRC`` and
``ALLSRC`` can be used in rebase destination revset to precisely define
destination for every individual source revision.

For example, the following command could rebase all orphaned changesets
to reasonable new places so they are no longer orphaned::

  hg rebase
-r 'orphan()-obsolete()'
-d 'max((successors(max(roots(ALLSRC) & ::SRC)^)-obsolete())::)'

REPOSITORY
  rHG Mercurial

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

AFFECTED FILES
  hgext/rebase.py
  tests/test-rebase-dest.t
  tests/test-rebase-named-branches.t
  tests/test-rebase-scenario-global.t

CHANGE DETAILS

diff --git a/tests/test-rebase-scenario-global.t 
b/tests/test-rebase-scenario-global.t
--- a/tests/test-rebase-scenario-global.t
+++ b/tests/test-rebase-scenario-global.t
@@ -264,7 +264,7 @@
 F onto G - rebase onto a descendant:
 
   $ hg rebase -s 5 -d 6
-  abort: source is ancestor of destination
+  abort: source and destination form a cycle
   [255]
 
 G onto B - merge revision with both parents not in ancestors of target:
diff --git a/tests/test-rebase-named-branches.t 
b/tests/test-rebase-named-branches.t
--- a/tests/test-rebase-named-branches.t
+++ b/tests/test-rebase-named-branches.t
@@ -245,7 +245,7 @@
   @  0: 'A'
   
   $ hg rebase -s 5 -d 6
-  abort: source is ancestor of destination
+  abort: source and destination form a cycle
   [255]
 
   $ hg rebase -s 6 -d 5
diff --git a/tests/test-rebase-dest.t b/tests/test-rebase-dest.t
--- a/tests/test-rebase-dest.t
+++ b/tests/test-rebase-dest.t
@@ -203,7 +203,7 @@
   > |
   > Z
   > EOS
-  abort: source is ancestor of destination
+  abort: source and destination form a cycle
   [255]
 
 Switch roots:
@@ -290,22 +290,163 @@
   |/
   o  0: A
   
-Source overlaps with destination (not handled well currently):
+Source overlaps with destination:
 
   $ rebasewithdag -s 'B+C+D' -d 'map(SRC, "B:C,C:D")' <<'EOS'
   > B C D
   >  \|/
   >   A
   > EOS
+  rebasing 2:dc0947a82db8 "C" (C)
   rebasing 1:112478962961 "B" (B)
-  rebasing 2:dc0947a82db8 "C" (C)
-  o  5: C
+  o  5: B
+  |
+  o  4: C
+  |
+  o  3: D
+  |
+  o  0: A
+  
+Detect cycles early:
+
+  $ rebasewithdag -r 'all()-Z' -d 'map(SRC, "A:B,B:C,C:D,D:B")' <<'EOS'
+  > A B C
+  >  \|/
+  >   | D
+  >   |/
+  >   Z
+  > EOS
+  abort: source and destination form a cycle
+  [255]
+
+Detect source is ancestor of dest in runtime:
+
+  $ rebasewithdag -r 'C+B' -d 'map(SRC, "C:B,B:D")' -q <<'EOS'
+  >   D
+  >   |
+  > B C
+  >  \|
+  >   A
+  > EOS
+  abort: source is ancestor of destination
+  [255]
+
+"Already rebased" fast path still works:
+
+  $ rebasewithdag -r 'all()' -d 'SRC^' <<'EOS'
+  >   E F
+  >  /| |
+  > B C D
+  >  \|/
+  >   A
+  > EOS
+  already rebased 1:112478962961 "B" (B)
+  already rebased 2:dc0947a82db8 "C" (C)
+  already rebased 3:b18e25de2cf5 "D" (D)
+  already rebased 4:312782b8f06e "E" (E)
+  already rebased 5:ad6717a6a58e "F" (F tip)
+  o  5: F
   |
   o  3: D
   |
-  | o  4: B orphan
+  | o4: E
+  | |\
+  +---o  2: C
   | |
-  | x  2: C
+  | o  1: B
   |/
   o  0: A
   
+Massively rewrite the DAG:
+
+  $ rebasewithdag -r 'all()' -d 'map(SRC, 
"A:I,I:null,H:A,B:J,J:C,C:H,D:E,F:G,G:K,K:D,E:B")' <<'EOS'
+  > D G K
+  > | | |
+  > C F J
+  > | | |
+  > B E I
+  >  \| |
+  >   A H
+  > EOS
+  rebasing 4:701514e1408d "I" (I)
+  rebasing 0:426bada5c675 "A" (A)
+  rebasing 1:e7050b6e5048 "H" (H)
+  rebasing 5:26805aba1e60 "C" (C)
+  rebasing 7:cf89f86b485b "J" (J)
+  rebasing 2:112478962961 "B" (B)
+  rebasing 3:7fb047a69f22 "E" (E)
+  rebasing 8:f585351a92f8 "D" (D)
+  rebasing 10:ae41898d7875 "K" (K tip)
+  rebasing 9:711f53bbef0b "G" (G)
+  rebasing 6:64a8289d2492 "F" (F)
+  o  21: F
+  |
+  o  20: G
+  |
+  o  19: K
+  |
+  o  18: D
+  |
+  o  17: E
+  |
+  o  16: B
+  |
+  o  15: J
+  |
+  o  14: C
+  |
+  o  13: H
+  |
+  o  12: A
+  |
+  o  11: I
+  
+Resolve instability:
+
+  $ rebasewithdag <<'EOF' -r 'orphan()-obsolete()' -d 
'max((successors(max(roots(ALLSRC) & ::SRC)^)-obsolete())::)'
+  >  F2
+  >  |
+  >J E E2
+  >| |/
+  > I2 I | 

D347: rebase: rewrite _computeobsoletenotrebased

2017-08-21 Thread quark (Jun Wu)
quark updated this revision to Diff 1146.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D347?vs=899=1146

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

AFFECTED FILES
  hgext/rebase.py

CHANGE DETAILS

diff --git a/hgext/rebase.py b/hgext/rebase.py
--- a/hgext/rebase.py
+++ b/hgext/rebase.py
@@ -1484,31 +1484,23 @@
 obsolete => None entries in the mapping indicate nodes with no successor"""
 obsoletenotrebased = {}
 
-# Build a mapping successor => obsolete nodes for the obsolete
-# nodes to be rebased
-allsuccessors = {}
-cl = repo.changelog
-for r in rebaseobsrevs:
-node = cl.node(r)
-for s in obsutil.allsuccessors(repo.obsstore, [node]):
-try:
-allsuccessors[cl.rev(s)] = cl.rev(node)
-except LookupError:
-pass
-
-if allsuccessors:
-# Look for successors of obsolete nodes to be rebased among
-# the ancestors of dest
-ancs = cl.ancestors([dest],
-stoprev=min(allsuccessors),
-inclusive=True)
-for s in allsuccessors:
-if s in ancs:
-obsoletenotrebased[allsuccessors[s]] = s
-elif (s == allsuccessors[s] and
-  allsuccessors.values().count(s) == 1):
-# plain prune
-obsoletenotrebased[s] = None
+cl = repo.unfiltered().changelog
+nodemap = cl.nodemap
+destnode = cl.node(dest)
+for srcrev in rebaseobsrevs:
+srcnode = cl.node(srcrev)
+# XXX: more advanced APIs are required to handle split correctly
+successors = list(obsutil.allsuccessors(repo.obsstore, [srcnode]))
+if len(successors) == 1:
+# prune
+obsoletenotrebased[srcrev] = None
+else:
+for succnode in successors:
+if succnode == srcnode or succnode not in nodemap:
+continue
+if cl.isancestor(succnode, destnode):
+obsoletenotrebased[srcrev] = nodemap[succnode]
+break
 
 return obsoletenotrebased
 



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


D348: rebase: change internal format to support destination map

2017-08-21 Thread quark (Jun Wu)
quark updated this revision to Diff 1147.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D348?vs=900=1147

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

AFFECTED FILES
  hgext/rebase.py
  tests/test-rebase-legacy.t

CHANGE DETAILS

diff --git a/tests/test-rebase-legacy.t b/tests/test-rebase-legacy.t
new file mode 100644
--- /dev/null
+++ b/tests/test-rebase-legacy.t
@@ -0,0 +1,76 @@
+Test rebase --continue with rebasestate written by legacy client
+
+  $ cat >> $HGRCPATH < [extensions]
+  > rebase=
+  > drawdag=$TESTDIR/drawdag.py
+  > EOF
+
+  $ hg init
+  $ hg debugdrawdag <<'EOF'
+  >D H
+  >| |
+  >C G
+  >| |
+  >B F
+  >| |
+  >  Z A E
+  >   \|/
+  >R
+  > EOF
+
+rebasestate generated by a legacy client running "hg rebase -r B+D+E+G+H -d Z"
+
+  $ touch .hg/last-message.txt
+  $ cat > .hg/rebasestate < 
+  > f424eb6a8c01c4a0c0fba9f863f79b3eb5b4b69f
+  > 
+  > 0
+  > 0
+  > 0
+  > 
+  > 21a6c45028857f500f56ae84fbf40689c429305b:-2
+  > 
de008c61a447fcfd93f808ef527d933a84048ce7:
+  > 
c1e6b162678d07d0b204e5c8267d51b4e03b633c:
+  > aeba276fcb7df8e10153a07ee728d5540693f5aa:-3
+  > bd5548558fcf354d37613005737a143871bf3723:-3
+  > 
d2fa1c02b2401b0e32867f26cce50818a4bd796a:
+  > 
6f7a236de6852570cd54649ab62b1012bb78abc8:
+  > 
6582e6951a9c48c236f746f186378e36f59f4928:
+  > EOF
+
+  $ hg rebase --continue
+  rebasing 4:c1e6b162678d "B" (B)
+  rebasing 8:6f7a236de685 "D" (D)
+  rebasing 2:de008c61a447 "E" (E)
+  rebasing 7:d2fa1c02b240 "G" (G)
+  rebasing 9:6582e6951a9c "H" (H tip)
+  warning: orphaned descendants detected, not stripping c1e6b162678d, 
de008c61a447
+  saved backup bundle to 
$TESTTMP/.hg/strip-backup/6f7a236de685-9880a3dc-rebase.hg (glob)
+
+  $ hg log -G -T '{rev}:{node|short} {desc}\n'
+  o  11:721b8da0a708 H
+  |
+  o  10:9d65695ec3c2 G
+  |
+  o  9:21c8397a5d68 E
+  |
+  | o  8:fc52970345e8 D
+  | |
+  | o  7:eac96551b107 B
+  |/
+  | o  6:bd5548558fcf C
+  | |
+  | | o  5:aeba276fcb7d F
+  | | |
+  | o |  4:c1e6b162678d B
+  | | |
+  o | |  3:f424eb6a8c01 Z
+  | | |
+  +---o  2:de008c61a447 E
+  | |
+  | o  1:21a6c4502885 A
+  |/
+  o  0:b41ce7760717 R
+  
diff --git a/hgext/rebase.py b/hgext/rebase.py
--- a/hgext/rebase.py
+++ b/hgext/rebase.py
@@ -21,7 +21,6 @@
 
 from mercurial.i18n import _
 from mercurial.node import (
-hex,
 nullid,
 nullrev,
 short,
@@ -60,6 +59,7 @@
 
 # Indicates that a revision needs to be rebased
 revtodo = -1
+revtodostr = '-1'
 
 # legacy revstates no longer needed in current code
 # -2: nullmerge, -3: revignored, -4: revprecursor, -5: revpruned
@@ -146,7 +146,7 @@
 # dict will be what contains most of the rebase progress state.
 self.state = {}
 self.activebookmark = None
-self.dest = None
+self.destmap = {}
 self.skipped = set()
 
 self.collapsef = opts.get('collapse', False)
@@ -177,42 +177,45 @@
 def _writestatus(self, f):
 repo = self.repo.unfiltered()
 f.write(repo[self.originalwd].hex() + '\n')
-f.write(repo[self.dest].hex() + '\n')
+# was "dest". we now write dest per src root below.
+f.write('\n')
 f.write(repo[self.external].hex() + '\n')
 f.write('%d\n' % int(self.collapsef))
 f.write('%d\n' % int(self.keepf))
 f.write('%d\n' % int(self.keepbranchesf))
 f.write('%s\n' % (self.activebookmark or ''))
+destmap = self.destmap
 for d, v in self.state.iteritems():
 oldrev = repo[d].hex()
 if v >= 0:
 newrev = repo[v].hex()
-elif v == revtodo:
-# To maintain format compatibility, we have to use nullid.
-# Please do remove this special case when upgrading the format.
-newrev = hex(nullid)
 else:
 newrev = v
-f.write("%s:%s\n" % (oldrev, newrev))
+destnode = repo[destmap[d]].hex()
+f.write("%s:%s:%s\n" % (oldrev, newrev, destnode))
 repo.ui.debug('rebase status stored\n')
 
 def restorestatus(self):
 """Restore a previously stored status"""
 repo = self.repo
 keepbranches = None
-dest = None
+legacydest = None
 collapse = False
 external = nullrev
 activebookmark = None
 state = {}
+destmap = {}
 
 try:
 f = repo.vfs("rebasestate")
 for i, l in enumerate(f.read().splitlines()):
 if i == 0:
 originalwd = repo[l].rev()
 elif i == 1:
-dest = repo[l].rev()
+# this 

Re: D464: Use an unambigious path suffix for the commit editor file.

2017-08-21 Thread Sean Farley

mbolin (Michael Bolin)  writes:

> mbolin created this revision.
> Herald added a subscriber: mercurial-devel.
> Herald added a reviewer: hg-reviewers.
>
> REVISION SUMMARY
>   Changes the path for a commit editor file from `/tmp/hg-editor-XX.txt` 
> to
>   `/tmp/hg-editor-XX.hgcommit.txt`.
>   
>   Some editors (such as Atom) make it possible to statically define a 
> [TextMate]
>   grammar for files with a particular suffix. For example, because Git 
> reliably
>   uses `.git/COMMIT_EDITMSG` and `.git/MERGE_MSG` as the paths for commit-type
>   messages, it is trivial to define a grammar that is applied when files of
>   either name are opened in Atom:
>   
>   
> https://github.com/atom/language-git/blob/v0.19.1/grammars/git%20commit%20message.cson#L4-L5
>   
>   Because Hg currently uses the generic `.txt` suffix, it is much harder to
>   disambiguate whether the file is an arbitrary text file as opposed to one
>   created for the specific purpose of authoring an Hg commit message.
>   
>   It would be nice to update all of the other similar uses of temp files in 
> Hg,
>   but this seemed like the most impactful place to start.

This is actually why I created the `editortmpinhg' experimental setting.
If I understand correctly, that should be enough to statically match
`.hg/hg-editor-*.txt'. In fact, that's what I do here in my emacs
thingy:

https://bitbucket.org/seanfarley/mahgic/src/default/lisp/hg-commit.el#hg-commit.el-348


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


Re: D447: templatekw: choose {latesttag} by len(changes), not date (issue5659)

2017-08-21 Thread Sean Farley

yuja (Yuya Nishihara)  writes:

> yuja accepted this revision.
> yuja added a comment.
> This revision is now accepted and ready to land.
>
>
>   This one looks good to me, thanks. I leave it to Sean since he said he's 
> queued the previous series.

Thanks. I think I figured out out to queue this again. Will test, merge,
and push.


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


D468: Use ~ as a suffix when creating a temp file in the same directory as a source file.

2017-08-21 Thread mbolin (Michael Bolin)
mbolin created this revision.
Herald added a subscriber: mercurial-devel.

REVISION SUMMARY
  Tools like Buck have patterns to ignore the creation of files (in the working
  copy) that match certain patterns:
  
  
https://github.com/facebook/buck/blob/39278a4f0701c5239eae148968dc1ed4cc8661f7/src/com/facebook/buck/cli/Main.java#L259-L299
  
  When Buck sees a new source file (as reported by Watchman), it has to 
invalidate
  a number of caches associated with the directory that contains the file.
  Using a standard suffix, such as `~`, would make it easier for Buck and others
  to filter out these types of file creation events.
  
  The other uses of `tempfile.mkstemp()` in Hg do not appear to be problematic
  because they (generally speaking) do not specify the `dir` parameter, so the
  new file is created in the system-appropriate temp directory, which is outside
  the working copy.

TEST PLAN
  CI

REPOSITORY
  rHG Mercurial

BRANCH
  default

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

AFFECTED FILES
  mercurial/util.py

CHANGE DETAILS

diff --git a/mercurial/util.py b/mercurial/util.py
--- a/mercurial/util.py
+++ b/mercurial/util.py
@@ -1525,7 +1525,7 @@
 Returns the name of the temporary file.
 """
 d, fn = os.path.split(name)
-fd, temp = tempfile.mkstemp(prefix='.%s-' % fn, dir=d)
+fd, temp = tempfile.mkstemp(prefix='.%s-' % fn, suffix='~', dir=d)
 os.close(fd)
 # Temporary files are created with mode 0600, which is usually not
 # what we want.  If the original file already exists, just copy



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


D464: commit: use an unambiguous path suffix for the commit editor file

2017-08-21 Thread quark (Jun Wu)
quark accepted this revision.
quark added a comment.


  Looks good to me. I have changed the title to follow the `topic: 
uncapitalized, no trailing period` pattern suggested by ContributingChanges 
wiki .

REPOSITORY
  rHG Mercurial

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

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


D466: run-tests: make per-line condition support testcase names

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

REVISION SUMMARY
  https://phab.mercurial-scm.org/rHG7340465bd78819921cc7a07dfed17dc9ca573b7f 
added multiple test cases support. The latter has a problem -
  output lines cannot be made conditional with `#if`:
  
# COUNTEREXAMPLE: DOES NOT WORK
#testcases A B
  $ command-foo
  common ouput
#if A
  A's ouput
#else
  B's ouput
#endif
  common ouput
  
  That's not trivial to fix (even if it works in test, `run-tests.py -i` may
  be suboptimal because diff algorithm does not know how to skip the `#if`
  lines, even if it does, it may have trouble figuring out whether a changed
  line belongs to inside a `#if` block or outside).
  
  Matching output lines conditionally is useful. 
https://phab.mercurial-scm.org/rHG4eec2f04a672a9d53d305e885f762093b805e486 
added per-line
  condition support for hghave. This patch extends that to also support test
  case names.

REPOSITORY
  rHG Mercurial

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

AFFECTED FILES
  tests/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
@@ -823,6 +823,20 @@
 2
   #endif
 
+  $ cat >> test-cases.t <<'EOF'
+  > #if a
+  >   $ NAME=A
+  > #else
+  >   $ NAME=B
+  > #endif
+  >   $ echo $NAME
+  >   A (a !)
+  >   B (b !)
+  > EOF
+  $ rt test-cases.t
+  ..
+  # Ran 2 tests, 0 skipped, 0 failed.
+
   $ rm test-cases.t
 
 (reinstall)
diff --git a/tests/run-tests.py b/tests/run-tests.py
--- a/tests/run-tests.py
+++ b/tests/run-tests.py
@@ -1425,7 +1425,7 @@
 conditions = [
 c for c in m.group(2).split(b' ')]
 
-if not self._hghave(conditions)[0]:
+if not self._iftest(conditions):
 optional.append(i)
 
 i += 1
@@ -1459,7 +1459,7 @@
 if m:
 conditions = [c for c in m.group(2).split(' ')]
 
-if self._hghave(conditions)[0]:
+if self._iftest(conditions):
 # Don't append as optional line
 continue
 else:
@@ -1540,7 +1540,7 @@
 conditions = [c for c in m.group(2).split(b' ')]
 
 el = m.group(1) + b"\n"
-if not self._hghave(conditions)[0]:
+if not self._iftest(conditions):
 retry = "retry"# Not required by listed features
 
 if el.endswith(b" (esc)\n"):



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


[PATCH 3 of 4] client: don't swallow ResponseError inside open()

2017-08-21 Thread Gábor Stefanik
# HG changeset patch
# User Gábor Stefanik 
# Date 1503327973 -7200
#  Mon Aug 21 17:06:13 2017 +0200
# Node ID 8b4d606b49655d44091c2689a3f35a3fff17a28d
# Parent  e2b082707b44c5d9f630bf0ca722723bad8cefb1
client: don't swallow ResponseError inside open()

_readhello() can generate meaningful ResponseError exceptions. However,
open()'s exception handler swallows these, converting them into generic
ServerErrors. Allow the original ResponseErrors to pass through.

diff -r e2b082707b44 -r 8b4d606b4965 hglib/client.py
--- a/hglib/client.py   Mon Aug 21 17:02:14 2017 +0200
+++ b/hglib/client.py   Mon Aug 21 17:06:13 2017 +0200
@@ -259,6 +259,9 @@
 self.server = util.popen(self._args, self._env)
 try:
 self._readhello()
+except error.ResponseError:
+self.close()
+raise
 except error.ServerError:
 ret, serr = self._close()
 raise error.ServerError('server exited with status %d: %s'

 This message, including its attachments, is confidential and the property of 
NNG Llc. For more information please read NNG's email policy here:
http://www.nng.com/emailpolicy/
By responding to this email you accept the email policy.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 4 of 4] client: raise ResponseError in _readchannel()

2017-08-21 Thread Gábor Stefanik
# HG changeset patch
# User Gábor Stefanik 
# Date 1503328417 -7200
#  Mon Aug 21 17:13:37 2017 +0200
# Node ID 6f59b1f3360d599dfe66cf509bbde926d87ebe5e
# Parent  8b4d606b49655d44091c2689a3f35a3fff17a28d
client: raise ResponseError in _readchannel()

Make it clearer that this is an unrecoverable communication error.
ServerError alone is not always unrecoverable, as CapabilityError is considered
a subtype of it.

This way, a caller can check for ResponseError to identify errors that require
reopening the client to recover.

diff -r 8b4d606b4965 -r 6f59b1f3360d hglib/client.py
--- a/hglib/client.py   Mon Aug 21 17:06:13 2017 +0200
+++ b/hglib/client.py   Mon Aug 21 17:13:37 2017 +0200
@@ -140,7 +140,7 @@
 data = self.server.stdout.read(hgclient.outputfmtsize)
 if not data:
 self.close()
-raise error.ServerError()
+raise error.ResponseError('no response received from server')
 channel, length = struct.unpack(hgclient.outputfmt, data)
 if channel in b('IL'):
 return channel, length

 This message, including its attachments, is confidential and the property of 
NNG Llc. For more information please read NNG's email policy here:
http://www.nng.com/emailpolicy/
By responding to this email you accept the email policy.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D464: Use an unambigious path suffix for the commit editor file.

2017-08-21 Thread mbolin (Michael Bolin)
mbolin created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  Changes the path for a commit editor file from `/tmp/hg-editor-XX.txt` to
  `/tmp/hg-editor-XX.hgcommit.txt`.
  
  Some editors (such as Atom) make it possible to statically define a [TextMate]
  grammar for files with a particular suffix. For example, because Git reliably
  uses `.git/COMMIT_EDITMSG` and `.git/MERGE_MSG` as the paths for commit-type
  messages, it is trivial to define a grammar that is applied when files of
  either name are opened in Atom:
  
  
https://github.com/atom/language-git/blob/v0.19.1/grammars/git%20commit%20message.cson#L4-L5
  
  Because Hg currently uses the generic `.txt` suffix, it is much harder to
  disambiguate whether the file is an arbitrary text file as opposed to one
  created for the specific purpose of authoring an Hg commit message.
  
  It would be nice to update all of the other similar uses of temp files in Hg,
  but this seemed like the most impactful place to start.

TEST PLAN
  Created this commit using this change and saw that it used
  `/tmp/hg-editor-HiUL0W.hgcommit.txt` as the path instead of
  `/tmp/hg-editor-HiUL0W.txt` as the path.

REPOSITORY
  rHG Mercurial

BRANCH
  default

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

AFFECTED FILES
  mercurial/cmdutil.py

CHANGE DETAILS

diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -3208,7 +3208,12 @@
 repo.dirstate.write(tr)
 pending = tr and tr.writepending() and repo.root
 
-editortext = repo.ui.edit(committext, ctx.user(), ctx.extra(),
+# provide an unambigious path suffix so editors can provide special support
+# for authoring Hg commit messages
+extra = ctx.extra()
+extra['suffix'] = '.hgcommit.txt'
+
+editortext = repo.ui.edit(committext, ctx.user(), extra,
   editform=editform, pending=pending,
   repopath=repo.path)
 text = editortext



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


Re: [PATCH 4 of 6] i18n: use saved object to get actual function information if available

2017-08-21 Thread FUJIWARA Katsunori
At Mon, 21 Aug 2017 21:46:35 +0900,
Yuya Nishihara wrote:
> 
> On Wed, 16 Aug 2017 01:19:04 +0900, FUJIWARA Katsunori wrote:
> > # HG changeset patch
> > # User FUJIWARA Katsunori 
> > # Date 1502792844 -32400
> > #  Tue Aug 15 19:27:24 2017 +0900
> > # Node ID b6dd19c795147e675b9caf58383b6cafd3f03534
> > # Parent  1d204d17d51eb143f1ef66426cec1831cd8c93bf
> > # Available At https://bitbucket.org/foozy/mercurial-wip
> > #  hg pull https://bitbucket.org/foozy/mercurial-wip -r 
> > b6dd19c79514
> > # EXP-Topic i18n-fix-update-pot-issues
> > i18n: use saved object to get actual function information if available
> > 
> > To list up available compression types instead of
> > ".. bundlecompressionmarker" in "hg help bundlespec" output, proxy
> > object "docobject" is used, because:
> > 
> > - current online help system requires that __doc__ of registered
> >   object (maybe, function) is already well formatted in reST syntax
> > 
> > - bundletype() method of compressionengine classes is used to list up
> >   available compression types, but
> > 
> > - __doc__ of bundletype() object (= "instancemethod") is read-only
> 
> Just curious. Any reason why we can't make the bundletype.__doc__ statically
> formatted?

Would you suppose change like below ?


diff --git a/mercurial/util.py b/mercurial/util.py
--- a/mercurial/util.py
+++ b/mercurial/util.py
@@ -3425,7 +3425,8 @@ class _zlibengine(compressionengine):
 return 'zlib'
 
 def bundletype(self):
-"""zlib compression using the DEFLATE algorithm.
+"""``zlib``
+zlib compression using the DEFLATE algorithm.
 
 All Mercurial clients should support this format. The compression
 algorithm strikes a reasonable balance between compression ratio


If we keep extensibility of compression algorithms, this kind of
manual formatting causes broken help output easily, IMHO.

Though, I don't know any plan or actual implementation of compression
type other than built-in ones :-)

-- 
--
[FUJIWARA Katsunori] fo...@lares.dti.ne.jp
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D451: revset: remove order information from tree

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

INLINE COMMENTS

> quark wrote in revset.py:893
> In this case, `y` is expected to completely redefine the order. So `y`'s 
> `subset`'s order does not matter.

By "y's subset", I mean "getset(repo, subset, x, xorder)".

REPOSITORY
  rHG Mercurial

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

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


D451: revset: remove order information from tree

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

INLINE COMMENTS

> yuja wrote in revset.py:129
> `subset & xs` should be correct since `dagrange` doesn't have
> its own order unlike `rangeset`.
> 
> Most revset functions "follow" the default order even if they
> are used where they may "define" order.

For `subset & xs` to be correct, `subset` needs to be in ascending order. That 
is true currently. But it is not very obvious why `subset` is in ascending 
order here (or, the question is, who is responsible to sort it?).

I think it's simpler to not depend on it and make every revset respect 
`defineorder` explicitly. That also allows us to remove some unnecessary 
sorting.

> yuja wrote in revset.py:893
> IIUC, `followorder` is correct because the ordering flags of
> `x and y` are flipped as if they were `y and x`.

In this case, `y` is expected to completely redefine the order. So `y`'s 
`subset`'s order does not matter.

> yuja wrote in revset.py:1830
> Can you split this to new patch, and preferably include a micro benchmark?
> 
> Revset had historically lots of subtle ordering bugs, and I believe
> there are still some. Fewer "if"s should be better in general.

I can do that.

REPOSITORY
  rHG Mercurial

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

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


D358: copytrace: move fb extension to core under flag experimental.fastcopytrace

2017-08-21 Thread stash (Stanislau Hlebik)
stash added a comment.


  Quick heads-up: one of our bootcampers works on the task that does the 
following: if rebase/merge/graft happens only on the local stack (i.e. base 
commit is draft), then we fallback to the normal copytrace, because we are sure 
it's going to be fast enough

REPOSITORY
  rHG Mercurial

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

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


mercurial@33857: 19 new changesets

2017-08-21 Thread Mercurial Commits
19 new changesets in mercurial:

https://www.mercurial-scm.org/repo/hg/rev/7d5bc0e5b88f
changeset:   33839:7d5bc0e5b88f
user:Augie Fackler 
date:Mon Jul 24 14:38:40 2017 -0400
summary: py3: introduce a wrapper for __builtins__.{raw_,}input()

https://www.mercurial-scm.org/repo/hg/rev/627cb36b537f
changeset:   33840:627cb36b537f
user:Augie Fackler 
date:Thu Jul 27 00:00:15 2017 -0400
summary: python3: whitelist another *13* tests that now pass

https://www.mercurial-scm.org/repo/hg/rev/35fc5e919675
changeset:   33841:35fc5e919675
user:Jun Wu 
date:Sat Jul 08 20:05:52 2017 -0700
summary: rebase: extract ctx description logic to a function

https://www.mercurial-scm.org/repo/hg/rev/30573b3d2ebc
changeset:   33842:30573b3d2ebc
user:Jun Wu 
date:Sat Jul 08 20:14:33 2017 -0700
summary: rebase: move obsoleted not rebased messages earlier (BC)

https://www.mercurial-scm.org/repo/hg/rev/d8d0ef5f5975
changeset:   33843:d8d0ef5f5975
user:Jun Wu 
date:Sat Jul 08 20:38:34 2017 -0700
summary: rebase: remove revprecursor and revpruned states (BC)

https://www.mercurial-scm.org/repo/hg/rev/437e317d7913
changeset:   33844:437e317d7913
user:Jun Wu 
date:Sat Jul 08 20:38:34 2017 -0700
summary: rebase: remove messages for nullmerge and revignored (BC)

https://www.mercurial-scm.org/repo/hg/rev/3ddbab49efcf
changeset:   33845:3ddbab49efcf
user:Jun Wu 
date:Mon Jul 10 12:18:32 2017 -0700
summary: rebase: remove revignored and nullmerge states

https://www.mercurial-scm.org/repo/hg/rev/3b04a6ff625c
changeset:   33846:3b04a6ff625c
user:Jun Wu 
date:Fri Jul 14 09:01:45 2017 -0700
summary: rebase: remove rebaseset from _checkobsrebase

https://www.mercurial-scm.org/repo/hg/rev/ddf77c0cc169
changeset:   33847:ddf77c0cc169
user:Jun Wu 
date:Fri Aug 11 01:05:47 2017 -0700
summary: rebase: remove self.destancestors

https://www.mercurial-scm.org/repo/hg/rev/bc9e075133c9
changeset:   33848:bc9e075133c9
user:Jun Wu 
date:Fri Aug 11 01:36:59 2017 -0700
summary: rebase: remove "state >= revtodo" condition

https://www.mercurial-scm.org/repo/hg/rev/3ae2eaecb49e
changeset:   33849:3ae2eaecb49e
user:Jun Wu 
date:Fri Aug 11 01:08:07 2017 -0700
summary: rebase: optimize "source" calculation in adjustdest

https://www.mercurial-scm.org/repo/hg/rev/84a3e04e35b5
changeset:   33850:84a3e04e35b5
user:Yuya Nishihara 
date:Wed Aug 16 13:57:19 2017 +0900
summary: templatekw: rename termwidth() per convention

https://www.mercurial-scm.org/repo/hg/rev/7827fbbd0b06
changeset:   33851:7827fbbd0b06
user:Yuya Nishihara 
date:Sun Aug 13 14:12:28 2017 +0900
summary: templatekw: specify plural form of instability

https://www.mercurial-scm.org/repo/hg/rev/f18b11534274
changeset:   33852:f18b11534274
user:Yuya Nishihara 
date:Wed Aug 16 13:50:11 2017 +0900
summary: py3: make encoding.strio() an identity function on Python 2

https://www.mercurial-scm.org/repo/hg/rev/cfcfbe6c96f8
changeset:   33853:cfcfbe6c96f8
user:Yuya Nishihara 
date:Wed Aug 16 13:54:24 2017 +0900
summary: py3: select input or raw_input by pycompat

https://www.mercurial-scm.org/repo/hg/rev/f6dc30b83432
changeset:   33854:f6dc30b83432
user:Jun Wu 
date:Tue Aug 15 17:22:57 2017 -0700
summary: push: fix docsstring

https://www.mercurial-scm.org/repo/hg/rev/457d1ebf151b
changeset:   33855:457d1ebf151b
user:Boris Feld 
date:Wed Aug 16 16:48:41 2017 +0200
summary: revset: mark evolution-related revsets as experimental

https://www.mercurial-scm.org/repo/hg/rev/eae63a9e59da
changeset:   33856:eae63a9e59da
user:Boris Feld 
date:Wed Aug 16 10:26:26 2017 +0200
summary: obsmarker: precnode was renamed into prednode

https://www.mercurial-scm.org/repo/hg/rev/833f70277f0e
changeset:   33857:833f70277f0e
bookmark:@
tag: tip
user:Boris Feld 
date:Wed Aug 16 10:18:57 2017 +0200
summary: obsmarker: fix precnode deprecation

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


[PATCH 2 of 4] client: kill the server on unrecoverable communication errors (issue5516)

2017-08-21 Thread Gábor Stefanik
# HG changeset patch
# User Gábor Stefanik 
# Date 1503327734 -7200
#  Mon Aug 21 17:02:14 2017 +0200
# Node ID e2b082707b44c5d9f630bf0ca722723bad8cefb1
# Parent  242d719e85ce451e61ab262eec443668bb4792ce
client: kill the server on unrecoverable communication errors (issue5516)

Once an unrecoverable communication error occurs between the client and server,
it's no longer safe to send further commands to the same server.
On Windows, attempting to do so is known to cause lockups and memory leaks.

Close the client and kill the server when an such an error occurs. This way,
any further commands will fail gracefully with ValueError until the client
is reopened.

diff -r 242d719e85ce -r e2b082707b44 hglib/client.py
--- a/hglib/client.py   Mon Aug 21 16:39:17 2017 +0200
+++ b/hglib/client.py   Mon Aug 21 17:02:14 2017 +0200
@@ -139,6 +139,7 @@
 def _readchannel(self):
 data = self.server.stdout.read(hgclient.outputfmtsize)
 if not data:
+self.close()
 raise error.ServerError()
 channel, length = struct.unpack(hgclient.outputfmt, data)
 if channel in b('IL'):
@@ -190,6 +191,7 @@
 return struct.unpack(hgclient.retfmt, data)[0]
 # a channel that we don't know and can't ignore
 elif channel.isupper():
+self.close()
 raise error.ResponseError(
 "unexpected data on required channel '%s'" % channel)
 # optional channel

 This message, including its attachments, is confidential and the property of 
NNG Llc. For more information please read NNG's email policy here:
http://www.nng.com/emailpolicy/
By responding to this email you accept the email policy.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 1 of 4] client: fail gracefully on unexpected prompts (issue5516)

2017-08-21 Thread Gábor Stefanik
# HG changeset patch
# User Gábor Stefanik 
# Date 1503326357 -7200
#  Mon Aug 21 16:39:17 2017 +0200
# Node ID 242d719e85ce451e61ab262eec443668bb4792ce
# Parent  8e959ad6a25c9fe6ab490e1a4cbd5f7445d9bcb1
client: fail gracefully on unexpected prompts (issue5516)

Right now, if hglib encounters an unexpected prompt, it fails with a rather
opaque "unexpected data on required channel 'L'" error message. Furthermore,
if subsequently another command is called on the same client instance, both
the client and server processes lock up hard (at least on Windows), and the
server process rapidly leaks ~2GB of memory.

Fix this by responding with an empty string to any unexpected prompt. This
will trigger an "abort: response expected" exception from the server, which
is easily handled as a CommandError, and subsequent commands sent from the
same client work as expected.

This doesn't completely resolve bug 5516, as unexpected requests on another
required channel (e.g. I) can still cause a lockup.
However, it does fix the most common case of an unexpected password prompt.

diff -r 8e959ad6a25c -r 242d719e85ce hglib/client.py
--- a/hglib/client.py   Mon Apr 03 16:02:08 2017 -0500
+++ b/hglib/client.py   Mon Aug 21 16:39:17 2017 +0200
@@ -235,6 +235,8 @@
 reply = prompt(size, out.getvalue())
 return reply
 inchannels[b('L')] = func
+else:
+inchannels[b('L')] = lambda _: ''
 if input is not None:
 inchannels[b('I')] = input


 This message, including its attachments, is confidential and the property of 
NNG Llc. For more information please read NNG's email policy here:
http://www.nng.com/emailpolicy/
By responding to this email you accept the email policy.
___
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-21 Thread martinvonz (Martin von Zweigbergk)
martinvonz added a comment.


  > it may make sense to have a more generic "textwidth"
  
  Good idea! That seems like what one usually wants. Can we not simply add that 
(defined as "termwidth - graphwidth")? If we had that, when would one want 
termwidth or graphwidth themselves?

REPOSITORY
  rHG Mercurial

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

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


D451: revset: remove order information from tree

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


  In https://phab.mercurial-scm.org/D451#7257, @yuja wrote:
  
  > We could change this policy so all predicates must "define" their own 
ordering
  >  schemes (as you did, I think), but I guess that would lead to bugs that 
are hardly
  >  noticed.
  
  
  I think the current way is easier to hide bugs if more revset's `defineorder` 
is not the default (ascending). For example, I think `p1(X+Y)` could be 
naturally parsed as `p1(X) + p1(Y)` so it is not equivalent to `p1(Y+X)`. But 
the current code relies heavily on default ascending order and could not 
implement that easily. (This series does not change `p1` behavior, it's just a 
possibility)
  
  My understanding about `anyorder` is, we can random-shuffle `anyorder` sets 
without affecting correctness - I had tried that approach and it did reveal 
issues (like "contains" does not respect "defineorder"). But I found 
https://phab.mercurial-scm.org/D456 to be a stronger test about ordering issues.
  
  > So I'm against to bring more "any" ordering without noticeable
  >  performance win. Can you measure it?
  
  Probably hard to measure. I think with the new suggested code pattern (either 
taking `subset` and `order`, or take none of them), it's harder to implement 
wrong.

REPOSITORY
  rHG Mercurial

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

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


[PATCH 3 of 4] client: don't swallow ResponseError inside open()

2017-08-21 Thread Gábor Stefanik
# HG changeset patch
# User Gábor Stefanik 
# Date 1503327973 -7200
#  Mon Aug 21 17:06:13 2017 +0200
# Node ID 8b4d606b49655d44091c2689a3f35a3fff17a28d
# Parent  e2b082707b44c5d9f630bf0ca722723bad8cefb1
client: don't swallow ResponseError inside open()

_readhello() can generate meaningful ResponseError exceptions. However,
open()'s exception handler swallows these, converting them into generic
ServerErrors. Allow the original ResponseErrors to pass through.

diff -r e2b082707b44 -r 8b4d606b4965 hglib/client.py
--- a/hglib/client.py   Mon Aug 21 17:02:14 2017 +0200
+++ b/hglib/client.py   Mon Aug 21 17:06:13 2017 +0200
@@ -259,6 +259,9 @@
 self.server = util.popen(self._args, self._env)
 try:
 self._readhello()
+except error.ResponseError:
+self.close()
+raise
 except error.ServerError:
 ret, serr = self._close()
 raise error.ServerError('server exited with status %d: %s'

 This message, including its attachments, is confidential and the property of 
NNG Llc. For more information please read NNG's email policy here:
http://www.nng.com/emailpolicy/
By responding to this email you accept the email policy.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 1 of 4] client: fail gracefully on unexpected prompts (issue5516)

2017-08-21 Thread Gábor Stefanik
# HG changeset patch
# User Gábor Stefanik 
# Date 1503326357 -7200
#  Mon Aug 21 16:39:17 2017 +0200
# Node ID 242d719e85ce451e61ab262eec443668bb4792ce
# Parent  8e959ad6a25c9fe6ab490e1a4cbd5f7445d9bcb1
client: fail gracefully on unexpected prompts (issue5516)

Right now, if hglib encounters an unexpected prompt, it fails with a rather
opaque "unexpected data on required channel 'L'" error message. Furthermore,
if subsequently another command is called on the same client instance, both
the client and server processes lock up hard (at least on Windows), and the
server process rapidly leaks ~2GB of memory.

Fix this by responding with an empty string to any unexpected prompt. This
will trigger an "abort: response expected" exception from the server, which
is easily handled as a CommandError, and subsequent commands sent from the
same client work as expected.

This doesn't completely resolve bug 5516, as unexpected requests on another
required channel (e.g. I) can still cause a lockup.
However, it does fix the most common case of an unexpected password prompt.

diff -r 8e959ad6a25c -r 242d719e85ce hglib/client.py
--- a/hglib/client.py   Mon Apr 03 16:02:08 2017 -0500
+++ b/hglib/client.py   Mon Aug 21 16:39:17 2017 +0200
@@ -235,6 +235,8 @@
 reply = prompt(size, out.getvalue())
 return reply
 inchannels[b('L')] = func
+else:
+inchannels[b('L')] = lambda _: ''
 if input is not None:
 inchannels[b('I')] = input


 This message, including its attachments, is confidential and the property of 
NNG Llc. For more information please read NNG's email policy here:
http://www.nng.com/emailpolicy/
By responding to this email you accept the email policy.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 4 of 4] client: raise ResponseError in _readchannel()

2017-08-21 Thread Gábor Stefanik
# HG changeset patch
# User Gábor Stefanik 
# Date 1503328417 -7200
#  Mon Aug 21 17:13:37 2017 +0200
# Node ID 6f59b1f3360d599dfe66cf509bbde926d87ebe5e
# Parent  8b4d606b49655d44091c2689a3f35a3fff17a28d
client: raise ResponseError in _readchannel()

Make it clearer that this is an unrecoverable communication error.
ServerError alone is not always unrecoverable, as CapabilityError is considered
a subtype of it.

This way, a caller can check for ResponseError to identify errors that require
reopening the client to recover.

diff -r 8b4d606b4965 -r 6f59b1f3360d hglib/client.py
--- a/hglib/client.py   Mon Aug 21 17:06:13 2017 +0200
+++ b/hglib/client.py   Mon Aug 21 17:13:37 2017 +0200
@@ -140,7 +140,7 @@
 data = self.server.stdout.read(hgclient.outputfmtsize)
 if not data:
 self.close()
-raise error.ServerError()
+raise error.ResponseError('no response received from server')
 channel, length = struct.unpack(hgclient.outputfmt, data)
 if channel in b('IL'):
 return channel, length

 This message, including its attachments, is confidential and the property of 
NNG Llc. For more information please read NNG's email policy here:
http://www.nng.com/emailpolicy/
By responding to this email you accept the email policy.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 4] client: kill the server on unrecoverable communication errors (issue5516)

2017-08-21 Thread Gábor Stefanik
# HG changeset patch
# User Gábor Stefanik 
# Date 1503327734 -7200
#  Mon Aug 21 17:02:14 2017 +0200
# Node ID e2b082707b44c5d9f630bf0ca722723bad8cefb1
# Parent  242d719e85ce451e61ab262eec443668bb4792ce
client: kill the server on unrecoverable communication errors (issue5516)

Once an unrecoverable communication error occurs between the client and server,
it's no longer safe to send further commands to the same server.
On Windows, attempting to do so is known to cause lockups and memory leaks.

Close the client and kill the server when an such an error occurs. This way,
any further commands will fail gracefully with ValueError until the client
is reopened.

diff -r 242d719e85ce -r e2b082707b44 hglib/client.py
--- a/hglib/client.py   Mon Aug 21 16:39:17 2017 +0200
+++ b/hglib/client.py   Mon Aug 21 17:02:14 2017 +0200
@@ -139,6 +139,7 @@
 def _readchannel(self):
 data = self.server.stdout.read(hgclient.outputfmtsize)
 if not data:
+self.close()
 raise error.ServerError()
 channel, length = struct.unpack(hgclient.outputfmt, data)
 if channel in b('IL'):
@@ -190,6 +191,7 @@
 return struct.unpack(hgclient.retfmt, data)[0]
 # a channel that we don't know and can't ignore
 elif channel.isupper():
+self.close()
 raise error.ResponseError(
 "unexpected data on required channel '%s'" % channel)
 # optional channel

 This message, including its attachments, is confidential and the property of 
NNG Llc. For more information please read NNG's email policy here:
http://www.nng.com/emailpolicy/
By responding to this email you accept the email policy.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D340: rebase: choose merge base without unwanted revisions

2017-08-21 Thread quark (Jun Wu)
This revision was automatically updated to reflect the committed changes.
Closed by commit rHG3160876c6e4e: rebase: choose merge base without unwanted 
revisions (authored by quark).

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D340?vs=1085=1124

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

AFFECTED FILES
  hgext/rebase.py
  tests/test-rebase-newancestor.t
  tests/test-rebase-obsolete.t

CHANGE DETAILS

diff --git a/tests/test-rebase-obsolete.t b/tests/test-rebase-obsolete.t
--- a/tests/test-rebase-obsolete.t
+++ b/tests/test-rebase-obsolete.t
@@ -1065,10 +1065,8 @@
   note: not rebasing 3:7fb047a69f22 "E" (E), already in destination as 
1:112478962961 "B"
   rebasing 2:b18e25de2cf5 "D" (D)
   rebasing 5:66f1a38021c9 "F" (F tip)
-  warning: rebasing 5:66f1a38021c9 may include unwanted changes from 
3:7fb047a69f22
+  note: rebase of 5:66f1a38021c9 created no changes to commit
   $ hg log -G
-  o  7:9ed45af61fa0 F
-  |
   o  6:8f47515dda15 D
   |
   | x5:66f1a38021c9 F
@@ -1102,11 +1100,9 @@
   note: not rebasing 2:b18e25de2cf5 "D" (D), already in destination as 
1:112478962961 "B"
   rebasing 3:7fb047a69f22 "E" (E)
   rebasing 5:66f1a38021c9 "F" (F tip)
-  warning: rebasing 5:66f1a38021c9 may include unwanted changes from 
2:b18e25de2cf5
+  note: rebase of 5:66f1a38021c9 created no changes to commit
 
   $ hg log -G
-  o  7:502540f44880 F
-  |
   o  6:533690786a86 E
   |
   | x5:66f1a38021c9 F
@@ -1123,6 +1119,88 @@
   
   $ cd ..
 
+Rebase merge where both parents have successors in destination
+
+  $ hg init p12-succ-in-dest
+  $ cd p12-succ-in-dest
+  $ hg debugdrawdag <<'EOS'
+  >   E   F
+  >  /|  /|  # replace: A -> C
+  > A B C D  # replace: B -> D
+  > | |
+  > X Y
+  > EOS
+  $ hg rebase -r A+B+E -d F
+  note: not rebasing 4:a3d17304151f "A" (A), already in destination as 
0:96cc3511f894 "C"
+  note: not rebasing 5:b23a2cc00842 "B" (B), already in destination as 
1:058c1e1fb10a "D"
+  rebasing 7:dac5d11c5a7d "E" (E tip)
+  abort: rebasing 7:dac5d11c5a7d will include unwanted changes from 
3:59c792af609c, 5:b23a2cc00842 or 2:ba2b7fa7166d, 4:a3d17304151f
+  [255]
+  $ cd ..
+
+Rebase a non-clean merge. One parent has successor in destination, the other
+parent moves as requested.
+
+  $ hg init p1-succ-p2-move
+  $ cd p1-succ-p2-move
+  $ hg debugdrawdag <<'EOS'
+  >   D Z
+  >  /| | # replace: A -> C
+  > A B C # D/D = D
+  > EOS
+  $ hg rebase -r A+B+D -d Z
+  note: not rebasing 0:426bada5c675 "A" (A), already in destination as 
2:96cc3511f894 "C"
+  rebasing 1:fc2b737bb2e5 "B" (B)
+  rebasing 3:b8ed089c80ad "D" (D)
+
+  $ rm .hg/localtags
+  $ hg log -G
+  o  6:e4f78693cc88 D
+  |
+  o  5:76840d832e98 B
+  |
+  o  4:50e41c1f3950 Z
+  |
+  o  2:96cc3511f894 C
+  
+  $ hg files -r tip
+  B
+  C
+  D
+  Z
+
+  $ cd ..
+
+  $ hg init p1-move-p2-succ
+  $ cd p1-move-p2-succ
+  $ hg debugdrawdag <<'EOS'
+  >   D Z
+  >  /| |  # replace: B -> C
+  > A B C  # D/D = D
+  > EOS
+  $ hg rebase -r B+A+D -d Z
+  note: not rebasing 1:fc2b737bb2e5 "B" (B), already in destination as 
2:96cc3511f894 "C"
+  rebasing 0:426bada5c675 "A" (A)
+  rebasing 3:b8ed089c80ad "D" (D)
+
+  $ rm .hg/localtags
+  $ hg log -G
+  o  6:1b355ed94d82 D
+  |
+  o  5:a81a74d764a6 A
+  |
+  o  4:50e41c1f3950 Z
+  |
+  o  2:96cc3511f894 C
+  
+  $ hg files -r tip
+  A
+  C
+  D
+  Z
+
+  $ cd ..
+
 Test that bookmark is moved and working dir is updated when all changesets have
 equivalents in destination
   $ hg init rbsrepo && cd rbsrepo
diff --git a/tests/test-rebase-newancestor.t b/tests/test-rebase-newancestor.t
--- a/tests/test-rebase-newancestor.t
+++ b/tests/test-rebase-newancestor.t
@@ -354,16 +354,8 @@
   rebasing 5:5f2c926dfecf "D" (D)
   rebasing 6:b296604d9846 "E" (E)
   rebasing 7:caa9781e507d "F" (F tip)
-  warning: rebasing 7:caa9781e507d may include unwanted changes from 
4:d6003a550c2c
-  saved backup bundle to 
$TESTTMP/dual-merge-base1/.hg/strip-backup/b296604d9846-0516f6d2-rebase.hg 
(glob)
-  $ hg log -r 4 -T '{files}\n'
-  C
-  $ hg manifest -r 'desc(F)'
-  C
-  D
-  E
-  R
-  Z
+  abort: rebasing 7:caa9781e507d will include unwanted changes from 
4:d6003a550c2c or 3:c1e6b162678d
+  [255]
 
 The warning does not get printed if there is no unwanted change detected:
 
diff --git a/hgext/rebase.py b/hgext/rebase.py
--- a/hgext/rebase.py
+++ b/hgext/rebase.py
@@ -1041,11 +1041,14 @@
 for j, x in enumerate(newps[:i]):
 if x == nullrev:
 continue
-if isancestor(np, x):
+if isancestor(np, x): # CASE-1
 np = nullrev
-elif isancestor(x, np):
+elif isancestor(x, np): # CASE-2
 newps[j] = np
 np = nullrev
+# New parents forming an ancestor relationship does not
+# mean the old parents have a similar relationship. Do not
+# set bases[x] to 

D346: rebase: only change self.state when collapsing in _finishrebase

2017-08-21 Thread quark (Jun Wu)
This revision was automatically updated to reflect the committed changes.
Closed by commit rHG70354bd4f19b: rebase: only change self.state when 
collapsing in _finishrebase (authored by quark).

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D346?vs=780=1125

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

AFFECTED FILES
  hgext/rebase.py

CHANGE DETAILS

diff --git a/hgext/rebase.py b/hgext/rebase.py
--- a/hgext/rebase.py
+++ b/hgext/rebase.py
@@ -461,12 +461,10 @@
editor=editor,
keepbranches=self.keepbranchesf,
date=self.date)
-if newnode is None:
-newrev = self.dest
-else:
+if newnode is not None:
 newrev = repo[newnode].rev()
-for oldrev in self.state.iterkeys():
-self.state[oldrev] = newrev
+for oldrev in self.state.iterkeys():
+self.state[oldrev] = newrev
 
 if 'qtip' in repo.tags():
 updatemq(repo, self.state, self.skipped, **opts)



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


D451: revset: remove order information from tree

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


  (just scanned the series; no careful review yet)
  
  Perhaps the name `defineorder` was misleading. As of lazyset was introduced,
  most revset predicates "follow"ed the order of the input `subset`, which was 
by
  default rev-ascending. This is also true now. And there are a few exceptions
  (e.g. `rangeset`), which MAY enforce their ordering scheme if the flag is 
`defineorder`.
  
  So, `anyorder` for `not x` would be my mistake because `x and not y` could be
  theoretically flipped.
  
  We could change this policy so all predicates must "define" their own ordering
  schemes (as you did, I think), but I guess that would lead to bugs that are 
hardly
  noticed. So I'm against to bring more "any" ordering without noticeable
  performance win. Can you measure it?

INLINE COMMENTS

> quark wrote in revset.py:129
> In theory this should be:
> 
>   if order == defineorder:
>   return xs & subset
>   else:
>   return subset & xs
> 
> But it's a bit tricky to find a counterexample. I'm still trying.

`subset & xs` should be correct since `dagrange` doesn't have
its own order unlike `rangeset`.

Most revset functions "follow" the default order even if they
are used where they may "define" order.

> revset.py:893
> +# followorder for now to hide those issues.
> +xorder = followorder
> +else:

IIUC, `followorder` is correct because the ordering flags of
`x and y` are flipped as if they were `y and x`.

> revset.py:1830
> +
> +revs = getset(repo, subset, s, sorder)
>  

Can you split this to new patch, and preferably include a micro benchmark?

Revset had historically lots of subtle ordering bugs, and I believe
there are still some. Fewer "if"s should be better in general.

REPOSITORY
  rHG Mercurial

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

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


D423: pushvars: do not mangle repo state

2017-08-21 Thread ryanmce (Ryan McElroy)
ryanmce accepted this revision.
ryanmce added a comment.


  It would be really nice to get this change in.

REPOSITORY
  rHG Mercurial

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

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


mercurial@33838: 25 new changesets

2017-08-21 Thread Mercurial Commits
25 new changesets in mercurial:

https://www.mercurial-scm.org/repo/hg/rev/81b12f69ef5b
changeset:   33814:81b12f69ef5b
user:Matthieu Laneuville 
date:Fri Aug 11 14:21:49 2017 +0200
summary: run-tests: also color the summary messages (skipped, failed...)

https://www.mercurial-scm.org/repo/hg/rev/97ee669f1f6d
changeset:   33815:97ee669f1f6d
user:FUJIWARA Katsunori 
date:Wed Aug 02 01:03:20 2017 +0900
summary: i18n: make hggettext use original docstring to compute offset

https://www.mercurial-scm.org/repo/hg/rev/1775f93da25c
changeset:   33816:1775f93da25c
user:FUJIWARA Katsunori 
date:Wed Aug 02 01:15:07 2017 +0900
summary: largefiles: fix help text to avoid warning at "make update-pot"

https://www.mercurial-scm.org/repo/hg/rev/726dd73df3b9
changeset:   33817:726dd73df3b9
user:FUJIWARA Katsunori 
date:Sun Aug 13 15:20:16 2017 +0900
summary: i18n: ignore doctest part to avoid warning at "make update-pot"

https://www.mercurial-scm.org/repo/hg/rev/ed04d7254a91
changeset:   33818:ed04d7254a91
user:FUJIWARA Katsunori 
date:Tue Aug 15 19:27:24 2017 +0900
summary: i18n: use saved object to get actual function information if 
available

https://www.mercurial-scm.org/repo/hg/rev/d5ef17608159
changeset:   33819:d5ef17608159
user:FUJIWARA Katsunori 
date:Tue Aug 15 21:06:26 2017 +0900
summary: i18n: ignore docstring for modules under mercurial

https://www.mercurial-scm.org/repo/hg/rev/fa7e30efe05a
changeset:   33820:fa7e30efe05a
user:FUJIWARA Katsunori 
date:Tue Aug 15 21:09:33 2017 +0900
summary: i18n: get translation entries for description of each compression 
engines

https://www.mercurial-scm.org/repo/hg/rev/3c91cc0c5fde
changeset:   33821:3c91cc0c5fde
user:Augie Fackler 
date:Wed Jul 26 17:58:19 2017 -0400
summary: httppeer: add support for httppostargs when we're sending a file

https://www.mercurial-scm.org/repo/hg/rev/42ad7cc645a4
changeset:   33822:42ad7cc645a4
user:Pulkit Goyal <7895pul...@gmail.com>
date:Wed Aug 16 00:25:20 2017 +0530
summary: copies: add more details to the documentation of mergecopies()

https://www.mercurial-scm.org/repo/hg/rev/5d286eb7009f
changeset:   33823:5d286eb7009f
user:Martin von Zweigbergk 
date:Mon Aug 14 23:26:51 2017 -0700
summary: commit: move dirstateguard creation out of try-block

https://www.mercurial-scm.org/repo/hg/rev/158dddc635ff
changeset:   33824:158dddc635ff
user:Martin von Zweigbergk 
date:Mon Aug 14 23:26:54 2017 -0700
summary: commit: use context manager with dirstateguard

https://www.mercurial-scm.org/repo/hg/rev/de573184686e
changeset:   33825:de573184686e
user:Phil Cohen 
date:Sun Aug 13 20:06:52 2017 -0700
summary: simplemerge: extract verifytext as a helper function

https://www.mercurial-scm.org/repo/hg/rev/b3571dc0e6b8
changeset:   33826:b3571dc0e6b8
user:Phil Cohen 
date:Sun Aug 13 20:06:52 2017 -0700
summary: simplemerge: add optional context parameters to simplemerge

https://www.mercurial-scm.org/repo/hg/rev/db3e9f7c91aa
changeset:   33827:db3e9f7c91aa
user:Phil Cohen 
date:Sun Aug 13 20:06:52 2017 -0700
summary: filemerge: pass contexts to simplemerge

https://www.mercurial-scm.org/repo/hg/rev/8b91a4ff23ad
changeset:   33828:8b91a4ff23ad
user:Phil Cohen 
date:Sun Aug 13 20:06:52 2017 -0700
summary: simplemerge: use contexts to read file data from, if passed

https://www.mercurial-scm.org/repo/hg/rev/b86fc43e4b73
changeset:   33829:b86fc43e4b73
user:Phil Cohen 
date:Sun Aug 13 22:46:03 2017 -0700
summary: simplemerge: write merge result to the localctx, if passed

https://www.mercurial-scm.org/repo/hg/rev/aa6c290a77fa
changeset:   33830:aa6c290a77fa
user:Phil Cohen 
date:Sun Aug 13 22:46:16 2017 -0700
summary: filemerge: extract `_picklabels` as a helper function

https://www.mercurial-scm.org/repo/hg/rev/75fdaf851e83
changeset:   33831:75fdaf851e83
user:Jun Wu 
date:Mon Jul 17 23:14:06 2017 -0700
summary: phabricator: change "readpatch" to be more flexible

https://www.mercurial-scm.org/repo/hg/rev/539541779010
changeset:   33832:539541779010
user:Jun Wu 
date:Mon Jul 17 23:19:11 2017 -0700
summary: phabricator: add a small language to query Differential Revisions

https://www.mercurial-scm.org/repo/hg/rev/fb59192b4981
changeset:   33833:fb59192b4981
user:Jun Wu 
date:Tue Jul 18 01:34:55 

Re: [PATCH 8 of 9 V3] template: better prune support in obsfate

2017-08-21 Thread Boris Feld
On Mon, 2017-08-21 at 13:06 +0200, Denis Laxalde wrote:
> Boris Feld a écrit :
> > # HG changeset patch
> > # User Boris Feld 
> > # Date 1499096336 -7200
> > #  Mon Jul 03 17:38:56 2017 +0200
> > # Node ID 7cb7e67addd11cdbecea49ec707e3e9b30bb8677
> > # Parent  faad6d683f7a30996007116d296df9ebf853c44d
> > # EXP-Topic obsfatetemplate
> > template: better prune support in obsfate
> > 
> > successorssets don't returns good results for pruned commit, add a
> > workaround
> > for simple cases.
> > 
> > A proper fix would require a large rework of successorssets
> > algorithm, I will
> > send a separate series for this refactoring.
> > 
> > diff -r faad6d683f7a -r 7cb7e67addd1 mercurial/obsutil.py
> > --- a/mercurial/obsutil.py  Mon Jul 03 15:34:10 2017 +0200
> > +++ b/mercurial/obsutil.py  Mon Jul 03 17:38:56 2017 +0200
> > @@ -614,8 +614,32 @@
> >   
> >   ssets = successorssets(repo, ctx.node(), closest=True)
> >   
> > +# closestsuccessors returns an empty list for pruned
> > revisions, remap it
> > +# into a list containing en empty list for future processing
> 
> typo: "an" empty list

Fixed thanks

> 
> > +if ssets == []:
> > +ssets = [[]]
> > +
> > +# Try to recover pruned markers
> > +succsmap = repo.obsstore.successors
> > +fullsuccessorsets = [] # successor set + markers
> > +for sset in ssets:
> > +if sset:
> > +fullsuccessorsets.append(sset)
> > +else:
> > +# XXX we do not catch all prune markers (eg rewritten
> > then pruned)
> > +# (fix me later)
> > +foundany = False
> > +for mark in succsmap.get(ctx.node(), ()):
> > +if not mark[1]:
> > +foundany = True
> > +sset = _succs()
> > +sset.markers.add(mark)
> > +fullsuccessorsets.append(sset)
> > +if not foundany:
> > +fullsuccessorsets.append(_succs())
> > +
> >   values = []
> > -for sset in ssets:
> > +for sset in fullsuccessorsets:
> >   values.append({'successors': sset, 'markers':
> > sset.markers})
> >   
> >   return values
> 
> Maybe I'm not familiar enough with these things, but I can't figure
> out
> what the algorithm is doing. Would you mind explaining it in a
> comment?

I've added a comment on the next version of this series, here it is:

# successorsset return an empty set() when ctx or one of its successors
is
# pruned.
# In this case, walk the obs-markers tree again starting with ctx and
find the
# relevant pruning obs-makers, the ones without successors.
# Returning these markers allow us to compute some information about
its fate,
# like who pruned this changeset and when.

# XXX we do not catch all prune markers (eg rewritten then pruned) (fix
me
# later)

What do you think? Is the comment clear?


I will wait for yuja comment on the series before sending a V4.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH v4] run-tests: also color the summary messages (skipped, failed...)

2017-08-21 Thread Yuya Nishihara
On Fri, 11 Aug 2017 14:25:12 +0200, mlaneuvi...@gmail.com wrote:
> # HG changeset patch
> # User Matthieu Laneuville 
> # Date 1502454109 -7200
> #  Fri Aug 11 14:21:49 2017 +0200
> # Node ID 26bd9bfc7f679dc521b8056b48875eee71cd8627
> # Parent  609606d217659e0a6c1cf6f907b6512be5340e57
> run-tests: also color the summary messages (skipped, failed...)
> 
> diff -r 609606d21765 -r 26bd9bfc7f67 tests/run-tests.py
> --- a/tests/run-tests.py  Thu Jul 20 01:30:41 2017 -0700
> +++ b/tests/run-tests.py  Fri Aug 11 14:21:49 2017 +0200
> @@ -94,13 +94,48 @@
>  try: # is pygments installed
>  import pygments
>  import pygments.lexers as lexers
> +import pygments.lexer as lexer
>  import pygments.formatters as formatters
> +import pygments.token as token
> +import pygments.style as style
>  pygmentspresent = True
>  difflexer = lexers.DiffLexer()
>  terminal256formatter = formatters.Terminal256Formatter()
>  except ImportError:
>  pass
>  
> +if pygmentspresent:
> +class TestRunnerStyle(style.Style):
> +default_style = ""
> +skipped = token.string_to_tokentype("Token.Generic.Skipped")
> +failed = token.string_to_tokentype("Token.Generic.Failed")
> +error = token.string_to_tokentype("Token.Generic.Error")
> +skippedname = token.string_to_tokentype("Token.Generic.SName")
> +failedname = token.string_to_tokentype("Token.Generic.FName")
> +styles = {
> +skipped: '#e5e5e5',
> +skippedname: '#00',
> +failed:  '#7f',
> +failedname:  '#ff',
> +}
> +
> +class TestRunnerLexer(lexer.RegexLexer):
> +tokens = {
> +'root': [
> +(r'^Skipped', token.Generic.Skipped, 'skipped'),
> +(r'^Failed ', token.Generic.Failed, 'failed'),
> +(r'^ERROR: ', token.Generic.Failed, 'failed'),
> +],
> +'skipped': [
> +(r'[\w-]+\.t', token.Generic.SName),
> +(r':.*', token.Generic.Skipped),
> +],
> +'failed': [
> +(r'[\w-]+\.t', token.Generic.FName),
> +(r'(:| ).*', token.Generic.Failed),
> +]
> +}
> +
>  if sys.version_info > (3, 5, 0):
>  PYTHON3 = True
>  xrange = range # we use xrange in one place, and we'd rather not use 
> range
> @@ -1586,7 +1621,14 @@
>  self.stream.write('t')
>  else:
>  if not self._options.nodiff:
> -self.stream.write('\nERROR: %s output changed\n' % 
> test)
> +formatted = '\nERROR: %s output changed\n' % test
> +if self.color:
> +formatted = pygments.highlight(
> +formatted,
> +TestRunnerLexer(),
> +formatters.Terminal256Formatter(
> +style=TestRunnerStyle))
> +self.stream.write(formatted)
>  self.stream.write('!')
>  
>  self.stream.flush()
> @@ -1988,9 +2030,23 @@
>  
>  if not self._runner.options.noskips:
>  for test, msg in result.skipped:
> -self.stream.writeln('Skipped %s: %s' % (test.name, msg))
> +formatted = 'Skipped %s: %s' % (test.name, msg)
> +if result.color:
> +formatted = pygments.highlight(
> +formatted,
> +TestRunnerLexer(),
> +formatters.Terminal256Formatter(
> +
> style=TestRunnerStyle)).strip("\n")
> +self.stream.writeln(formatted)
>  for test, msg in result.failures:
> -self.stream.writeln('Failed %s: %s' % (test.name, msg))
> +formatted = 'Failed %s: %s' % (test.name, msg)
> +if result.color:
> +formatted = pygments.highlight(
> +formatted,
> +TestRunnerLexer(),
> +formatters.Terminal256Formatter(
> +style=TestRunnerStyle)).strip("\n")

Perhaps these pygments objects should be instantiated only once, because
pygments is slow. 20436925e080

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


D231: httppeer: add support for httppostargs when we're sending a file

2017-08-21 Thread yuja (Yuya Nishihara)
yuja added inline comments.

INLINE COMMENTS

> httppeer.py:105
> +def read(self, amt=None):
> +if amt <= 0:
> +return ''.join(f.read() for f in self._fileobjs)

Just nits:

- `read(0)` should return an empty string.
- `None <= 0` is TypeError on Python 3.

> httppeer.py:223
> +argsio.length = len(strargs)
> +data = _multifile(argsio, data)
> +headers['X-HgArgs-Post'] = len(strargs)

Does this mean `data` must have `length` attribute if it isn't
a string? A plain file object has no such attribute.

REPOSITORY
  rHG Mercurial

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

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


D454: releasenotes: view admonition titles using -l flag

2017-08-21 Thread rishabhmadan96 (Rishabh Madan)
rishabhmadan96 updated this revision to Diff 1123.
rishabhmadan96 edited the summary of this revision.
rishabhmadan96 retitled this revision from "releasenotes: view admonition 
titles using -a flag" to "releasenotes: view admonition titles using -l flag".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D454?vs=1106=1123

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

AFFECTED FILES
  hgext/releasenotes.py
  tests/test-releasenotes-formatting.t

CHANGE DETAILS

diff --git a/tests/test-releasenotes-formatting.t 
b/tests/test-releasenotes-formatting.t
--- a/tests/test-releasenotes-formatting.t
+++ b/tests/test-releasenotes-formatting.t
@@ -378,3 +378,15 @@
   
   * Adds a new feature.
 
+  $ cd ..
+
+Usage of --list flag
+
+  $ hg init relnotes-list
+  $ cd relnotes-list
+  $ hg releasenotes -l
+  feature: New Features
+  bc: Backwards Compatibility Changes
+  fix: Bug Fixes
+  perf: Performance Improvements
+  api: API Changes
diff --git a/hgext/releasenotes.py b/hgext/releasenotes.py
--- a/hgext/releasenotes.py
+++ b/hgext/releasenotes.py
@@ -242,6 +242,10 @@
 read('.hgreleasenotes')
 return p['sections']
 
+def _getadmonitionlist(ui, sections):
+for section in sections._sections:
+ui.write(_(str(section[0]) + ": " + section[1] + "\n"))
+
 def parsenotesfromrevisions(repo, directives, revs):
 notes = parsedreleasenotes()
 
@@ -432,9 +436,11 @@
 return '\n'.join(lines)
 
 @command('releasenotes',
-[('r', 'rev', '', _('revisions to process for release notes'), _('REV'))],
-_('[-r REV] FILE'))
-def releasenotes(ui, repo, file_, rev=None):
+[('r', 'rev', '', _('revisions to process for release notes'), _('REV')),
+('l', 'list', False, _('list the available admonitions with their title'),
+None)],
+_('hg releasenotes [-r REV] FILE'))
+def releasenotes(ui, repo, file_=None, **opts):
 """parse release notes from commit messages into an output file
 
 Given an output file and set of revisions, this command will parse commit
@@ -511,6 +517,10 @@
 release note after it has been added to the release notes file.
 """
 sections = releasenotessections(ui, repo)
+if opts.get('list'):
+return _getadmonitionlist(ui, sections)
+
+rev = opts.get('rev')
 
 revs = scmutil.revrange(repo, [rev or 'not public()'])
 incoming = parsenotesfromrevisions(repo, sections.names(), revs)



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


Re: [PATCH 6 of 9 V3] template: compute user in obsfateusers

2017-08-21 Thread Boris Feld
On Mon, 2017-08-21 at 12:55 +0200, Denis Laxalde wrote:
> Boris Feld a écrit :
> > # HG changeset patch
> > # User Boris Feld 
> > # Date 1499088840 -7200
> > #  Mon Jul 03 15:34:00 2017 +0200
> > # Node ID 2fee3b06f7b09f35dcfa312b645cf94090c11fb9
> > # Parent  66a2b0407c8cffedfae4897bd7a2f0e2d6a22363
> > # EXP-Topic obsfatetemplate
> > template: compute user in obsfateusers
> > 
> > Extract, deduplicate users informations from obs markers in order
> > to display
> > them.
> > 
> > Print all users for the moment, we might want to display users only
> > in verbose
> > mode later.
> > 
> > diff -r 66a2b0407c8c -r 2fee3b06f7b0 mercurial/obsutil.py
> > --- a/mercurial/obsutil.py  Mon Jul 03 15:33:27 2017 +0200
> > +++ b/mercurial/obsutil.py  Mon Jul 03 15:34:00 2017 +0200
> > @@ -579,6 +579,18 @@
> >   verb = 'split'
> >   return {'verb': verb}
> >   
> > +def _successorsetusers(successorset, markers):
> > +""" Returns a sorted list of markers users without duplicates
> > +"""
> > +if not markers:
> > +return {}
> > +
> > +# Check that user is present in meta
> > +markersmeta = [dict(m[3]) for m in markers]
> > +users = set(meta.get('user') for meta in markersmeta if
> > meta.get('user'))
> > +
> > +return {'users': sorted(users)}
> 
> "users" set might be empty, do we want an empty dict instead in this
> case?

I think we want to distinguish the case where we don't have any marker
(empty dict) from the case markers are missing users information (empty
'users' list) which shouldn't be frequent.

We could also returns directly the users, the dict is an artifact of
the previous version of this series.

> 
> > +
> >   def successorsandmarkers(repo, ctx):
> >   """compute the raw data needed for computing obsfate
> >   Returns a list of dict, one dict per successors set
> > diff -r 66a2b0407c8c -r 2fee3b06f7b0 mercurial/templater.py
> > --- a/mercurial/templater.pyMon Jul 03 15:33:27 2017 +0200
> > +++ b/mercurial/templater.pyMon Jul 03 15:34:00 2017 +0200
> > @@ -859,6 +859,24 @@
> >   
> >   return obsutil._successorsetverb(successors, markers)['verb']
> >   
> > +@templatefunc('obsfateusers(successors, markers)')
> > +def obsfateusers(context, mapping, args):
> > +""" Compute obsfate related information based on successors
> > and markers
> > +"""
> > +successors = evalfuncarg(context, mapping, args[0])
> > +markers = evalfuncarg(context, mapping, args[1])
> > +data = obsutil._successorsetusers(successors, markers)
> > +
> > +_hybrid = templatekw._hybrid
> > +
> > +def makemap(x):
> > +return x
> > +
> > +def joinfmt(d):
> > +return d
> > +
> > +return _hybrid(None, [data], makemap, joinfmt)
> > +
> >   @templatefunc('relpath(path)')
> >   def relpath(context, mapping, args):
> >   """Convert a repository-absolute path into a filesystem path
> > relative to
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D454: releasenotes: view admonition titles using -a flag

2017-08-21 Thread rishabhmadan96 (Rishabh Madan)
rishabhmadan96 added inline comments.

INLINE COMMENTS

> pulkit wrote in releasenotes.py:475
> I am not sure whether `-a` is the best choice of flag. Maybe we can have `-l` 
> and `--list`.
> 
> Also the help can be improved to "list the available admonitions with their 
> title".

`--list` sounds good to me. I'll make the changes.

REPOSITORY
  rHG Mercurial

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

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


Re: [PATCH 1 of 9 V3] obsolete: introduce a _succs class

2017-08-21 Thread Boris Feld
On Mon, 2017-08-21 at 12:45 +0200, Denis Laxalde wrote:
> Boris Feld a écrit :
> > # HG changeset patch
> > # User Boris Feld 
> > # Date 1499036035 -7200
> > #  Mon Jul 03 00:53:55 2017 +0200
> > # Node ID 328789121fa66b99c50ffa2fb139df700cf9fdc8
> > # Parent  3cfc9070245fbaa8c4c010327f24d579a416370f
> > # EXP-Topic obsfatetemplate
> > obsolete: introduce a _succs class
> > 
> > It will be useful later when we will be adding markers to _succs in
> > order to
> > represent a successorset with the list of markers from the root to
> > each
> > successors sets. This information will be needed for the obsfate
> > template I will
> > introduce.
> > 
> > Makes it a subclass of list so all callers will continue to work.
> > 
> > diff -r 3cfc9070245f -r 328789121fa6 mercurial/obsutil.py
> > --- a/mercurial/obsutil.py  Wed Aug 16 10:44:06 2017 -0700
> > +++ b/mercurial/obsutil.py  Mon Jul 03 00:53:55 2017 +0200
> > @@ -327,6 +327,9 @@
> >   obsoleted.add(rev)
> >   return obsoleted
> >   
> > +class _succs(list):
> > +"""small class to represent a successors with some metadata
> > about it"""
> > +
> >   def successorssets(repo, initialnode, closest=False, cache=None):
> >   """Return set of all latest successors of initial nodes
> >   
> > @@ -445,11 +448,11 @@
> >   # case (2): end of walk.
> >   if current in repo:
> >   # We have a valid successors.
> > -cache[current] = [(current,)]
> > +cache[current] = [_succs((current,))]
> >   else:
> >   # Final obsolete version is unknown locally.
> >   # Do not count that as a valid successors
> > -cache[current] = []
> > +cache[current] = _succs()
> 
> While equivalent by value (at this point), it seems to me that this
> should be kept as an empty list in "else" case (to keep
> `type(cache[current]) == list`).

You are right, cache values type should be list. I've fixed this
specific line and another for cycle-breaking (just below). It will be
part of a V4.

> 
> >   else:
> >   # cases (3) and (4)
> >   #
> > @@ -487,7 +490,7 @@
> >   if suc not in cache:
> >   if suc in stackedset:
> >   # cycle breaking
> > -cache[suc] = []
> > +cache[suc] = _succs()
> >   else:
> >   # case (3) If we have not computed
> > successors sets
> >   # of one of those successors we add
> > it to the
> > @@ -521,13 +524,13 @@
> >   succssets = []
> >   for mark in sorted(succmarkers[current]):
> >   # successors sets contributed by this marker
> > -markss = [[]]
> > +markss = [_succs()]
> >   for suc in mark[1]:
> >   # cardinal product with previous
> > successors
> >   productresult = []
> >   for prefix in markss:
> >   for suffix in cache[suc]:
> > -newss = list(prefix)
> > +newss = _succs(prefix)
> >   for part in suffix:
> >   # do not duplicated entry in
> > successors set
> >   # first entry wins.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 4 of 6] i18n: use saved object to get actual function information if available

2017-08-21 Thread Yuya Nishihara
On Wed, 16 Aug 2017 01:19:04 +0900, FUJIWARA Katsunori wrote:
> # HG changeset patch
> # User FUJIWARA Katsunori 
> # Date 1502792844 -32400
> #  Tue Aug 15 19:27:24 2017 +0900
> # Node ID b6dd19c795147e675b9caf58383b6cafd3f03534
> # Parent  1d204d17d51eb143f1ef66426cec1831cd8c93bf
> # Available At https://bitbucket.org/foozy/mercurial-wip
> #  hg pull https://bitbucket.org/foozy/mercurial-wip -r 
> b6dd19c79514
> # EXP-Topic i18n-fix-update-pot-issues
> i18n: use saved object to get actual function information if available
> 
> To list up available compression types instead of
> ".. bundlecompressionmarker" in "hg help bundlespec" output, proxy
> object "docobject" is used, because:
> 
> - current online help system requires that __doc__ of registered
>   object (maybe, function) is already well formatted in reST syntax
> 
> - bundletype() method of compressionengine classes is used to list up
>   available compression types, but
> 
> - __doc__ of bundletype() object (= "instancemethod") is read-only

Just curious. Any reason why we can't make the bundletype.__doc__ statically
formatted?
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D454: releasenotes: view admonition titles using -a flag

2017-08-21 Thread pulkit (Pulkit Goyal)
pulkit requested changes to this revision.
pulkit added a comment.
This revision now requires changes to proceed.


  The patch in general looks good to me. I have some inline comments.

INLINE COMMENTS

> releasenotes.py:278
>  
> +def getadmonitionlist(ui, sections):
> +for section in sections._sections:

Generally we add a '_' before an internal function. Since you need to resend 
because you need to rebase, can you change the function name to 
`_getadmonitionlist`. Also it will be extremely great if you send a patch 
documenting the functions in the `releasenotes.py` file.

> releasenotes.py:475
> +_('REV')),
> +('a', 'admonition', False, _('returns admonition and its title'), None)],
>  _('hg releasenotes [-r REV] [-c] FILE'))

I am not sure whether `-a` is the best choice of flag. Maybe we can have `-l` 
and `--list`.

Also the help can be improved to "list the available admonitions with their 
title".

> test-releasenotes-formatting.t:409
>Invalid admonition 'fixes' present in changeset 0e7130d2705c
>(did you mean fix?)
> +

The above lines were added in https://phab.mercurial-scm.org/D368 which is not 
yet pushed. So can you rebase this patch and resend so that it can be pushed 
independently.

REPOSITORY
  rHG Mercurial

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

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


D358: copytrace: move fb extension to core under flag experimental.fastcopytrace

2017-08-21 Thread pulkit (Pulkit Goyal)
pulkit added a comment.


  In https://phab.mercurial-scm.org/D358#7173, @quark wrote:
  
  > For config options, I think it's cleaner if we can unify them:
  >
  >   experimental.copytrace = disable | default | fast
  >   
  >
  > - `disable`: no copy tracing
  > - `default`: old copy tracing algorithm
  > - `fast`: this algorithm
  >
  >   I'm fine with leaving `fastcopytrace.sourcecommitlimit` config options. 
But if we do want to not introduce them, they could be also folded into 
`experimental.copytrace` option, like 
`fast:sourcecommitlimit=100,maxmovescandidatestocheck=200`.
  
  
  I like the idea of unifying the config, but I was thinking to add a 
`copytrace` section as there are couple of more flags introduced by copytracing 
during amend namely `amendcopytrace` and `amendcopytracelimit`. (This is when 
if we don't want to leave `sourcecommitlimit` and `maxmovescandidatestocheck` 
options).
  If we don't want to introduce these limiting flags, then we can plug the 
existing things into `experimental` section only.
  
  Also after this and copytracing while amend patches (not send yet) get in, I 
am thinking to have `hg help -k copytrace` to document these things so that 
user can understand them.

REPOSITORY
  rHG Mercurial

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

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


D461: morestatus: check whether the conflict message is None before printing

2017-08-21 Thread pulkit (Pulkit Goyal)
pulkit created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  There are cases like bisect when the conflict message can be None. So we make
  sure that we don't print None in that case.
  
  Thanks to Martin for catching this.

REPOSITORY
  rHG Mercurial

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

AFFECTED FILES
  mercurial/cmdutil.py
  tests/test-bisect.t

CHANGE DETAILS

diff --git a/tests/test-bisect.t b/tests/test-bisect.t
--- a/tests/test-bisect.t
+++ b/tests/test-bisect.t
@@ -187,7 +187,6 @@
   $ hg status -v
   # The repository is in an unfinished *bisect* state.
   
-  None
   # To mark the changeset good:hg bisect --good
   # To mark the changeset bad: hg bisect --bad
   # To abort:  hg bisect --reset
diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -673,7 +673,8 @@
 statemsg = _('The repository is in an unfinished *%s* state.') % state
 fm.write('statemsg', '%s\n',  _commentlines(statemsg), label=label)
 conmsg = _conflictsmsg(repo)
-fm.write('conflictsmsg', '%s\n', conmsg, label=label)
+if conmsg:
+fm.write('conflictsmsg', '%s\n', conmsg, label=label)
 if helpfulmsg:
 helpmsg = helpfulmsg()
 fm.write('helpmsg', '%s\n', helpmsg, label=label)



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


Re: [PATCH 8 of 9 V3] template: better prune support in obsfate

2017-08-21 Thread Denis Laxalde

Boris Feld a écrit :

# HG changeset patch
# User Boris Feld 
# Date 1499096336 -7200
#  Mon Jul 03 17:38:56 2017 +0200
# Node ID 7cb7e67addd11cdbecea49ec707e3e9b30bb8677
# Parent  faad6d683f7a30996007116d296df9ebf853c44d
# EXP-Topic obsfatetemplate
template: better prune support in obsfate

successorssets don't returns good results for pruned commit, add a workaround
for simple cases.

A proper fix would require a large rework of successorssets algorithm, I will
send a separate series for this refactoring.

diff -r faad6d683f7a -r 7cb7e67addd1 mercurial/obsutil.py
--- a/mercurial/obsutil.py  Mon Jul 03 15:34:10 2017 +0200
+++ b/mercurial/obsutil.py  Mon Jul 03 17:38:56 2017 +0200
@@ -614,8 +614,32 @@
  
  ssets = successorssets(repo, ctx.node(), closest=True)
  
+# closestsuccessors returns an empty list for pruned revisions, remap it

+# into a list containing en empty list for future processing


typo: "an" empty list


+if ssets == []:
+ssets = [[]]
+
+# Try to recover pruned markers
+succsmap = repo.obsstore.successors
+fullsuccessorsets = [] # successor set + markers
+for sset in ssets:
+if sset:
+fullsuccessorsets.append(sset)
+else:
+# XXX we do not catch all prune markers (eg rewritten then pruned)
+# (fix me later)
+foundany = False
+for mark in succsmap.get(ctx.node(), ()):
+if not mark[1]:
+foundany = True
+sset = _succs()
+sset.markers.add(mark)
+fullsuccessorsets.append(sset)
+if not foundany:
+fullsuccessorsets.append(_succs())
+
  values = []
-for sset in ssets:
+for sset in fullsuccessorsets:
  values.append({'successors': sset, 'markers': sset.markers})
  
  return values


Maybe I'm not familiar enough with these things, but I can't figure out
what the algorithm is doing. Would you mind explaining it in a comment?
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 6 of 9 V3] template: compute user in obsfateusers

2017-08-21 Thread Denis Laxalde

Boris Feld a écrit :

# HG changeset patch
# User Boris Feld 
# Date 1499088840 -7200
#  Mon Jul 03 15:34:00 2017 +0200
# Node ID 2fee3b06f7b09f35dcfa312b645cf94090c11fb9
# Parent  66a2b0407c8cffedfae4897bd7a2f0e2d6a22363
# EXP-Topic obsfatetemplate
template: compute user in obsfateusers

Extract, deduplicate users informations from obs markers in order to display
them.

Print all users for the moment, we might want to display users only in verbose
mode later.

diff -r 66a2b0407c8c -r 2fee3b06f7b0 mercurial/obsutil.py
--- a/mercurial/obsutil.py  Mon Jul 03 15:33:27 2017 +0200
+++ b/mercurial/obsutil.py  Mon Jul 03 15:34:00 2017 +0200
@@ -579,6 +579,18 @@
  verb = 'split'
  return {'verb': verb}
  
+def _successorsetusers(successorset, markers):

+""" Returns a sorted list of markers users without duplicates
+"""
+if not markers:
+return {}
+
+# Check that user is present in meta
+markersmeta = [dict(m[3]) for m in markers]
+users = set(meta.get('user') for meta in markersmeta if meta.get('user'))
+
+return {'users': sorted(users)}


"users" set might be empty, do we want an empty dict instead in this case?


+
  def successorsandmarkers(repo, ctx):
  """compute the raw data needed for computing obsfate
  Returns a list of dict, one dict per successors set
diff -r 66a2b0407c8c -r 2fee3b06f7b0 mercurial/templater.py
--- a/mercurial/templater.pyMon Jul 03 15:33:27 2017 +0200
+++ b/mercurial/templater.pyMon Jul 03 15:34:00 2017 +0200
@@ -859,6 +859,24 @@
  
  return obsutil._successorsetverb(successors, markers)['verb']
  
+@templatefunc('obsfateusers(successors, markers)')

+def obsfateusers(context, mapping, args):
+""" Compute obsfate related information based on successors and markers
+"""
+successors = evalfuncarg(context, mapping, args[0])
+markers = evalfuncarg(context, mapping, args[1])
+data = obsutil._successorsetusers(successors, markers)
+
+_hybrid = templatekw._hybrid
+
+def makemap(x):
+return x
+
+def joinfmt(d):
+return d
+
+return _hybrid(None, [data], makemap, joinfmt)
+
  @templatefunc('relpath(path)')
  def relpath(context, mapping, args):
  """Convert a repository-absolute path into a filesystem path relative to

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


Re: [PATCH 1 of 9 V3] obsolete: introduce a _succs class

2017-08-21 Thread Denis Laxalde

Boris Feld a écrit :

# HG changeset patch
# User Boris Feld 
# Date 1499036035 -7200
#  Mon Jul 03 00:53:55 2017 +0200
# Node ID 328789121fa66b99c50ffa2fb139df700cf9fdc8
# Parent  3cfc9070245fbaa8c4c010327f24d579a416370f
# EXP-Topic obsfatetemplate
obsolete: introduce a _succs class

It will be useful later when we will be adding markers to _succs in order to
represent a successorset with the list of markers from the root to each
successors sets. This information will be needed for the obsfate template I will
introduce.

Makes it a subclass of list so all callers will continue to work.

diff -r 3cfc9070245f -r 328789121fa6 mercurial/obsutil.py
--- a/mercurial/obsutil.py  Wed Aug 16 10:44:06 2017 -0700
+++ b/mercurial/obsutil.py  Mon Jul 03 00:53:55 2017 +0200
@@ -327,6 +327,9 @@
  obsoleted.add(rev)
  return obsoleted
  
+class _succs(list):

+"""small class to represent a successors with some metadata about it"""
+
  def successorssets(repo, initialnode, closest=False, cache=None):
  """Return set of all latest successors of initial nodes
  
@@ -445,11 +448,11 @@

  # case (2): end of walk.
  if current in repo:
  # We have a valid successors.
-cache[current] = [(current,)]
+cache[current] = [_succs((current,))]
  else:
  # Final obsolete version is unknown locally.
  # Do not count that as a valid successors
-cache[current] = []
+cache[current] = _succs()


While equivalent by value (at this point), it seems to me that this
should be kept as an empty list in "else" case (to keep
`type(cache[current]) == list`).


  else:
  # cases (3) and (4)
  #
@@ -487,7 +490,7 @@
  if suc not in cache:
  if suc in stackedset:
  # cycle breaking
-cache[suc] = []
+cache[suc] = _succs()
  else:
  # case (3) If we have not computed successors sets
  # of one of those successors we add it to the
@@ -521,13 +524,13 @@
  succssets = []
  for mark in sorted(succmarkers[current]):
  # successors sets contributed by this marker
-markss = [[]]
+markss = [_succs()]
  for suc in mark[1]:
  # cardinal product with previous successors
  productresult = []
  for prefix in markss:
  for suffix in cache[suc]:
-newss = list(prefix)
+newss = _succs(prefix)
  for part in suffix:
  # do not duplicated entry in successors 
set
  # first entry wins.

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


[Bug 5664] New: hglib should allow prompt handling for all commands, and include --noninteractive when no prompt handler is specified

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

Bug ID: 5664
   Summary: hglib should allow prompt handling for all commands,
and include --noninteractive when no prompt handler is
specified
   Product: Mercurial
   Version: default branch
  Hardware: All
OS: All
Status: UNCONFIRMED
  Severity: feature
  Priority: wish
 Component: hglib
  Assignee: bugzi...@mercurial-scm.org
  Reporter: gabor.stefa...@nng.com
CC: mercurial-devel@mercurial-scm.org

Extensions, hooks and HTTP authentication can cause prompts to appear in
(almost) any command. Right now, when this happens in python-hglib, it renders
the session unusable in a rather unclean way (see bug 5516).

To make matters worse, hglib doesn't allow passing a prompt handler to most
commands, and doesn't expose the --noninteractive switch.

We should allow a prompt handler to be passed to all commands (especially those
that deal with the network), and if none is passed, set --noninteractive.

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


[PATCH 4 of 9 V3] template: add minimal obsfate template function

2017-08-21 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1502987171 -7200
#  Thu Aug 17 18:26:11 2017 +0200
# Node ID 84a35f753f9ab500902f5c06ce3845ce85e5b5a9
# Parent  89a659e236b906e58a48dfed8a4e3b89372d7184
# EXP-Topic obsfatetemplate
template: add minimal obsfate template function

The goal of this series is to have templates capable of displaying the
evolution of a changeset in a clean and human-readable way.

Add the succsandmarkers template return successors and markers so it can be
used separately like this:

> {succsandmarkers % "{get(succsandmarkers, "markers")|json};"}

The following patches will add template functions that takes successors and
markers as inputs and compute various obsfate fields from them.

diff -r 89a659e236b9 -r 84a35f753f9a mercurial/obsutil.py
--- a/mercurial/obsutil.py  Mon Jul 03 03:27:58 2017 +0200
+++ b/mercurial/obsutil.py  Thu Aug 17 18:26:11 2017 +0200
@@ -567,3 +567,18 @@
 final.reverse() # put small successors set first
 cache[current] = final
 return cache[initialnode]
+
+def successorsandmarkers(repo, ctx):
+"""compute the raw data needed for computing obsfate
+Returns a list of dict, one dict per successors set
+"""
+if not ctx.obsolete():
+return None
+
+ssets = successorssets(repo, ctx.node(), closest=True)
+
+values = []
+for sset in ssets:
+values.append({'successors': sset, 'markers': sset.markers})
+
+return values
diff -r 89a659e236b9 -r 84a35f753f9a mercurial/templatekw.py
--- a/mercurial/templatekw.py   Mon Jul 03 03:27:58 2017 +0200
+++ b/mercurial/templatekw.py   Thu Aug 17 18:26:11 2017 +0200
@@ -18,6 +18,7 @@
 encoding,
 error,
 hbisect,
+node as nodemod,
 obsutil,
 patch,
 pycompat,
@@ -662,6 +663,47 @@
 return _hybrid(gen(data), data, lambda x: {'successorset': x},
lambda d: d["successorset"])
 
+@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 = []
+
+hex = nodemod.hex
+
+data = []
+for i in values:
+# Format successors
+successors = i['successors']
+
+successors = [hex(n) for n in successors]
+successors = _hybrid(None, successors,
+ lambda x: {'ctx': repo[x], 'revcache': {}},
+ lambda d: _formatrevnode(d['ctx']))
+
+# Format markers
+finalmarkers = []
+for m in i['markers']:
+hexprec = hex(m[0])
+hexsucs = tuple(hex(n) for n in m[1])
+hexparents = None
+if m[5] is not None:
+hexparents = tuple(hex(n) for n in m[5])
+newmarker = (hexprec, hexsucs) + m[2:5] + (hexparents,) + m[6:]
+finalmarkers.append(newmarker)
+
+data.append({'successors': successors, 'markers': finalmarkers})
+
+f = _showlist('succsandmarkers', data, args)
+return _hybrid(f, data, lambda x: x, lambda d: d)
+
 @templatekeyword('p1rev')
 def showp1rev(repo, ctx, templ, **args):
 """Integer. The repository-local revision number of the changeset's
diff -r 89a659e236b9 -r 84a35f753f9a tests/test-obsmarker-template.t
--- a/tests/test-obsmarker-template.t   Mon Jul 03 03:27:58 2017 +0200
+++ b/tests/test-obsmarker-template.t   Thu Aug 17 18:26:11 2017 +0200
@@ -11,6 +11,9 @@
   > publish=False
   > [experimental]
   > stabilization=all
+  > [templates]
+  > obsfatesuccessors = " as {join(successors, ", ")}"
+  > obsfate = "rewritten{obsfatesuccessors}; "
   > [alias]
   > tlog = log -G -T '{node|short}\
   > {if(predecessors, "\n  Predecessors: {predecessors}")}\
@@ -20,6 +23,8 @@
   > {if(successorssets, "\n  Successors: {successorssets}")}\
   > {if(successorssets, "\n  multi-line: {join(successorssets, "\n  
multi-line: ")}")}\
   > {if(successorssets, "\n  json: {successorssets|json}")}\n'
+  > fatelog = log -G -T '{node|short}\n{if(succsandmarkers, "  Obsfate: 
{succsandmarkers % "{obsfate}"} \n" )}'
+  > fatelogjson = log -G -T '{node|short}\n{if(succsandmarkers, "  Obsfate: 
{succsandmarkers|json}\n")}'
   > EOF
 
 Test templates on amended commit
@@ -33,8 +38,8 @@
   $ mkcommit ROOT
   $ mkcommit A0
   $ echo 42 >> A0
-  $ hg commit --amend -m "A1"
-  $ hg commit --amend -m "A2"
+  $ HGUSER=test1 hg commit --amend -m "A1" --config 
devel.default-date="1234567890 0"
+  $ HGUSER=test2 hg commit --amend -m "A2" --config 
devel.default-date="987654321 0"
 
   $ hg log --hidden -G
   @  changeset:   4:d004c8f274b9
@@ -83,6 +88,27 @@
   |  json: [["d004c8f274b9ec480a47a93c10dac5eee63adb78"]]
   o  ea207398892e
   
+  $ hg fatelog -q 

[PATCH 8 of 9 V3] template: better prune support in obsfate

2017-08-21 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499096336 -7200
#  Mon Jul 03 17:38:56 2017 +0200
# Node ID 7cb7e67addd11cdbecea49ec707e3e9b30bb8677
# Parent  faad6d683f7a30996007116d296df9ebf853c44d
# EXP-Topic obsfatetemplate
template: better prune support in obsfate

successorssets don't returns good results for pruned commit, add a workaround
for simple cases.

A proper fix would require a large rework of successorssets algorithm, I will
send a separate series for this refactoring.

diff -r faad6d683f7a -r 7cb7e67addd1 mercurial/obsutil.py
--- a/mercurial/obsutil.py  Mon Jul 03 15:34:10 2017 +0200
+++ b/mercurial/obsutil.py  Mon Jul 03 17:38:56 2017 +0200
@@ -614,8 +614,32 @@
 
 ssets = successorssets(repo, ctx.node(), closest=True)
 
+# closestsuccessors returns an empty list for pruned revisions, remap it
+# into a list containing en empty list for future processing
+if ssets == []:
+ssets = [[]]
+
+# Try to recover pruned markers
+succsmap = repo.obsstore.successors
+fullsuccessorsets = [] # successor set + markers
+for sset in ssets:
+if sset:
+fullsuccessorsets.append(sset)
+else:
+# XXX we do not catch all prune markers (eg rewritten then pruned)
+# (fix me later)
+foundany = False
+for mark in succsmap.get(ctx.node(), ()):
+if not mark[1]:
+foundany = True
+sset = _succs()
+sset.markers.add(mark)
+fullsuccessorsets.append(sset)
+if not foundany:
+fullsuccessorsets.append(_succs())
+
 values = []
-for sset in ssets:
+for sset in fullsuccessorsets:
 values.append({'successors': sset, 'markers': sset.markers})
 
 return values
diff -r faad6d683f7a -r 7cb7e67addd1 tests/test-obsmarker-template.t
--- a/tests/test-obsmarker-template.t   Mon Jul 03 15:34:10 2017 +0200
+++ b/tests/test-obsmarker-template.t   Mon Jul 03 17:38:56 2017 +0200
@@ -12,7 +12,7 @@
   > [experimental]
   > stabilization=all
   > [templates]
-  > obsfatesuccessors = " as {join(successors, ", ")}"
+  > obsfatesuccessors = "{if(successors, " as ")}{join(successors, ", ")}"
   > obsfateverb = "{obsfateverb(successors, markers)}"
   > obsfateuserstmpl = "{if(users, " by {join(users, ", ")}")}"
   > obsfateusers = "{obsfateusers(successors, markers) % "{obsfateuserstmpl}"}"
@@ -167,7 +167,7 @@
   | @  a468dc9b3633
   |/ Obsfate: rewritten as 4:d004c8f274b9 by test2 (at 2001-04-19 04:25 
+);
   | x  f137d23bb3e1
-  | |
+  | |Obsfate: pruned by test1 (at 2009-02-13 23:31 +);
   | x  471f378eab4c
   |/ Obsfate: rewritten as 3:a468dc9b3633 by test1 (at 2009-02-13 23:31 
+);
   o  ea207398892e
@@ -216,7 +216,7 @@
   | x  a468dc9b3633
   |/ Obsfate: rewritten as 4:d004c8f274b9 by test2 (at 2001-04-19 04:25 
+);
   | x  f137d23bb3e1
-  | |
+  | |Obsfate: pruned by test1 (at 2009-02-13 23:31 +);
   | x  471f378eab4c
   |/ Obsfate: rewritten as 3:a468dc9b3633 by test1 (at 2009-02-13 23:31 
+);
   o  ea207398892e
@@ -227,7 +227,7 @@
   | x  a468dc9b3633
   |/ Obsfate: [{"markers": [["a468dc9b36338b14fdb7825f55ce3df4e71517ad", 
["d004c8f274b9ec480a47a93c10dac5eee63adb78"], 0, [["user", "test2"]], 
[987654321.0, 0], null]], "successors": 
["d004c8f274b9ec480a47a93c10dac5eee63adb78"]}]
   | x  f137d23bb3e1
-  | |
+  | |Obsfate: [{"markers": [["f137d23bb3e11dc1daeb6264fac9cb2433782e15", 
[], 0, [["user", "test1"]], [1234567890.0, 0], 
["471f378eab4c5e25f6c77f785b27c936efb22874"]]], "successors": []}]
   | x  471f378eab4c
   |/ Obsfate: [{"markers": [["471f378eab4c5e25f6c77f785b27c936efb22874", 
["a468dc9b36338b14fdb7825f55ce3df4e71517ad"], 0, [["user", "test1"]], 
[1234567890.0, 0], null]], "successors": 
["a468dc9b36338b14fdb7825f55ce3df4e71517ad"]}]
   o  ea207398892e
@@ -1220,7 +1220,7 @@
   o  f897c6137566
   |
   | @  471f378eab4c
-  |/
+  |/ Obsfate: pruned;
   o  ea207398892e
   
 
@@ -1637,11 +1637,11 @@
   
   $ hg fatelog
   @  471f378eab4c
-  |
+  |Obsfate: pruned by test (at 1970-01-01 00:00 +);
   o  ea207398892e
   
   $ hg fatelog -v
   @  471f378eab4c
-  |
+  |Obsfate: pruned by test (at 1970-01-01 00:00 +);
   o  ea207398892e
   
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 9 V3] obsolete: add an explicit '_succs.copy()' method

2017-08-21 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499044397 -7200
#  Mon Jul 03 03:13:17 2017 +0200
# Node ID 60a7a3ca1dae7dc99b8b018b4aefa24b74d3b149
# Parent  328789121fa66b99c50ffa2fb139df700cf9fdc8
# EXP-Topic obsfatetemplate
obsolete: add an explicit '_succs.copy()' method

Mimic the standard API for copying in the _succs class, it makes the code
slightly cleaner and will be needed later for copying markers at the same time
than copying the list content.

diff -r 328789121fa6 -r 60a7a3ca1dae mercurial/obsutil.py
--- a/mercurial/obsutil.py  Mon Jul 03 00:53:55 2017 +0200
+++ b/mercurial/obsutil.py  Mon Jul 03 03:13:17 2017 +0200
@@ -330,6 +330,9 @@
 class _succs(list):
 """small class to represent a successors with some metadata about it"""
 
+def copy(self):
+return _succs(self)
+
 def successorssets(repo, initialnode, closest=False, cache=None):
 """Return set of all latest successors of initial nodes
 
@@ -530,7 +533,7 @@
 productresult = []
 for prefix in markss:
 for suffix in cache[suc]:
-newss = _succs(prefix)
+newss = prefix.copy()
 for part in suffix:
 # do not duplicated entry in successors set
 # first entry wins.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 5 of 9 V3] template: compute verb in obsfateverb

2017-08-21 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499088807 -7200
#  Mon Jul 03 15:33:27 2017 +0200
# Node ID 66a2b0407c8cffedfae4897bd7a2f0e2d6a22363
# Parent  84a35f753f9ab500902f5c06ce3845ce85e5b5a9
# EXP-Topic obsfatetemplate
template: compute verb in obsfateverb

Add a template function obsfateverb which use the markers information to
compute a better obsfate verb.

The current logic behind the obsfate verb is simple for the moment:

- If the successorsets is empty, the changeset has been pruned, for example:

Obsfate: pruned

- If the successorsets length is 1, the changeset has been rewritten without
  divergence, for example:

Obsfate: rewritten as 2:337fec4d2edc, 3:f257fde29c7a

- If the successorsets length is more than 1, the changeset has diverged, for
  example:

Obsfate: split as 2:337fec4d2edc, 3:f257fde29c7a

As the divergence might occurs on a subset of successors, we might see some
successors twice:

Obsfate: split as 9:0b997eb7ceee, 5:dd800401bd8c, 10:eceed8f98ffc; split
as 8:b18bc8331526, 5:dd800401bd8c, 10:eceed8f98ffc

diff -r 84a35f753f9a -r 66a2b0407c8c mercurial/obsutil.py
--- a/mercurial/obsutil.py  Thu Aug 17 18:26:11 2017 +0200
+++ b/mercurial/obsutil.py  Mon Jul 03 15:33:27 2017 +0200
@@ -568,6 +568,17 @@
 cache[current] = final
 return cache[initialnode]
 
+def _successorsetverb(successorset, markers):
+""" Return the verb summarizing the successorset
+"""
+if not successorset:
+verb = 'pruned'
+elif len(successorset) == 1:
+verb = 'rewritten'
+else:
+verb = 'split'
+return {'verb': verb}
+
 def successorsandmarkers(repo, ctx):
 """compute the raw data needed for computing obsfate
 Returns a list of dict, one dict per successors set
diff -r 84a35f753f9a -r 66a2b0407c8c mercurial/templater.py
--- a/mercurial/templater.pyThu Aug 17 18:26:11 2017 +0200
+++ b/mercurial/templater.pyMon Jul 03 15:33:27 2017 +0200
@@ -18,6 +18,7 @@
 encoding,
 error,
 minirst,
+obsutil,
 parser,
 pycompat,
 registrar,
@@ -849,6 +850,15 @@
 func = lambda a, b: a % b
 return runarithmetic(context, mapping, (func, args[0], args[1]))
 
+@templatefunc('obsfateverb(successors, markers)')
+def obsfateverb(context, mapping, args):
+""" Compute obsfate related information based on successors and markers
+"""
+successors = evalfuncarg(context, mapping, args[0])
+markers = evalfuncarg(context, mapping, args[1])
+
+return obsutil._successorsetverb(successors, markers)['verb']
+
 @templatefunc('relpath(path)')
 def relpath(context, mapping, args):
 """Convert a repository-absolute path into a filesystem path relative to
diff -r 84a35f753f9a -r 66a2b0407c8c tests/test-obsmarker-template.t
--- a/tests/test-obsmarker-template.t   Thu Aug 17 18:26:11 2017 +0200
+++ b/tests/test-obsmarker-template.t   Mon Jul 03 15:33:27 2017 +0200
@@ -13,7 +13,8 @@
   > stabilization=all
   > [templates]
   > obsfatesuccessors = " as {join(successors, ", ")}"
-  > obsfate = "rewritten{obsfatesuccessors}; "
+  > obsfateverb = "{obsfateverb(successors, markers)}"
+  > obsfate = "{obsfateverb}{obsfatesuccessors}; "
   > [alias]
   > tlog = log -G -T '{node|short}\
   > {if(predecessors, "\n  Predecessors: {predecessors}")}\
@@ -318,7 +319,7 @@
   o  337fec4d2edc
   |
   | @  471597cad322
-  |/ Obsfate: rewritten as 2:337fec4d2edc, 3:f257fde29c7a;
+  |/ Obsfate: split as 2:337fec4d2edc, 3:f257fde29c7a;
   o  ea207398892e
   
   $ hg up f257fde29c7a
@@ -359,7 +360,7 @@
   o  337fec4d2edc
   |
   | x  471597cad322
-  |/ Obsfate: rewritten as 2:337fec4d2edc, 3:f257fde29c7a;
+  |/ Obsfate: split as 2:337fec4d2edc, 3:f257fde29c7a;
   o  ea207398892e
   
   $ hg fatelogjson --hidden
@@ -1528,7 +1529,7 @@
   o  dd800401bd8c
   |
   | x  9bd10a0775e4
-  |/ Obsfate: rewritten as 5:dd800401bd8c, 6:4a004186e638, 7:ba2ed02b0c9a;
+  |/ Obsfate: split as 5:dd800401bd8c, 6:4a004186e638, 7:ba2ed02b0c9a;
   o  f897c6137566
   |
   | x  0dec01379d3b
@@ -1603,7 +1604,7 @@
   o  dd800401bd8c
   |
   | @  9bd10a0775e4
-  |/ Obsfate: rewritten as 5:dd800401bd8c, 9:0b997eb7ceee, 
10:eceed8f98ffc; rewritten as 5:dd800401bd8c, 8:b18bc8331526, 10:eceed8f98ffc;
+  |/ Obsfate: split as 5:dd800401bd8c, 9:0b997eb7ceee, 10:eceed8f98ffc; 
split as 5:dd800401bd8c, 8:b18bc8331526, 10:eceed8f98ffc;
   o  f897c6137566
   |
   o  ea207398892e
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 7 of 9 V3] template: compute dates in obsfatedate

2017-08-21 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499088850 -7200
#  Mon Jul 03 15:34:10 2017 +0200
# Node ID faad6d683f7a30996007116d296df9ebf853c44d
# Parent  2fee3b06f7b09f35dcfa312b645cf94090c11fb9
# EXP-Topic obsfatetemplate
template: compute dates in obsfatedate

Extract the dates from obsmarkers. Compute the min and max date from the
obsmarker range list.

diff -r 2fee3b06f7b0 -r faad6d683f7a mercurial/obsutil.py
--- a/mercurial/obsutil.py  Mon Jul 03 15:34:00 2017 +0200
+++ b/mercurial/obsutil.py  Mon Jul 03 15:34:10 2017 +0200
@@ -591,6 +591,20 @@
 
 return {'users': sorted(users)}
 
+def _successorsetdates(successorset, markers):
+"""returns the max date and the min date of the markers list
+"""
+
+if not markers:
+return {}
+
+dates = [m[4] for m in markers]
+
+return {
+'min_date': min(dates),
+'max_date': max(dates)
+}
+
 def successorsandmarkers(repo, ctx):
 """compute the raw data needed for computing obsfate
 Returns a list of dict, one dict per successors set
diff -r 2fee3b06f7b0 -r faad6d683f7a mercurial/templater.py
--- a/mercurial/templater.pyMon Jul 03 15:34:00 2017 +0200
+++ b/mercurial/templater.pyMon Jul 03 15:34:10 2017 +0200
@@ -877,6 +877,22 @@
 
 return _hybrid(None, [data], makemap, joinfmt)
 
+@templatefunc('obsfatedate(successors, markers)')
+def obsfatedate(context, mapping, args):
+""" Compute obsfate related information based on successors and markers
+"""
+successors = evalfuncarg(context, mapping, args[0])
+markers = evalfuncarg(context, mapping, args[1])
+data = obsutil._successorsetdates(successors, markers)
+
+def makemap(x):
+return x
+
+def joinfmt(d):
+return d
+
+return templatekw._hybrid(None, [data], makemap, joinfmt)
+
 @templatefunc('relpath(path)')
 def relpath(context, mapping, args):
 """Convert a repository-absolute path into a filesystem path relative to
diff -r 2fee3b06f7b0 -r faad6d683f7a tests/test-obsmarker-template.t
--- a/tests/test-obsmarker-template.t   Mon Jul 03 15:34:00 2017 +0200
+++ b/tests/test-obsmarker-template.t   Mon Jul 03 15:34:10 2017 +0200
@@ -16,7 +16,9 @@
   > obsfateverb = "{obsfateverb(successors, markers)}"
   > obsfateuserstmpl = "{if(users, " by {join(users, ", ")}")}"
   > obsfateusers = "{obsfateusers(successors, markers) % "{obsfateuserstmpl}"}"
-  > obsfate = "{obsfateverb}{obsfatesuccessors}{obsfateusers}; "
+  > obsfatedatetmpl = "{if(max_date, "{ifeq(min_date, max_date, " (at 
{min_date|isodate})", " (between {min_date|isodate} and 
{max_date|isodate})")}")}"
+  > obsfatedate = "{obsfatedate(successors, markers) % "{obsfatedatetmpl}"}"
+  > obsfate = "{obsfateverb}{obsfatesuccessors}{obsfateusers}{obsfatedate}; "
   > [alias]
   > tlog = log -G -T '{node|short}\
   > {if(predecessors, "\n  Predecessors: {predecessors}")}\
@@ -95,21 +97,21 @@
   o  d004c8f274b9
   |
   | @  471f378eab4c
-  |/ Obsfate: rewritten as 4:d004c8f274b9 by test1, test2;
+  |/ Obsfate: rewritten as 4:d004c8f274b9 by test1, test2 (between 
2001-04-19 04:25 + and 2009-02-13 23:31 +);
   o  ea207398892e
   
   $ hg fatelog
   o  d004c8f274b9
   |
   | @  471f378eab4c
-  |/ Obsfate: rewritten as 4:d004c8f274b9 by test1, test2;
+  |/ Obsfate: rewritten as 4:d004c8f274b9 by test1, test2 (between 
2001-04-19 04:25 + and 2009-02-13 23:31 +);
   o  ea207398892e
   
   $ hg fatelog -v
   o  d004c8f274b9
   |
   | @  471f378eab4c
-  |/ Obsfate: rewritten as 4:d004c8f274b9 by test1, test2;
+  |/ Obsfate: rewritten as 4:d004c8f274b9 by test1, test2 (between 
2001-04-19 04:25 + and 2009-02-13 23:31 +);
   o  ea207398892e
   
   $ hg up 'desc(A1)' --hidden
@@ -132,7 +134,7 @@
   o  d004c8f274b9
   |
   | @  a468dc9b3633
-  |/ Obsfate: rewritten as 4:d004c8f274b9 by test2;
+  |/ Obsfate: rewritten as 4:d004c8f274b9 by test2 (at 2001-04-19 04:25 
+);
   o  ea207398892e
   
 Predecessors template should show all the predecessors as we force their 
display
@@ -163,11 +165,11 @@
   o  d004c8f274b9
   |
   | @  a468dc9b3633
-  |/ Obsfate: rewritten as 4:d004c8f274b9 by test2;
+  |/ Obsfate: rewritten as 4:d004c8f274b9 by test2 (at 2001-04-19 04:25 
+);
   | x  f137d23bb3e1
   | |
   | x  471f378eab4c
-  |/ Obsfate: rewritten as 3:a468dc9b3633 by test1;
+  |/ Obsfate: rewritten as 3:a468dc9b3633 by test1 (at 2009-02-13 23:31 
+);
   o  ea207398892e
   
 
@@ -212,11 +214,11 @@
   @  d004c8f274b9
   |
   | x  a468dc9b3633
-  |/ Obsfate: rewritten as 4:d004c8f274b9 by test2;
+  |/ Obsfate: rewritten as 4:d004c8f274b9 by test2 (at 2001-04-19 04:25 
+);
   | x  f137d23bb3e1
   | |
   | x  471f378eab4c
-  |/ Obsfate: rewritten as 3:a468dc9b3633 by test1;
+  |/ Obsfate: rewritten as 3:a468dc9b3633 by test1 (at 2009-02-13 23:31 
+);
   o  ea207398892e
   
   $ hg fatelogjson --hidden
@@ -320,7 +322,7 @@
   o  

[PATCH 6 of 9 V3] template: compute user in obsfateusers

2017-08-21 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499088840 -7200
#  Mon Jul 03 15:34:00 2017 +0200
# Node ID 2fee3b06f7b09f35dcfa312b645cf94090c11fb9
# Parent  66a2b0407c8cffedfae4897bd7a2f0e2d6a22363
# EXP-Topic obsfatetemplate
template: compute user in obsfateusers

Extract, deduplicate users informations from obs markers in order to display
them.

Print all users for the moment, we might want to display users only in verbose
mode later.

diff -r 66a2b0407c8c -r 2fee3b06f7b0 mercurial/obsutil.py
--- a/mercurial/obsutil.py  Mon Jul 03 15:33:27 2017 +0200
+++ b/mercurial/obsutil.py  Mon Jul 03 15:34:00 2017 +0200
@@ -579,6 +579,18 @@
 verb = 'split'
 return {'verb': verb}
 
+def _successorsetusers(successorset, markers):
+""" Returns a sorted list of markers users without duplicates
+"""
+if not markers:
+return {}
+
+# Check that user is present in meta
+markersmeta = [dict(m[3]) for m in markers]
+users = set(meta.get('user') for meta in markersmeta if meta.get('user'))
+
+return {'users': sorted(users)}
+
 def successorsandmarkers(repo, ctx):
 """compute the raw data needed for computing obsfate
 Returns a list of dict, one dict per successors set
diff -r 66a2b0407c8c -r 2fee3b06f7b0 mercurial/templater.py
--- a/mercurial/templater.pyMon Jul 03 15:33:27 2017 +0200
+++ b/mercurial/templater.pyMon Jul 03 15:34:00 2017 +0200
@@ -859,6 +859,24 @@
 
 return obsutil._successorsetverb(successors, markers)['verb']
 
+@templatefunc('obsfateusers(successors, markers)')
+def obsfateusers(context, mapping, args):
+""" Compute obsfate related information based on successors and markers
+"""
+successors = evalfuncarg(context, mapping, args[0])
+markers = evalfuncarg(context, mapping, args[1])
+data = obsutil._successorsetusers(successors, markers)
+
+_hybrid = templatekw._hybrid
+
+def makemap(x):
+return x
+
+def joinfmt(d):
+return d
+
+return _hybrid(None, [data], makemap, joinfmt)
+
 @templatefunc('relpath(path)')
 def relpath(context, mapping, args):
 """Convert a repository-absolute path into a filesystem path relative to
diff -r 66a2b0407c8c -r 2fee3b06f7b0 tests/test-obsmarker-template.t
--- a/tests/test-obsmarker-template.t   Mon Jul 03 15:33:27 2017 +0200
+++ b/tests/test-obsmarker-template.t   Mon Jul 03 15:34:00 2017 +0200
@@ -14,7 +14,9 @@
   > [templates]
   > obsfatesuccessors = " as {join(successors, ", ")}"
   > obsfateverb = "{obsfateverb(successors, markers)}"
-  > obsfate = "{obsfateverb}{obsfatesuccessors}; "
+  > obsfateuserstmpl = "{if(users, " by {join(users, ", ")}")}"
+  > obsfateusers = "{obsfateusers(successors, markers) % "{obsfateuserstmpl}"}"
+  > obsfate = "{obsfateverb}{obsfatesuccessors}{obsfateusers}; "
   > [alias]
   > tlog = log -G -T '{node|short}\
   > {if(predecessors, "\n  Predecessors: {predecessors}")}\
@@ -93,21 +95,21 @@
   o  d004c8f274b9
   |
   | @  471f378eab4c
-  |/ Obsfate: rewritten as 4:d004c8f274b9;
+  |/ Obsfate: rewritten as 4:d004c8f274b9 by test1, test2;
   o  ea207398892e
   
   $ hg fatelog
   o  d004c8f274b9
   |
   | @  471f378eab4c
-  |/ Obsfate: rewritten as 4:d004c8f274b9;
+  |/ Obsfate: rewritten as 4:d004c8f274b9 by test1, test2;
   o  ea207398892e
   
   $ hg fatelog -v
   o  d004c8f274b9
   |
   | @  471f378eab4c
-  |/ Obsfate: rewritten as 4:d004c8f274b9;
+  |/ Obsfate: rewritten as 4:d004c8f274b9 by test1, test2;
   o  ea207398892e
   
   $ hg up 'desc(A1)' --hidden
@@ -130,7 +132,7 @@
   o  d004c8f274b9
   |
   | @  a468dc9b3633
-  |/ Obsfate: rewritten as 4:d004c8f274b9;
+  |/ Obsfate: rewritten as 4:d004c8f274b9 by test2;
   o  ea207398892e
   
 Predecessors template should show all the predecessors as we force their 
display
@@ -161,11 +163,11 @@
   o  d004c8f274b9
   |
   | @  a468dc9b3633
-  |/ Obsfate: rewritten as 4:d004c8f274b9;
+  |/ Obsfate: rewritten as 4:d004c8f274b9 by test2;
   | x  f137d23bb3e1
   | |
   | x  471f378eab4c
-  |/ Obsfate: rewritten as 3:a468dc9b3633;
+  |/ Obsfate: rewritten as 3:a468dc9b3633 by test1;
   o  ea207398892e
   
 
@@ -210,14 +212,13 @@
   @  d004c8f274b9
   |
   | x  a468dc9b3633
-  |/ Obsfate: rewritten as 4:d004c8f274b9;
+  |/ Obsfate: rewritten as 4:d004c8f274b9 by test2;
   | x  f137d23bb3e1
   | |
   | x  471f378eab4c
-  |/ Obsfate: rewritten as 3:a468dc9b3633;
+  |/ Obsfate: rewritten as 3:a468dc9b3633 by test1;
   o  ea207398892e
   
-
   $ hg fatelogjson --hidden
   @  d004c8f274b9
   |
@@ -319,7 +320,7 @@
   o  337fec4d2edc
   |
   | @  471597cad322
-  |/ Obsfate: split as 2:337fec4d2edc, 3:f257fde29c7a;
+  |/ Obsfate: split as 2:337fec4d2edc, 3:f257fde29c7a by test;
   o  ea207398892e
   
   $ hg up f257fde29c7a
@@ -360,7 +361,7 @@
   o  337fec4d2edc
   |
   | x  471597cad322
-  |/ Obsfate: split as 2:337fec4d2edc, 3:f257fde29c7a;
+  |/ Obsfate: split as 

[PATCH 9 of 9 V3] test: add more obsmarker tests for pruning scenarios

2017-08-21 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1502986172 -7200
#  Thu Aug 17 18:09:32 2017 +0200
# Node ID 9821bcb3d8fd64a8ab1f68b2ab5d76b108587048
# Parent  7cb7e67addd11cdbecea49ec707e3e9b30bb8677
# EXP-Topic obsfatetemplate
test: add more obsmarker tests for pruning scenarios

The obsfate output in cases of pruning is not ideal right now, add some tests
so have these scenarios around.

diff -r 7cb7e67addd1 -r 9821bcb3d8fd tests/test-obsmarker-template.t
--- a/tests/test-obsmarker-template.t   Mon Jul 03 17:38:56 2017 +0200
+++ b/tests/test-obsmarker-template.t   Thu Aug 17 18:09:32 2017 +0200
@@ -1645,3 +1645,138 @@
   |Obsfate: pruned by test (at 1970-01-01 00:00 +);
   o  ea207398892e
   
+Test templates with multiple pruned commits
+===
+
+Test setup
+--
+
+  $ hg init $TESTTMP/multiple-local-prune
+  $ cd $TESTTMP/multiple-local-prune
+  $ mkcommit ROOT
+  $ mkcommit A0
+  $ hg commit --amend -m "A1"
+  $ hg debugobsolete --record-parent `getid "."`
+  obsoleted 1 changesets
+
+  $ hg up -r "desc(A0)" --hidden
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg commit --amend -m "A2"
+  $ hg debugobsolete --record-parent `getid "."`
+  obsoleted 1 changesets
+
+Check output
+
+
+  $ hg up "desc(A0)" --hidden
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg tlog
+  @  471f378eab4c
+  |
+  o  ea207398892e
+  
+# todo: the obsfate output is not ideal
+  $ hg fatelog
+  @  471f378eab4c
+  |Obsfate: pruned;
+  o  ea207398892e
+  
+  $ hg fatelog -v --hidden
+  x  65b757b745b9
+  |Obsfate: pruned by test (at 1970-01-01 00:00 +);
+  | x  fdf9bde5129a
+  |/ Obsfate: pruned by test (at 1970-01-01 00:00 +);
+  | @  471f378eab4c
+  |/ Obsfate: rewritten as 2:fdf9bde5129a by test (at 1970-01-01 00:00 
+); rewritten as 3:65b757b745b9 by test (at 1970-01-01 00:00 +);
+  o  ea207398892e
+  
+
+Test templates with splitted and pruned commit
+==
+
+  $ hg init $TESTTMP/templates-local-split-prune
+  $ cd $TESTTMP/templates-local-split-prune
+  $ mkcommit ROOT
+  $ echo 42 >> a
+  $ echo 43 >> b
+  $ hg commit -A -m "A0"
+  adding a
+  adding b
+  $ hg log --hidden -G
+  @  changeset:   1:471597cad322
+  |  tag: tip
+  |  user:test
+  |  date:Thu Jan 01 00:00:00 1970 +
+  |  summary: A0
+  |
+  o  changeset:   0:ea207398892e
+ user:test
+ date:Thu Jan 01 00:00:00 1970 +
+ summary: ROOT
+  
+# Simulate split
+  $ hg up -r "desc(ROOT)"
+  0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+  $ echo 42 >> a
+  $ hg commit -A -m "A1"
+  adding a
+  created new head
+  $ echo 43 >> b
+  $ hg commit -A -m "A2"
+  adding b
+  $ hg debugobsolete `getid "1"` `getid "2"` `getid "3"`
+  obsoleted 1 changesets
+
+# Simulate prune
+  $ hg debugobsolete --record-parent `getid "."`
+  obsoleted 1 changesets
+
+  $ hg log --hidden -G
+  @  changeset:   3:0d0ef4bdf70e
+  |  tag: tip
+  |  user:test
+  |  date:Thu Jan 01 00:00:00 1970 +
+  |  summary: A2
+  |
+  o  changeset:   2:617adc3a144c
+  |  parent:  0:ea207398892e
+  |  user:test
+  |  date:Thu Jan 01 00:00:00 1970 +
+  |  summary: A1
+  |
+  | x  changeset:   1:471597cad322
+  |/   user:test
+  |date:Thu Jan 01 00:00:00 1970 +
+  |summary: A0
+  |
+  o  changeset:   0:ea207398892e
+ user:test
+ date:Thu Jan 01 00:00:00 1970 +
+ summary: ROOT
+  
+Check templates
+---
+
+  $ hg up 'desc("A0")' --hidden
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+# todo: the obsfate output is not ideal
+  $ hg fatelog
+  o  617adc3a144c
+  |
+  | @  471597cad322
+  |/ Obsfate: pruned;
+  o  ea207398892e
+  
+  $ hg up -r 'desc("A2")' --hidden
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+  $ hg fatelog --hidden
+  @  0d0ef4bdf70e
+  |Obsfate: pruned by test (at 1970-01-01 00:00 +);
+  o  617adc3a144c
+  |
+  | x  471597cad322
+  |/ Obsfate: split as 2:617adc3a144c, 3:0d0ef4bdf70e by test (at 
1970-01-01 00:00 +);
+  o  ea207398892e
+  
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 3 of 9 V3] obsolete: track markers in _succs

2017-08-21 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499045278 -7200
#  Mon Jul 03 03:27:58 2017 +0200
# Node ID 89a659e236b906e58a48dfed8a4e3b89372d7184
# Parent  60a7a3ca1dae7dc99b8b018b4aefa24b74d3b149
# EXP-Topic obsfatetemplate
obsolete: track markers in _succs

We now also store markers in _succs. It will be useful for the obsfate template 
that
will use them to display more meaningful information like the list of users
that have evolved a changeset into its successors.

diff -r 60a7a3ca1dae -r 89a659e236b9 mercurial/obsutil.py
--- a/mercurial/obsutil.py  Mon Jul 03 03:13:17 2017 +0200
+++ b/mercurial/obsutil.py  Mon Jul 03 03:27:58 2017 +0200
@@ -330,8 +330,14 @@
 class _succs(list):
 """small class to represent a successors with some metadata about it"""
 
+def __init__(self, *args, **kwargs):
+super(_succs, self).__init__(*args, **kwargs)
+self.markers = set()
+
 def copy(self):
-return _succs(self)
+new = _succs(self)
+new.markers = self.markers.copy()
+return new
 
 def successorssets(repo, initialnode, closest=False, cache=None):
 """Return set of all latest successors of initial nodes
@@ -527,13 +533,16 @@
 succssets = []
 for mark in sorted(succmarkers[current]):
 # successors sets contributed by this marker
-markss = [_succs()]
+base = _succs()
+base.markers.add(mark)
+markss = [base]
 for suc in mark[1]:
 # cardinal product with previous successors
 productresult = []
 for prefix in markss:
 for suffix in cache[suc]:
 newss = prefix.copy()
+newss.markers.update(suffix.markers)
 for part in suffix:
 # do not duplicated entry in successors set
 # first entry wins.
@@ -548,12 +557,13 @@
 candidate = sorted(((set(s), s) for s in succssets if s),
key=lambda x: len(x[1]), reverse=True)
 for setversion, listversion in candidate:
-for seenset in seen:
+for seenset, seensuccs in seen:
 if setversion.issubset(seenset):
+seensuccs.markers.update(listversion.markers)
 break
 else:
 final.append(listversion)
-seen.append(setversion)
+seen.append((setversion, listversion))
 final.reverse() # put small successors set first
 cache[current] = final
 return cache[initialnode]
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 1 of 9 V3] obsolete: introduce a _succs class

2017-08-21 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499036035 -7200
#  Mon Jul 03 00:53:55 2017 +0200
# Node ID 328789121fa66b99c50ffa2fb139df700cf9fdc8
# Parent  3cfc9070245fbaa8c4c010327f24d579a416370f
# EXP-Topic obsfatetemplate
obsolete: introduce a _succs class

It will be useful later when we will be adding markers to _succs in order to
represent a successorset with the list of markers from the root to each
successors sets. This information will be needed for the obsfate template I will
introduce.

Makes it a subclass of list so all callers will continue to work.

diff -r 3cfc9070245f -r 328789121fa6 mercurial/obsutil.py
--- a/mercurial/obsutil.py  Wed Aug 16 10:44:06 2017 -0700
+++ b/mercurial/obsutil.py  Mon Jul 03 00:53:55 2017 +0200
@@ -327,6 +327,9 @@
 obsoleted.add(rev)
 return obsoleted
 
+class _succs(list):
+"""small class to represent a successors with some metadata about it"""
+
 def successorssets(repo, initialnode, closest=False, cache=None):
 """Return set of all latest successors of initial nodes
 
@@ -445,11 +448,11 @@
 # case (2): end of walk.
 if current in repo:
 # We have a valid successors.
-cache[current] = [(current,)]
+cache[current] = [_succs((current,))]
 else:
 # Final obsolete version is unknown locally.
 # Do not count that as a valid successors
-cache[current] = []
+cache[current] = _succs()
 else:
 # cases (3) and (4)
 #
@@ -487,7 +490,7 @@
 if suc not in cache:
 if suc in stackedset:
 # cycle breaking
-cache[suc] = []
+cache[suc] = _succs()
 else:
 # case (3) If we have not computed successors sets
 # of one of those successors we add it to the
@@ -521,13 +524,13 @@
 succssets = []
 for mark in sorted(succmarkers[current]):
 # successors sets contributed by this marker
-markss = [[]]
+markss = [_succs()]
 for suc in mark[1]:
 # cardinal product with previous successors
 productresult = []
 for prefix in markss:
 for suffix in cache[suc]:
-newss = list(prefix)
+newss = _succs(prefix)
 for part in suffix:
 # do not duplicated entry in successors set
 # first entry wins.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH] bookmarks: allow renaming active bookmark using '.'

2017-08-21 Thread David Demelier
# HG changeset patch
# User David Demelier 
# Date 1503298366 -7200
#  Mon Aug 21 08:52:46 2017 +0200
# Node ID f6ee280ea6afef475c3d158c4c4964a05be6ef15
# Parent  1e71a27dee970ec9ef02c004f662b5a99182f69b
bookmarks: allow renaming active bookmark using '.'

diff -r 1e71a27dee97 -r f6ee280ea6af mercurial/bookmarks.py
--- a/mercurial/bookmarks.pySun Aug 13 00:17:13 2017 -0700
+++ b/mercurial/bookmarks.pyMon Aug 21 08:52:46 2017 +0200
@@ -763,7 +763,11 @@
 """
 marks = repo._bookmarks
 mark = checkformat(repo, new)
-if old not in marks:
+if old == ".":
+if not repo._activebookmark:
+raise error.Abort(_("no active bookmark to rename"))
+old = repo._activebookmark
+elif old not in marks:
 raise error.Abort(_("bookmark '%s' does not exist") % old)
 changes = []
 for bm in marks.checkconflict(mark, force):
diff -r 1e71a27dee97 -r f6ee280ea6af tests/test-bookmarks.t
--- a/tests/test-bookmarks.tSun Aug 13 00:17:13 2017 -0700
+++ b/tests/test-bookmarks.tMon Aug 21 08:52:46 2017 +0200
@@ -191,6 +191,28 @@
 
   $ hg bookmark -f -m X Y
 
+rename bookmark using .
+
+  $ hg book rename-me
+  $ hg book -m . renamed
+  $ hg bookmark
+ X21:925d80f479bb
+ Y 2:db815d6d32e6
+ Z 0:f7b1eb17ad24
+   * renamed   2:db815d6d32e6
+  $ hg up -q Y
+  $ hg book -d renamed
+
+rename bookmark using . with no active bookmark
+
+  $ hg book rename-me
+  $ hg book -i rename-me
+  $ hg book -m . renamed
+  abort: no active bookmark to rename
+  [255]
+  $ hg up -q Y
+  $ hg book -d rename-me
+
 list bookmarks
 
   $ hg bookmark
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel