D7631: absorb: allowing committed changes to be absorbed into their ancestors

2020-03-11 Thread mjacob (Manuel Jacob)
mjacob added a comment.


  In D7631#123321 , @mharbison72 
wrote:
  
  > In D7631#123318 , @mjacob 
wrote:
  >
  >> I like the name `--from` for the option. It would also make sense in 
combination with a possible future `--into` option.
  >
  > The unfortunate thing about `--from` is that it implies a range in `hg 
fold`, whereas here it seems to be a single(?) commit.  It does make a lot of 
sense within the context of this command though (i.e. taking stuff //from// 
this commit).  And it took me awhile to get comfortable with the meaning in `hg 
fold`, so maybe it can be changed to something else there?  In any event, I 
don't want to hold this up over an experimental name, just thinking out loud.
  
  The `--from` in `hg fold` does not only have a different meaning, it’s also a 
flag that does not take an argument. The `hg fold` command itself takes 
revisions as arguments, so people might think they pass a revision to `--from` 
while they actually pass a revision to `hg fold` (having the same meaning as if 
it is passed to `-r`). Coincidentally, I was asked for help today from someone 
misusing the command that way. The `hg rewind` command also takes a `--from` 
option, this time with an argument. I expect that at least one of it might get 
changed eventually and I think we should not block this patch on that 
discussion.
  
  Of course, if someone comes up with a name that doesn’t have these problems 
and is intuitive, we should use that name.
  
  > I tend to agree with @martinvonz that setting the successor back to the 
commit it was absorbed into would be confusing, and seems like a way to split 
the stack into two stacks on that destination, with the corresponding merge 
conflicts.  (Would the new "`hg evolve` => stabilize all descendants 
functionality" even stop at the break?  I don't think it would.)  I get what 
you're going for though if you want to track content.  But it seems like it 
would cause non power users a lot of confusion.
  
  I prepared a patch that helps to prevent that the stack gets split: 
https://foss.heptapod.net/mercurial/evolve/merge_requests/126
  
  As an example:
  
echo a > a; hg add a; hg ci -m a
echo b > b; hg add b; hg ci -m b
echo c > c; hg add c; hg ci -m c
echo a1 > a; echo b1 > b; hg ci -m 'change a and b'
echo d > d; hg add d; hg ci -m d
  
  Graph:
  
@  (4) d
|
o  (3) change a and b
|
o  (2) c
|
o  (1) b
|
o  (0) a
  
  First, let’s emulate a run of `hg absorb --from 3` that adds markers.
  
hg up 3
hg uncommit --all
hg up 2 --merge
hg absorb --apply-changes
hg prune -r 5 -s '6 + 7' --split
  
  Graph:
  
@  (8) c
|
o  (7) b
|
o  (6) a

*  (4) d
|
x  (3) change a and b — split using prune, uncommit as 6, 7
|
x  (2) c — rebased using absorb as 8
|
x  (1) b — rewritten using absorb as 7
|
x  (0) a — amended using absorb as 6
  
  Now, `hg evolve -r 4` would have the following result without the above patch:
  
o  (9) d
|
| @  (8) c
|/
o  (7) b
|
o  (6) a
  
  and with the above patch:
  
o  (9) d
|
@  (8) c
|
o  (7) b
|
o  (6) a

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7631/new/

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

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


D8243: copies: stop recording buggy file merge when new file overwrite an old one

2020-03-11 Thread martinvonz (Martin von Zweigbergk)
martinvonz added a comment.


  FYI, I'd like to look at this patch, but I'm busy with other things right now 
(switching back and forth between browser tabs to delay the interview feedback 
that I'm actually supposed to write), so it will take a bit longer before I'll 
find time for this one.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8243/new/

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

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


D8243: copies: stop recording buggy file merge when new file overwrite an old one

2020-03-11 Thread marmoute (Pierre-Yves David)
marmoute updated this revision to Diff 20755.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8243?vs=20595=20755

BRANCH
  default

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8243/new/

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

AFFECTED FILES
  mercurial/localrepo.py
  tests/test-convert-hg-source.t
  tests/test-copies-chain-merge.t

CHANGE DETAILS

diff --git a/tests/test-copies-chain-merge.t b/tests/test-copies-chain-merge.t
--- a/tests/test-copies-chain-merge.t
+++ b/tests/test-copies-chain-merge.t
@@ -212,7 +212,7 @@
   (branch merge, don't forget to commit)
   $ hg ci -m 'mBDm-0 simple merge - one way'
   $ hg up 'desc("d-2")'
-  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg merge 'desc("b-1")'
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   (branch merge, don't forget to commit)
@@ -314,8 +314,7 @@
  rev linkrev nodeid   p1   p2
0   2 01c2f5eabdc4  
1  10 b004912a8510  
-   2  15 0bb5445dc4d0 01c2f5eabdc4 b004912a8510
-   3  22 c72365ee036f  
+   2  22 c72365ee036f  
   $ hg up 'desc("b-1")'
   3 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg merge 'desc("f-2")'
@@ -323,7 +322,7 @@
   (branch merge, don't forget to commit)
   $ hg ci -m 'mBFm-0 simple merge - one way'
   $ hg up 'desc("f-2")'
-  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg merge 'desc("b-1")'
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   (branch merge, don't forget to commit)
@@ -537,17 +536,12 @@
 - one with change to an unrelated file
 - one deleting and recreating the change
 
-Note:
-| In this case, one of the merge wrongly record a merge while there is none.
-| This lead to bad copy tracing information to be dug up.
-
   $ hg status --copies --rev 'desc("b-1")' --rev 'desc("mBDm-0")'
   M d
   $ hg status --copies --rev 'desc("b-1")' --rev 'desc("mDBm-0")'
   M d
   $ hg status --copies --rev 'desc("d-2")' --rev 'desc("mBDm-0")'
   M b
-  M d
   $ hg status --copies --rev 'desc("d-2")' --rev 'desc("mDBm-0")'
   M b
   $ hg status --copies --rev 'desc("i-2")' --rev 'desc("mBDm-0")'
@@ -557,18 +551,14 @@
   M b
   M d
 
-The bugs makes recorded copy is different depending of where we started the 
merge from since
+
+The result must be the same for both merges
 
   $ hg manifest --debug --rev 'desc("mBDm-0")' | grep '644   d'
-  0bb5445dc4d02f4e0d86cf16f9f3a411d0f17744 644   d
+  b004912a8510032a0350a74daa2803dadfb00e12 644   d
   $ hg manifest --debug --rev 'desc("mDBm-0")' | grep '644   d'
   b004912a8510032a0350a74daa2803dadfb00e12 644   d
 
-The 0bb5445dc4d02f4e0d86cf16f9f3a411d0f17744 entry is wrong, since the file was
-deleted on one side (then recreate) and untouched on the other side, no "merge"
-has happened. The resulting `d` file is the untouched version from branch `D`,
-not a merge.
-
   $ hg manifest --debug --rev 'desc("d-2")' | grep '644   d'
   b004912a8510032a0350a74daa2803dadfb00e12 644   d
   $ hg manifest --debug --rev 'desc("b-1")' | grep '644   d'
@@ -577,29 +567,16 @@
  rev linkrev nodeid   p1   p2
0   2 01c2f5eabdc4  
1  10 b004912a8510  
-   2  15 0bb5445dc4d0 01c2f5eabdc4 b004912a8510
-   3  22 c72365ee036f  
-   4  23 863d9bc49190 01c2f5eabdc4 c72365ee036f
-   5  25 7bded9d9da1f 01c2f5eabdc4 
-   6  26 f04cac32d703 b004912a8510 7bded9d9da1f
-   7  27 d7a5eafb9322 7bded9d9da1f b004912a8510
-   8  28 2ed7a51aed47 c72365ee036f 7bded9d9da1f
-
-(This `hg log` output if wrong, since no merge actually happened).
+   2  22 c72365ee036f  
+   3  25 7bded9d9da1f 01c2f5eabdc4 
+   4  26 f04cac32d703 b004912a8510 7bded9d9da1f
+   5  27 d7a5eafb9322 7bded9d9da1f b004912a8510
+   6  28 2ed7a51aed47 c72365ee036f 7bded9d9da1f
 
   $ hg log -Gfr 'desc("mBDm-0")' d
-  o15 mBDm-0 simple merge - one way]
-  |\
-  o :  14 d-2 re-add d]
-  :/
-  o  2 i-2: c -move-> d]
+  o  14 d-2 re-add d]
   |
-  o  1 i-1: a -move-> c]
-  |
-  o  0 i-0 initial commit: a b h]
-  
-
-This `hg log` output is correct
+  ~
 
   $ hg log -Gfr 'desc("mDBm-0")' d
   o  14 d-2 re-add d]
@@ -609,7 +586,6 @@
   $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mBDm-0")'
   M b
   A d
-a
   R a
   $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mDBm-0")'
   M b
@@ -685,8 +661,7 @@
   $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mBFm-0")'
   M b
   A d
-a 

D8125: transactions: convert changes['phases'] to list of ranges

2020-03-11 Thread joerg.sonnenberger (Joerg Sonnenberger)
Closed by commit rHGc74bab41d1c5: transactions: convert 
changes[phases] to list of ranges (authored by joerg.sonnenberger).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

CHANGED PRIOR TO COMMIT
  https://phab.mercurial-scm.org/D8125?vs=20434=20748#toc

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8125?vs=20434=20748

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8125/new/

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

AFFECTED FILES
  mercurial/localrepo.py
  mercurial/phases.py
  mercurial/scmutil.py
  tests/testlib/ext-phase-report.py

CHANGE DETAILS

diff --git a/tests/testlib/ext-phase-report.py 
b/tests/testlib/ext-phase-report.py
--- a/tests/testlib/ext-phase-report.py
+++ b/tests/testlib/ext-phase-report.py
@@ -5,21 +5,22 @@
 
 def reposetup(ui, repo):
 def reportphasemove(tr):
-for rev, move in sorted(tr.changes[b'phases'].items()):
-if move[0] is None:
-ui.write(
-(
-b'test-debug-phase: new rev %d:  x -> %d\n'
-% (rev, move[1])
+for revs, move in sorted(tr.changes[b"phases"], key=lambda r: r[0][0]):
+for rev in revs:
+if move[0] is None:
+ui.write(
+(
+b'test-debug-phase: new rev %d:  x -> %d\n'
+% (rev, move[1])
+)
 )
-)
-else:
-ui.write(
-(
-b'test-debug-phase: move rev %d: %d -> %d\n'
-% (rev, move[0], move[1])
+else:
+ui.write(
+(
+b'test-debug-phase: move rev %d: %d -> %d\n'
+% (rev, move[0], move[1])
+)
 )
-)
 
 class reportphaserepo(repo.__class__):
 def transaction(self, *args, **kwargs):
diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py
--- a/mercurial/scmutil.py
+++ b/mercurial/scmutil.py
@@ -2058,14 +2058,11 @@
 pull/unbundle.
 """
 origrepolen = tr.changes.get(b'origrepolen', len(repo))
-phasetracking = tr.changes.get(b'phases', {})
-if not phasetracking:
-return
-published = [
-rev
-for rev, (old, new) in pycompat.iteritems(phasetracking)
-if new == phases.public and rev < origrepolen
-]
+published = []
+for revs, (old, new) in tr.changes.get(b'phases', []):
+if new != phases.public:
+continue
+published.extend(rev for rev in revs if rev < origrepolen)
 if not published:
 return
 msg = _(b'%d local changesets published\n')
diff --git a/mercurial/phases.py b/mercurial/phases.py
--- a/mercurial/phases.py
+++ b/mercurial/phases.py
@@ -216,17 +216,101 @@
 return headsbyphase
 
 
+def _sortedrange_insert(data, idx, rev, t):
+merge_before = False
+if idx:
+r1, t1 = data[idx - 1]
+merge_before = r1[-1] + 1 == rev and t1 == t
+merge_after = False
+if idx < len(data):
+r2, t2 = data[idx]
+merge_after = r2[0] == rev + 1 and t2 == t
+
+if merge_before and merge_after:
+data[idx - 1] = (pycompat.xrange(r1[0], r2[-1] + 1), t)
+data.pop(idx)
+elif merge_before:
+data[idx - 1] = (pycompat.xrange(r1[0], rev + 1), t)
+elif merge_after:
+data[idx] = (pycompat.xrange(rev, r2[-1] + 1), t)
+else:
+data.insert(idx, (pycompat.xrange(rev, rev + 1), t))
+
+
+def _sortedrange_split(data, idx, rev, t):
+r1, t1 = data[idx]
+if t == t1:
+return
+t = (t1[0], t[1])
+if len(r1) == 1:
+data.pop(idx)
+_sortedrange_insert(data, idx, rev, t)
+elif r1[0] == rev:
+data[idx] = (pycompat.xrange(rev + 1, r1[-1] + 1), t1)
+_sortedrange_insert(data, idx, rev, t)
+elif r1[-1] == rev:
+data[idx] = (pycompat.xrange(r1[0], rev), t1)
+_sortedrange_insert(data, idx + 1, rev, t)
+else:
+data[idx : idx + 1] = [
+(pycompat.xrange(r1[0], rev), t1),
+(pycompat.xrange(rev, rev + 1), t),
+(pycompat.xrange(rev + 1, r1[-1] + 1), t1),
+]
+
+
 def _trackphasechange(data, rev, old, new):
-"""add a phase move the  dictionnary
+"""add a phase move to the  list of ranges
 
 If data is None, nothing happens.
 """
 if data is None:
 return
-existing = data.get(rev)
-if existing is not None:
-old = existing[0]
-data[rev] = (old, new)
+
+# 

D8273: test-install: don't print Rust re2 bindings information if Rust is not in use

2020-03-11 Thread Raphaël Gomès
Closed by commit rHG9350ae3a42f1: test-install: dont print Rust re2 
bindings information if Rust is not in use (authored by Alphare).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8273?vs=20741=20747

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8273/new/

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

AFFECTED FILES
  tests/test-install.t

CHANGE DETAILS

diff --git a/tests/test-install.t b/tests/test-install.t
--- a/tests/test-install.t
+++ b/tests/test-install.t
@@ -18,7 +18,7 @@
   checking available compression engines (*zlib*) (glob)
   checking available compression engines for wire protocol (*zlib*) (glob)
   checking "re2" regexp engine \((available|missing)\) (re)
-  checking "re2" regexp engine Rust bindings \((installed|missing)\) (re)
+  checking "re2" regexp engine Rust bindings \((installed|missing)\) (re) 
(rust !)
   checking templates (*mercurial?templates)... (glob)
   checking default template (*mercurial?templates?map-cmdline.default) (glob)
   checking commit editor... (*) (glob)
@@ -78,7 +78,7 @@
   checking available compression engines (*zlib*) (glob)
   checking available compression engines for wire protocol (*zlib*) (glob)
   checking "re2" regexp engine \((available|missing)\) (re)
-  checking "re2" regexp engine Rust bindings \((installed|missing)\) (re)
+  checking "re2" regexp engine Rust bindings \((installed|missing)\) (re) 
(rust !)
   checking templates (*mercurial?templates)... (glob)
   checking default template (*mercurial?templates?map-cmdline.default) (glob)
   checking commit editor... (*) (glob)
@@ -126,7 +126,7 @@
   checking available compression engines (*zlib*) (glob)
   checking available compression engines for wire protocol (*zlib*) (glob)
   checking "re2" regexp engine \((available|missing)\) (re)
-  checking "re2" regexp engine Rust bindings \((installed|missing)\) (re)
+  checking "re2" regexp engine Rust bindings \((installed|missing)\) (re) 
(rust !)
   checking templates (*mercurial?templates)... (glob)
   checking default template (*mercurial?templates?map-cmdline.default) (glob)
   checking commit editor... ($TESTTMP/tools/testeditor.exe)
@@ -154,7 +154,7 @@
   checking available compression engines (*zlib*) (glob)
   checking available compression engines for wire protocol (*zlib*) (glob)
   checking "re2" regexp engine \((available|missing)\) (re)
-  checking "re2" regexp engine Rust bindings \((installed|missing)\) (re)
+  checking "re2" regexp engine Rust bindings \((installed|missing)\) (re) 
(rust !)
   checking templates (*mercurial?templates)... (glob)
   checking default template (*mercurial?templates?map-cmdline.default) (glob)
   checking commit editor... (c:\foo\bar\baz.exe) (windows !)
@@ -211,7 +211,7 @@
   checking available compression engines (*) (glob)
   checking available compression engines for wire protocol (*) (glob)
   checking "re2" regexp engine \((available|missing)\) (re)
-  checking "re2" regexp engine Rust bindings \((installed|missing)\) (re)
+  checking "re2" regexp engine Rust bindings \((installed|missing)\) (re) 
(rust !)
   checking templates 
($TESTTMP/installenv/*/site-packages/mercurial/templates)... (glob)
   checking default template 
($TESTTMP/installenv/*/site-packages/mercurial/templates/map-cmdline.default) 
(glob)
   checking commit editor... (*) (glob)
@@ -252,7 +252,7 @@
   checking available compression engines (*) (glob)
   checking available compression engines for wire protocol (*) (glob)
   checking "re2" regexp engine \((available|missing)\) (re)
-  checking "re2" regexp engine Rust bindings \((installed|missing)\) (re)
+  checking "re2" regexp engine Rust bindings \((installed|missing)\) (re) 
(rust !)
   checking templates 
($TESTTMP/installenv/*/site-packages/mercurial/templates)... (glob)
   checking default template 
($TESTTMP/installenv/*/site-packages/mercurial/templates/map-cmdline.default) 
(glob)
   checking commit editor... (*) (glob)



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


D8189: testlib: add a small scrip to help process to synchronise using file

2020-03-11 Thread mharbison72 (Matt Harbison)
mharbison72 added a comment.


  In D8189#123526 , @marmoute 
wrote:
  
  > In D8189#123521 , @mharbison72 
wrote:
  >
  >> In D8189#123323 , @durin42 
wrote:
  >>
  >>> I think it might be better to poll more often in the script and not even 
take a timeout: sleep forever waiting for the condition, and if it never comes 
let the test timeout at the runner level. Thoughts?
  >>
  >> I filed a bug about this that self-archived, but:
  >>
  >>   $ echo '  $ sleep 10' > test-timeout.t
  >>   $ time ./run-tests.py --local test-timeout.t -t 5
  >>   running 1 tests using 1 parallel processes
  >>   t
  >>   Failed test-timeout.t: timed out
  >>   # Ran 1 tests, 0 skipped, 1 failed.
  >>   python hash seed: 204038743
  >>   real0m10.363s
  >>   user0m0.000s
  >>   sys 0m0.030s
  >>
  >> So it looks like tests never timeout, but then the result is discarded 
afterward if the timeout period elapsed.  I can reproduce it on Windows and 
macOS.
  >
  > Do you have a link to the bug ?
  
  https://bz.mercurial-scm.org/show_bug.cgi?id=6125
  
  > Waiting for the test timeout is not a reasonable option because the test is 
killed without any details (and it is LOONG). The most common case for reaching 
the timeout is for one of the process to crash before reaching the checkpoing. 
When that happens, we want to be able to read the traceback. The second most 
common is code misbehaving and not going through the expected codepath. We also 
was to get output in this case. So in short, we need a clean way out in case of 
error and I have no better option than a (possibly long) timeout right now.
  
  I wonder if the test harness can be modified to process the data collected up 
to the point of the timeout, so that it's obvious what is getting stuck.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8189/new/

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

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


D8189: testlib: add a small scrip to help process to synchronise using file

2020-03-11 Thread marmoute (Pierre-Yves David)
marmoute added a comment.


  In D8189#123521 , @mharbison72 
wrote:
  
  > In D8189#123323 , @durin42 
wrote:
  >
  >> I think it might be better to poll more often in the script and not even 
take a timeout: sleep forever waiting for the condition, and if it never comes 
let the test timeout at the runner level. Thoughts?
  >
  > I filed a bug about this that self-archived, but:
  >
  >   $ echo '  $ sleep 10' > test-timeout.t
  >   $ time ./run-tests.py --local test-timeout.t -t 5
  >   running 1 tests using 1 parallel processes
  >   t
  >   Failed test-timeout.t: timed out
  >   # Ran 1 tests, 0 skipped, 1 failed.
  >   python hash seed: 204038743
  >   real0m10.363s
  >   user0m0.000s
  >   sys 0m0.030s
  >
  > So it looks like tests never timeout, but then the result is discarded 
afterward if the timeout period elapsed.  I can reproduce it on Windows and 
macOS.
  
  Do you have a link to the bug ?

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8189/new/

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

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


D8192: nodemap: display percentage of unused in `hg debugnodemap`

2020-03-11 Thread marmoute (Pierre-Yves David)
marmoute updated this revision to Diff 20743.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8192?vs=20687=20743

BRANCH
  default

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8192/new/

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

AFFECTED FILES
  mercurial/debugcommands.py
  mercurial/revlogutils/nodemap.py
  tests/test-persistent-nodemap.t

CHANGE DETAILS

diff --git a/tests/test-persistent-nodemap.t b/tests/test-persistent-nodemap.t
--- a/tests/test-persistent-nodemap.t
+++ b/tests/test-persistent-nodemap.t
@@ -17,6 +17,7 @@
   tip-node: 06ddac466af534d365326c13c3879f97caca3cb1
   data-length: 122880
   data-unused: 0
+  data-unused: 0.000%
   $ f --size .hg/store/00changelog.n
   .hg/store/00changelog.n: size=70
 
@@ -99,6 +100,7 @@
   tip-node: 2dd9b5258caa46469ff07d4a3da1eb3529a51f49
   data-length: 122880
   data-unused: 0
+  data-unused: 0.000%
 #else
   $ hg debugnodemap --metadata
   uid:  (glob)
@@ -106,6 +108,7 @@
   tip-node: 2dd9b5258caa46469ff07d4a3da1eb3529a51f49
   data-length: 123072
   data-unused: 192
+  data-unused: 0.156%
 #endif
 
   $ f --size .hg/store/00changelog.n
@@ -154,6 +157,7 @@
   tip-node: 6ce944fafcee85af91f29ea5b51654cc6101ad7e
   data-length: 123328
   data-unused: 384
+  data-unused: 0.311%
   $ f --sha256 .hg/store/00changelog-*.nd --size
   .hg/store/00changelog-.nd: size=123328, 
sha256=10d26e9776b6596af0f89143a54eba8cc581e929c38242a02a7b0760698c6c70 (glob)
 #endif
@@ -164,6 +168,7 @@
   tip-node: 6ce944fafcee85af91f29ea5b51654cc6101ad7e
   data-length: 123328
   data-unused: 384
+  data-unused: 0.311%
   $ f --sha256 .hg/store/00changelog-*.nd --size
   .hg/store/00changelog-.nd: size=123328, 
sha256=081eec9eb6708f2bf085d939b4c97bc0b6762bc8336bc4b93838f7fffa1516bf (glob)
 #endif
@@ -174,6 +179,7 @@
   tip-node: 6ce944fafcee85af91f29ea5b51654cc6101ad7e
   data-length: 122944
   data-unused: 0
+  data-unused: 0.000%
   $ f --sha256 .hg/store/00changelog-*.nd --size
   .hg/store/00changelog-.nd: size=122944, 
sha256=755976b22b64ab680401b45395953504e64e7fa8c31ac570f58dee21e15f9bc0 (glob)
 #endif
@@ -190,6 +196,7 @@
   tip-node: 6ce944fafcee85af91f29ea5b51654cc6101ad7e
   data-length: 122944
   data-unused: 0
+  data-unused: 0.000%
 #else
   $ hg debugnodemap --metadata
   uid:  (glob)
@@ -197,6 +204,7 @@
   tip-node: 6ce944fafcee85af91f29ea5b51654cc6101ad7e
   data-length: 122944
   data-unused: 0
+  data-unused: 0.000%
 #endif
 
 Check out of sync nodemap
@@ -230,6 +238,9 @@
   data-unused: 256 (pure !)
   data-unused: 256 (rust !)
   data-unused: 0 (no-rust no-pure !)
+  data-unused: 0.208% (pure !)
+  data-unused: 0.208% (rust !)
+  data-unused: 0.000% (no-rust no-pure !)
   $ cp -f ../tmp-copies/* .hg/store/
   $ hg debugnodemap --metadata
   uid:  (glob)
@@ -237,6 +248,7 @@
   tip-node: 6ce944fafcee85af91f29ea5b51654cc6101ad7e
   data-length: 122944
   data-unused: 0
+  data-unused: 0.000%
   $ hg log -r "$NODE" -T '{rev}\n'
   5003
 
@@ -271,6 +283,9 @@
   data-unused: 448 (pure !)
   data-unused: 123904 (rust !)
   data-unused: 0 (no-pure no-rust !)
+  data-unused: 50.273% (rust !)
+  data-unused: 0.363% (pure !)
+  data-unused: 0.000% (no-pure no-rust !)
 
   $ cp -f ../tmp-copies/* .hg/store/
   $ hg debugnodemap --metadata
@@ -279,6 +294,7 @@
   tip-node: 6ce944fafcee85af91f29ea5b51654cc6101ad7e
   data-length: 122944
   data-unused: 0
+  data-unused: 0.000%
   $ hg log -r "$OTHERNODE" -T '{rev}\n'
   5002
 
@@ -296,6 +312,7 @@
   tip-node: c91af76d172f1053cca41b83f7c2e4e514fe2bcf
   data-length: 123008
   data-unused: 0
+  data-unused: 0.000%
   $ echo babar2 > babar
   $ hg ci -m 'babar2' --config "hooks.pretxnclose.nodemap-test=hg debugnodemap 
--metadata"
   uid:  (glob)
@@ -307,6 +324,9 @@
   data-unused: 192 (pure !)
   data-unused: 192 (rust !)
   data-unused: 0 (no-pure no-rust !)
+  data-unused: 0.156% (pure !)
+  data-unused: 0.156% (rust !)
+  data-unused: 0.000% (no-pure no-rust !)
   $ hg debugnodemap --metadata
   uid:  (glob)
   tip-rev: 5004
@@ -317,6 +337,9 @@
   data-unused: 192 (pure !)
   data-unused: 192 (rust !)
   data-unused: 0 (no-pure no-rust !)
+  data-unused: 0.156% (pure !)
+  data-unused: 0.156% (rust !)
+  data-unused: 0.000% (no-pure no-rust !)
 
 Another process does not see the pending nodemap content during run.
 
@@ -340,6 +363,9 @@
   data-unused: 192 (pure !)
   data-unused: 192 (rust !)
   data-unused: 0 (no-pure no-rust !)
+  data-unused: 0.156% (pure !)
+  data-unused: 0.156% (rust !)
+  data-unused: 0.000% (no-pure no-rust !)
   $ hg debugnodemap --metadata
   uid:  (glob)
   tip-rev: 5005
@@ -350,6 +376,9 @@
   data-unused: 448 (pure !)
   data-unused: 448 (rust !)
   data-unused: 0 (no-pure no-rust !)
+  data-unused: 0.363% (pure !)
+  data-unused: 0.363% (rust !)
+  data-unused: 0.000% (no-pure no-rust 

D8193: nodemap: automatically "vacuum" the persistent nodemap when too sparse

2020-03-11 Thread marmoute (Pierre-Yves David)
marmoute updated this revision to Diff 20744.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8193?vs=20688=20744

BRANCH
  default

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8193/new/

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

AFFECTED FILES
  mercurial/configitems.py
  mercurial/revlogutils/nodemap.py
  tests/test-persistent-nodemap.t

CHANGE DETAILS

diff --git a/tests/test-persistent-nodemap.t b/tests/test-persistent-nodemap.t
--- a/tests/test-persistent-nodemap.t
+++ b/tests/test-persistent-nodemap.t
@@ -278,12 +278,12 @@
   tip-rev: 5002
   tip-node: 42bf3068c7ddfdfded53c4eb11d02266faeebfee
   data-length: 123456 (pure !)
-  data-length: 246464 (rust !)
+  data-length: 123008 (rust !)
   data-length: 123008 (no-pure no-rust !)
   data-unused: 448 (pure !)
-  data-unused: 123904 (rust !)
+  data-unused: 0 (rust !)
   data-unused: 0 (no-pure no-rust !)
-  data-unused: 50.273% (rust !)
+  data-unused: 0.000% (rust !)
   data-unused: 0.363% (pure !)
   data-unused: 0.000% (no-pure no-rust !)
 
diff --git a/mercurial/revlogutils/nodemap.py b/mercurial/revlogutils/nodemap.py
--- a/mercurial/revlogutils/nodemap.py
+++ b/mercurial/revlogutils/nodemap.py
@@ -143,13 +143,16 @@
 data_changed_count,
 data,
 ) = revlog.index.nodemap_data_incremental()
+new_length = target_docket.data_length + len(data)
+new_unused = target_docket.data_unused + data_changed_count
 if src_docket != target_docket:
 data = None
+elif (new_length // new_unused) < 10:  # under 10% of unused data
+data = None
 else:
 datafile = _rawdata_filepath(revlog, target_docket)
 # EXP-TODO: if this is a cache, this should use a cache vfs, not a
 # store vfs
-new_length = target_docket.data_length + len(data)
 tr.add(datafile, target_docket.data_length)
 with revlog.opener(datafile, b'r+') as fd:
 fd.seek(target_docket.data_length)
@@ -162,7 +165,7 @@
 fd.flush()
 new_data = util.buffer(util.mmapread(fd, new_length))
 target_docket.data_length = new_length
-target_docket.data_unused += data_changed_count
+target_docket.data_unused = new_unused
 
 if data is None:
 # otherwise fallback to a full new export
diff --git a/mercurial/configitems.py b/mercurial/configitems.py
--- a/mercurial/configitems.py
+++ b/mercurial/configitems.py
@@ -407,7 +407,6 @@
 )
 # TODO before getting `persistent-nodemap` out of experimental
 #
-# * regenerate a new nodemap when the unused/total ration is to high
 # * decide for a "status" of the persistent nodemap and associated location
 #   - part of the store next the revlog itself (new requirements)
 #   - part of the cache directory



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


D8191: nodemap: make sure on disk change get rolled back with the transaction

2020-03-11 Thread marmoute (Pierre-Yves David)
marmoute updated this revision to Diff 20742.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8191?vs=20686=20742

BRANCH
  default

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8191/new/

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

AFFECTED FILES
  mercurial/configitems.py
  mercurial/revlogutils/nodemap.py
  tests/test-persistent-nodemap.t
  tests/testlib/crash_transaction_late.py

CHANGE DETAILS

diff --git a/tests/testlib/crash_transaction_late.py 
b/tests/testlib/crash_transaction_late.py
new file mode 100644
--- /dev/null
+++ b/tests/testlib/crash_transaction_late.py
@@ -0,0 +1,32 @@
+# tiny extension to abort a transaction very late during test
+#
+# Copyright 2020 Pierre-Yves David 
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2 or any later version.
+
+from __future__ import absolute_import
+
+from mercurial import (
+error,
+transaction,
+)
+
+
+def abort(fp):
+raise error.Abort(b"This is a late abort")
+
+
+def reposetup(ui, repo):
+
+transaction.postfinalizegenerators.add(b'late-abort')
+
+class LateAbortRepo(repo.__class__):
+def transaction(self, *args, **kwargs):
+tr = super(LateAbortRepo, self).transaction(*args, **kwargs)
+tr.addfilegenerator(
+b'late-abort', [b'late-abort'], abort, order=999
+)
+return tr
+
+repo.__class__ = LateAbortRepo
diff --git a/tests/test-persistent-nodemap.t b/tests/test-persistent-nodemap.t
--- a/tests/test-persistent-nodemap.t
+++ b/tests/test-persistent-nodemap.t
@@ -353,3 +353,25 @@
 
   $ cat output.txt
 
+Check that a failing transaction will properly revert the data
+
+  $ echo plakfe > a
+  $ f --size --sha256 .hg/store/00changelog-*.nd
+  .hg/store/00changelog-.nd: size=123584, 
sha256=8c6cef6fd3d3fac291968793ee19a4be6d0b8375e9508bd5c7d4a8879e8df180 (glob) 
(pure !)
+  .hg/store/00changelog-.nd: size=123584, 
sha256=eb9e9a4bcafdb5e1344bc8a0cbb3288b2106413b8efae6265fb8a7973d7e97f9 (glob) 
(rust !)
+  .hg/store/00changelog-.nd: size=123136, 
sha256=4f504f5a834db3811ced50ab3e9e80bcae3581bb0f9b13a7a9f94b7fc34bcebe (glob) 
(no-pure no-rust !)
+  $ hg ci -m a3 --config 
"extensions.abort=$RUNTESTDIR/testlib/crash_transaction_late.py"
+  transaction abort!
+  rollback completed
+  abort: This is a late abort
+  [255]
+  $ hg debugnodemap --metadata
+  uid:  (glob)
+  tip-rev: 5005
+  tip-node: bae4d45c759e30f1cb1a40e1382cf0e0414154db
+  data-length: 123584
+  data-unused: 448
+  $ f --size --sha256 .hg/store/00changelog-*.nd
+  .hg/store/00changelog-.nd: size=123584, 
sha256=8c6cef6fd3d3fac291968793ee19a4be6d0b8375e9508bd5c7d4a8879e8df180 (glob) 
(pure !)
+  .hg/store/00changelog-.nd: size=123584, 
sha256=eb9e9a4bcafdb5e1344bc8a0cbb3288b2106413b8efae6265fb8a7973d7e97f9 (glob) 
(rust !)
+  .hg/store/00changelog-.nd: size=123136, 
sha256=4f504f5a834db3811ced50ab3e9e80bcae3581bb0f9b13a7a9f94b7fc34bcebe (glob) 
(no-pure no-rust !)
diff --git a/mercurial/revlogutils/nodemap.py b/mercurial/revlogutils/nodemap.py
--- a/mercurial/revlogutils/nodemap.py
+++ b/mercurial/revlogutils/nodemap.py
@@ -93,6 +93,15 @@
 def addpostclose(self, callback_id, callback_func):
 self._postclose[callback_id] = callback_func
 
+def registertmp(self, *args, **kwargs):
+pass
+
+def addbackup(self, *args, **kwargs):
+pass
+
+def add(self, *args, **kwargs):
+pass
+
 
 def update_persistent_nodemap(revlog):
 """update the persistent nodemap right now
@@ -138,6 +147,7 @@
 # EXP-TODO: if this is a cache, this should use a cache vfs, not a
 # store vfs
 new_length = target_docket.data_length + len(data)
+tr.add(datafile, target_docket.data_length)
 with revlog.opener(datafile, b'r+') as fd:
 fd.seek(target_docket.data_length)
 fd.write(data)
@@ -161,6 +171,7 @@
 data = persistent_data(revlog.index)
 # EXP-TODO: if this is a cache, this should use a cache vfs, not a
 # store vfs
+tr.add(datafile, 0)
 with revlog.opener(datafile, b'w+') as fd:
 fd.write(data)
 if feed_data:
@@ -177,6 +188,10 @@
 file_path = revlog.nodemap_file
 if pending:
 file_path += b'.a'
+tr.registertmp(file_path)
+else:
+tr.addbackup(file_path)
+
 with revlog.opener(file_path, b'w', atomictemp=True) as fp:
 fp.write(target_docket.serialize())
 revlog._nodemap_docket = target_docket
diff --git a/mercurial/configitems.py b/mercurial/configitems.py
--- a/mercurial/configitems.py
+++ b/mercurial/configitems.py
@@ -407,7 +407,6 @@
 )
 # TODO before getting `persistent-nodemap` out of experimental
 #
-# * code/tests around 

D8189: testlib: add a small scrip to help process to synchronise using file

2020-03-11 Thread marmoute (Pierre-Yves David)
marmoute added a comment.


  In D8189#123323 , @durin42 wrote:
  
  > In D8189#123280 , @marmoute 
wrote:
  >
  >> By using explicit wait on signal (through the fs) that each process 
reached the appropriate file. We avoid flackyness. There are already multiple 
use of this approach in the test suite, that does not suffer from flackyness 
(unlike the wheelbarrow of flaky test relying on sleep for sync).
  >
  > You avoid flakyness iff the test manages to finish this step in under 20 
seconds (in the next change, as an example). Which is to say, this is still a 
flake waiting to happen, you've just made it less likely. I think it might be 
better to poll more often in the script and not even take a timeout: sleep 
forever waiting for the condition, and if it never comes let the test timeout 
at the runner level. Thoughts?
  
  The 20 seconds seems like a lots of margin already, but I am fine with 
bumping it more it that make your more confortable.
  
  Waiting for the test timeout is not a reasonable option because the test is 
killed without any details (and it is LOONG). The most common case for reaching 
the timeout is for one of the process to crash before reaching the checkpoing. 
When that happens, we want to be able to read the traceback. The second most 
common is code misbehaving and not going through the expected codepath. We also 
was to get output in this case. So in short, we need a clean way out in case of 
error and I have no better option than a (possibly long) timeout right now.
  
  > I'm also not happy about the 1-second floor this puts on the step. Doesn't 
sleep(1) support sub-second sleeps on all platforms at this point?
  
  I am extremly sad too. But last time I checked, it was still not the case. We 
detect plateform and use small increment on better plateform (but I would 
rather follow up for that).

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8189/new/

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

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


D8189: testlib: add a small scrip to help process to synchronise using file

2020-03-11 Thread mharbison72 (Matt Harbison)
mharbison72 added a comment.


  In D8189#123323 , @durin42 wrote:
  
  > I think it might be better to poll more often in the script and not even 
take a timeout: sleep forever waiting for the condition, and if it never comes 
let the test timeout at the runner level. Thoughts?
  
  I filed a bug about this that self-archived, but:
  
$ echo '  $ sleep 10' > test-timeout.t
$ time ./run-tests.py --local test-timeout.t -t 5
running 1 tests using 1 parallel processes
t
Failed test-timeout.t: timed out
# Ran 1 tests, 0 skipped, 1 failed.
python hash seed: 204038743

real0m10.363s
user0m0.000s
sys 0m0.030s
  
  So it looks like tests never timeout, but then the result is discarded 
afterward if the timeout period elapsed.  I can reproduce it on Windows and 
macOS.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8189/new/

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

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


D8273: test-install: don't print Rust re2 bindings information if Rust is not in use

2020-03-11 Thread Raphaël Gomès
Alphare created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REPOSITORY
  rHG Mercurial

BRANCH
  default

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

AFFECTED FILES
  tests/test-install.t

CHANGE DETAILS

diff --git a/tests/test-install.t b/tests/test-install.t
--- a/tests/test-install.t
+++ b/tests/test-install.t
@@ -18,7 +18,7 @@
   checking available compression engines (*zlib*) (glob)
   checking available compression engines for wire protocol (*zlib*) (glob)
   checking "re2" regexp engine \((available|missing)\) (re)
-  checking "re2" regexp engine Rust bindings \((installed|missing)\) (re)
+  checking "re2" regexp engine Rust bindings \((installed|missing)\) (re) 
(rust !)
   checking templates (*mercurial?templates)... (glob)
   checking default template (*mercurial?templates?map-cmdline.default) (glob)
   checking commit editor... (*) (glob)
@@ -78,7 +78,7 @@
   checking available compression engines (*zlib*) (glob)
   checking available compression engines for wire protocol (*zlib*) (glob)
   checking "re2" regexp engine \((available|missing)\) (re)
-  checking "re2" regexp engine Rust bindings \((installed|missing)\) (re)
+  checking "re2" regexp engine Rust bindings \((installed|missing)\) (re) 
(rust !)
   checking templates (*mercurial?templates)... (glob)
   checking default template (*mercurial?templates?map-cmdline.default) (glob)
   checking commit editor... (*) (glob)
@@ -126,7 +126,7 @@
   checking available compression engines (*zlib*) (glob)
   checking available compression engines for wire protocol (*zlib*) (glob)
   checking "re2" regexp engine \((available|missing)\) (re)
-  checking "re2" regexp engine Rust bindings \((installed|missing)\) (re)
+  checking "re2" regexp engine Rust bindings \((installed|missing)\) (re) 
(rust !)
   checking templates (*mercurial?templates)... (glob)
   checking default template (*mercurial?templates?map-cmdline.default) (glob)
   checking commit editor... ($TESTTMP/tools/testeditor.exe)
@@ -154,7 +154,7 @@
   checking available compression engines (*zlib*) (glob)
   checking available compression engines for wire protocol (*zlib*) (glob)
   checking "re2" regexp engine \((available|missing)\) (re)
-  checking "re2" regexp engine Rust bindings \((installed|missing)\) (re)
+  checking "re2" regexp engine Rust bindings \((installed|missing)\) (re) 
(rust !)
   checking templates (*mercurial?templates)... (glob)
   checking default template (*mercurial?templates?map-cmdline.default) (glob)
   checking commit editor... (c:\foo\bar\baz.exe) (windows !)
@@ -211,7 +211,7 @@
   checking available compression engines (*) (glob)
   checking available compression engines for wire protocol (*) (glob)
   checking "re2" regexp engine \((available|missing)\) (re)
-  checking "re2" regexp engine Rust bindings \((installed|missing)\) (re)
+  checking "re2" regexp engine Rust bindings \((installed|missing)\) (re) 
(rust !)
   checking templates 
($TESTTMP/installenv/*/site-packages/mercurial/templates)... (glob)
   checking default template 
($TESTTMP/installenv/*/site-packages/mercurial/templates/map-cmdline.default) 
(glob)
   checking commit editor... (*) (glob)
@@ -252,7 +252,7 @@
   checking available compression engines (*) (glob)
   checking available compression engines for wire protocol (*) (glob)
   checking "re2" regexp engine \((available|missing)\) (re)
-  checking "re2" regexp engine Rust bindings \((installed|missing)\) (re)
+  checking "re2" regexp engine Rust bindings \((installed|missing)\) (re) 
(rust !)
   checking templates 
($TESTTMP/installenv/*/site-packages/mercurial/templates)... (glob)
   checking default template 
($TESTTMP/installenv/*/site-packages/mercurial/templates/map-cmdline.default) 
(glob)
   checking commit editor... (*) (glob)



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


D8200: pull: add `--confirm` flag to confirm before writing changes

2020-03-11 Thread pulkit (Pulkit Goyal)
Closed by commit rHG476c8e427975: pull: add `--confirm` flag to confirm before 
writing changes (authored by pulkit).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8200?vs=20501=20739

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8200/new/

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

AFFECTED FILES
  mercurial/commands.py
  mercurial/configitems.py
  mercurial/exchange.py
  relnotes/next
  tests/test-completion.t
  tests/test-obsolete-distributed.t
  tests/test-obsolete.t
  tests/test-phases-exchange.t
  tests/test-pull-r.t

CHANGE DETAILS

diff --git a/tests/test-pull-r.t b/tests/test-pull-r.t
--- a/tests/test-pull-r.t
+++ b/tests/test-pull-r.t
@@ -1,3 +1,9 @@
+  $ cat <> $HGRCPATH
+  > [ui]
+  > interactive = true
+  > EOF
+
+
   $ hg init repo
   $ cd repo
   $ echo foo > foo
@@ -42,12 +48,47 @@
   $ hg heads -q --closed
   2:effea6de0384
   1:ed1b79f46b9a
-  $ hg pull
+  $ hg pull --confirm << EOF
+  > n
+  > EOF
   pulling from $TESTTMP/repo2
   searching for changes
   adding changesets
   adding manifests
   adding file changes
+  adding 2 changesets with 1 changes to 1 files
+  new changesets 8c900227dd5d:00cfe9073916
+  accept incoming changes (yn)? n
+  transaction abort!
+  rollback completed
+  abort: user aborted
+  [255]
+  $ hg pull --config pull.confirm=true << EOF
+  > n
+  > EOF
+  pulling from $TESTTMP/repo2
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  adding 2 changesets with 1 changes to 1 files
+  new changesets 8c900227dd5d:00cfe9073916
+  accept incoming changes (yn)? n
+  transaction abort!
+  rollback completed
+  abort: user aborted
+  [255]
+  $ hg pull --confirm << EOF
+  > y
+  > EOF
+  pulling from $TESTTMP/repo2
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  adding 2 changesets with 1 changes to 1 files
+  new changesets 8c900227dd5d:00cfe9073916
+  accept incoming changes (yn)? y
   added 2 changesets with 1 changes to 1 files
   new changesets 8c900227dd5d:00cfe9073916
   (run 'hg update' to get a working copy)
@@ -56,6 +97,12 @@
   2:effea6de0384
   1:ed1b79f46b9a
 
+pull--confirm config option should be ignored if HGPLAIN is set
+  $ HGPLAIN=1 hg pull --config pull.confirm=True
+  pulling from $TESTTMP/repo2
+  searching for changes
+  no changes found
+
   $ cd ..
 
   $ hg init copy
diff --git a/tests/test-phases-exchange.t b/tests/test-phases-exchange.t
--- a/tests/test-phases-exchange.t
+++ b/tests/test-phases-exchange.t
@@ -326,12 +326,18 @@
   o  0 public a-A - 054250a37db4
   
   $ cd ../mu
-  $ hg pull ../nu
+  $ hg pull ../nu --confirm --config ui.interactive=True< y
+  > EOF
   pulling from ../nu
   searching for changes
   adding changesets
   adding manifests
   adding file changes
+  adding 2 changesets with 2 changes to 2 files
+  new changesets d6bcb4f74035:145e75495359 (2 drafts)
+  4 local changesets will be published
+  accept incoming changes (yn)? y
   added 2 changesets with 2 changes to 2 files
   new changesets d6bcb4f74035:145e75495359 (2 drafts)
   4 local changesets published
diff --git a/tests/test-obsolete.t b/tests/test-obsolete.t
--- a/tests/test-obsolete.t
+++ b/tests/test-obsolete.t
@@ -377,15 +377,53 @@
   2:245bde4270cd (public) [ ] add original_c
   6:6f9641995072 (draft) [tip ] add n3w_3_c
 
-Try to pull markers
+Try to pull markers while testing pull --confirm
 (extinct changeset are excluded but marker are pushed)
 
-  $ hg pull ../tmpb
+  $ hg pull ../tmpb --confirm --config ui.interactive=true < n
+  > EOF
   pulling from ../tmpb
   requesting all changes
   adding changesets
   adding manifests
   adding file changes
+  adding 4 changesets with 4 changes to 4 files (+1 heads)
+  5 new obsolescence markers
+  new changesets 1f0dee641bb7:6f9641995072 (1 drafts)
+  accept incoming changes (yn)? n
+  transaction abort!
+  rollback completed
+  abort: user aborted
+  [255]
+  $ HGPLAIN=1 hg pull ../tmpb --confirm --config ui.interactive=true < n
+  > EOF
+  pulling from ../tmpb
+  requesting all changes
+  adding changesets
+  adding manifests
+  adding file changes
+  adding 4 changesets with 4 changes to 4 files (+1 heads)
+  5 new obsolescence markers
+  new changesets 1f0dee641bb7:6f9641995072 (1 drafts)
+  accept incoming changes (yn)? n
+  transaction abort!
+  rollback completed
+  abort: user aborted
+  [255]
+  $ hg pull ../tmpb --confirm --config ui.interactive=true < y
+  > EOF
+  pulling from ../tmpb
+  requesting all changes
+  adding changesets
+  adding manifests
+  adding file changes
+  adding 4 changesets with 4 changes to 4 files (+1 heads)
+  5 new obsolescence markers
+  new changesets 1f0dee641bb7:6f9641995072 (1 drafts)
+  accept incoming changes (yn)? y
   added 4 changesets with 4 changes to 4 

D8269: tests: drop an extraneous (glob) from test-debugbackupbundle.t

2020-03-11 Thread mharbison72 (Matt Harbison)
Closed by commit rHGcae7cddef4b0: tests: drop an extraneous (glob) from 
test-debugbackupbundle.t (authored by mharbison72).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8269?vs=20650=20740

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8269/new/

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

AFFECTED FILES
  tests/test-debugbackupbundle.t

CHANGE DETAILS

diff --git a/tests/test-debugbackupbundle.t b/tests/test-debugbackupbundle.t
--- a/tests/test-debugbackupbundle.t
+++ b/tests/test-debugbackupbundle.t
@@ -22,7 +22,7 @@
   $ mkcommit b
   $ hg strip .
   0 files updated, 0 files merged, 1 files removed, 0 files unresolved
-  saved backup bundle to 
$TESTTMP/repo/.hg/strip-backup/d2ae7f538514-2953539b-backup.hg (glob)
+  saved backup bundle to 
$TESTTMP/repo/.hg/strip-backup/d2ae7f538514-2953539b-backup.hg
   $ hg debugbackupbundle
   Recover changesets using: hg debugbackupbundle --recover 
   



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


D8199: scmutil: add option to register summary callbacks as transaction validators

2020-03-11 Thread pulkit (Pulkit Goyal)
Closed by commit rHGf4c01f43132a: scmutil: add option to register summary 
callbacks as transaction validators (authored by pulkit).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8199?vs=20405=20738

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8199/new/

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

AFFECTED FILES
  mercurial/scmutil.py

CHANGE DETAILS

diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py
--- a/mercurial/scmutil.py
+++ b/mercurial/scmutil.py
@@ -1900,8 +1900,11 @@
 _reportstroubledchangesets = True
 
 
-def registersummarycallback(repo, otr, txnname=b''):
+def registersummarycallback(repo, otr, txnname=b'', as_validator=False):
 """register a callback to issue a summary after the transaction is closed
+
+If as_validator is true, then the callbacks are registered as transaction
+validators instead
 """
 
 def txmatch(sources):
@@ -1927,7 +1930,10 @@
 func(repo, tr)
 
 newcat = b'%02i-txnreport' % len(categories)
-otr.addpostclose(newcat, wrapped)
+if as_validator:
+otr.addvalidator(newcat, wrapped)
+else:
+otr.addpostclose(newcat, wrapped)
 categories.append(newcat)
 return wrapped
 
@@ -1942,6 +1948,8 @@
 if cgheads:
 htext = _(b" (%+d heads)") % cgheads
 msg = _(b"added %d changesets with %d changes to %d files%s\n")
+if as_validator:
+msg = _(b"adding %d changesets with %d changes to %d 
files%s\n")
 assert repo is not None  # help pytype
 repo.ui.status(msg % (cgchangesets, cgrevisions, cgfiles, htext))
 
@@ -1954,7 +1962,10 @@
 if newmarkers:
 repo.ui.status(_(b'%i new obsolescence markers\n') % 
newmarkers)
 if obsoleted:
-repo.ui.status(_(b'obsoleted %i changesets\n') % 
len(obsoleted))
+msg = _(b'obsoleted %i changesets\n')
+if as_validator:
+msg = _(b'obsoleting %i changesets\n')
+repo.ui.status(msg % len(obsoleted))
 
 if obsolete.isenabled(
 repo, obsolete.createmarkersopt
@@ -2057,9 +2068,10 @@
 ]
 if not published:
 return
-repo.ui.status(
-_(b'%d local changesets published\n') % len(published)
-)
+msg = _(b'%d local changesets published\n')
+if as_validator:
+msg = _(b'%d local changesets will be published\n')
+repo.ui.status(msg % len(published))
 
 
 def getinstabilitymessage(delta, instability):



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


D8198: transaction: add functionality to have multiple validators

2020-03-11 Thread pulkit (Pulkit Goyal)
Closed by commit rHG14e956b8acef: transaction: add functionality to have 
multiple validators (authored by pulkit).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8198?vs=20404=20737

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8198/new/

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

AFFECTED FILES
  mercurial/transaction.py

CHANGE DETAILS

diff --git a/mercurial/transaction.py b/mercurial/transaction.py
--- a/mercurial/transaction.py
+++ b/mercurial/transaction.py
@@ -165,12 +165,6 @@
 self._journal = journalname
 self._undoname = undoname
 self._queue = []
-# A callback to validate transaction content before closing it.
-# should raise exception is anything is wrong.
-# target user is repository hooks.
-if validator is None:
-validator = lambda tr: None
-self._validator = validator
 # A callback to do something just after releasing transaction.
 if releasefn is None:
 releasefn = lambda tr, success: None
@@ -214,6 +208,11 @@
 self._anypending = False
 # holds callback to call when writing the transaction
 self._finalizecallback = {}
+# holds callback to call when validating the transaction
+# should raise exception if anything is wrong
+self._validatecallback = {}
+if validator is not None:
+self._validatecallback['001-userhooks'] = validator
 # hold callback for post transaction close
 self._postclosecallback = {}
 # holds callbacks to call during abort
@@ -506,11 +505,21 @@
 self._abortcallback[category] = callback
 
 @active
+def addvalidator(self, category, callback):
+""" adds a callback to be called when validating the transaction.
+
+The transaction will be given as the first argument to the callback.
+
+callback should raise exception if to abort transaction """
+self._validatecallback[category] = callback
+
+@active
 def close(self):
 '''commit the transaction'''
 if self._count == 1:
-self._validator(self)  # will raise exception if needed
-self._validator = None  # Help prevent cycles.
+for category in sorted(self._validatecallback):
+self._validatecallback[category](self)
+self._validatecallback = None  # Help prevent cycles.
 self._generatefiles(group=GEN_GROUP_PRE_FINALIZE)
 while self._finalizecallback:
 callbacks = self._finalizecallback



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


D8217: hgit: make sure repository is local before checking for store type

2020-03-11 Thread pulkit (Pulkit Goyal)
Closed by commit rHGa2b49606a837: hgit: make sure repository is local before 
checking for store type (authored by pulkit).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8217?vs=20493=20736

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8217/new/

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

AFFECTED FILES
  hgext/git/__init__.py

CHANGE DETAILS

diff --git a/hgext/git/__init__.py b/hgext/git/__init__.py
--- a/hgext/git/__init__.py
+++ b/hgext/git/__init__.py
@@ -230,7 +230,7 @@
 
 
 def reposetup(ui, repo):
-if isinstance(repo.store, gitstore):
+if repo.local() and isinstance(repo.store, gitstore):
 orig = repo.__class__
 repo.store._progress_factory = repo.ui.makeprogress
 



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


D8246: hg-core: add a compilation error if trying to compile outside of Linux

2020-03-11 Thread Raphaël Gomès
Closed by commit rHG5a50e8c39b82: hg-core: add a compilation error if trying to 
compile outside of Linux (authored by Alphare).
This revision was automatically updated to reflect the committed changes.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8246?vs=20542=20735

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8246/new/

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

AFFECTED FILES
  rust/hg-core/src/lib.rs

CHANGE DETAILS

diff --git a/rust/hg-core/src/lib.rs b/rust/hg-core/src/lib.rs
--- a/rust/hg-core/src/lib.rs
+++ b/rust/hg-core/src/lib.rs
@@ -23,6 +23,14 @@
 pub use revlog::*;
 pub mod utils;
 
+/// Remove this to see (potential) non-artificial compile failures. MacOS
+/// *should* compile, but fail to compile tests for example as of 2020-03-06
+#[cfg(not(target_os = "linux"))]
+compile_error!(
+"`hg-core` has only been tested on Linux and will most \
+ likely not behave correctly on other platforms."
+);
+
 use crate::utils::hg_path::HgPathBuf;
 pub use filepatterns::{
 build_single_regex, read_pattern_file, PatternSyntax, PatternTuple,



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


D8253: hg-core: add function timing information

2020-03-11 Thread Raphaël Gomès
Closed by commit rHGd880805d5442: hg-core: add function timing information 
(authored by Alphare).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8253?vs=20710=20734

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8253/new/

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

AFFECTED FILES
  rust/Cargo.lock
  rust/hg-core/Cargo.toml
  rust/hg-core/src/dirstate/parsers.rs
  rust/hg-core/src/dirstate/status.rs
  rust/hg-core/src/lib.rs
  rust/hg-core/src/matchers.rs

CHANGE DETAILS

diff --git a/rust/hg-core/src/matchers.rs b/rust/hg-core/src/matchers.rs
--- a/rust/hg-core/src/matchers.rs
+++ b/rust/hg-core/src/matchers.rs
@@ -24,6 +24,7 @@
 PatternSyntax,
 };
 
+use micro_timer::timed;
 use std::collections::HashSet;
 use std::fmt::{Display, Error, Formatter};
 use std::iter::FromIterator;
@@ -548,6 +549,7 @@
 /// Parses all "ignore" files with their recursive includes and returns a
 /// function that checks whether a given file (in the general sense) should be
 /// ignored.
+#[timed]
 pub fn get_ignore_function<'a>(
 all_pattern_files: &[impl AsRef],
 root_dir: impl AsRef,
diff --git a/rust/hg-core/src/lib.rs b/rust/hg-core/src/lib.rs
--- a/rust/hg-core/src/lib.rs
+++ b/rust/hg-core/src/lib.rs
@@ -35,6 +35,10 @@
 use std::collections::HashMap;
 use twox_hash::RandomXxHashBuilder64;
 
+/// This is a contract between the `micro-timer` crate and us, to expose
+/// the `log` crate as `crate::log`.
+use log;
+
 pub type LineNumber = usize;
 
 /// Rust's default hasher is too slow because it tries to prevent collision
diff --git a/rust/hg-core/src/dirstate/status.rs 
b/rust/hg-core/src/dirstate/status.rs
--- a/rust/hg-core/src/dirstate/status.rs
+++ b/rust/hg-core/src/dirstate/status.rs
@@ -25,6 +25,7 @@
 PatternError,
 };
 use lazy_static::lazy_static;
+use micro_timer::timed;
 use rayon::prelude::*;
 use std::{
 borrow::Cow,
@@ -211,6 +212,7 @@
 
 /// Get stat data about the files explicitly specified by match.
 /// TODO subrepos
+#[timed]
 fn walk_explicit<'a>(
 files: Option<&'a HashSet<>>,
 dmap: &'a DirstateMap,
@@ -513,6 +515,7 @@
 ///
 /// This takes a mutable reference to the results to account for the `extend`
 /// in timings
+#[timed]
 fn traverse<'a>(
 matcher: &'a (impl Matcher + Sync),
 root_dir: impl AsRef + Sync + Send + Copy,
@@ -606,6 +609,7 @@
 
 /// This takes a mutable reference to the results to account for the `extend`
 /// in timings
+#[timed]
 fn extend_from_dmap<'a>(
 dmap: &'a DirstateMap,
 root_dir: impl AsRef + Sync + Send,
@@ -630,6 +634,7 @@
 pub bad: Vec<(Cow<'a, HgPath>, BadMatch)>,
 }
 
+#[timed]
 fn build_response<'a>(
 results: impl IntoIterator, Dispatch)>,
 ) -> (Vec>, DirstateStatus<'a>) {
@@ -710,6 +715,7 @@
 
 /// This takes a mutable reference to the results to account for the `extend`
 /// in timings
+#[timed]
 fn handle_unknowns<'a>(
 dmap: &'a DirstateMap,
 matcher: &(impl Matcher + Sync),
@@ -792,6 +798,7 @@
 /// This is the current entry-point for `hg-core` and is realistically unusable
 /// outside of a Python context because its arguments need to provide a lot of
 /// information that will not be necessary in the future.
+#[timed]
 pub fn status<'a: 'c, 'b: 'c, 'c>(
 dmap: &'a DirstateMap,
 matcher: &'b (impl Matcher + Sync),
diff --git a/rust/hg-core/src/dirstate/parsers.rs 
b/rust/hg-core/src/dirstate/parsers.rs
--- a/rust/hg-core/src/dirstate/parsers.rs
+++ b/rust/hg-core/src/dirstate/parsers.rs
@@ -9,6 +9,7 @@
 DirstateEntry, DirstatePackError, DirstateParents, DirstateParseError,
 };
 use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
+use micro_timer::timed;
 use std::convert::{TryFrom, TryInto};
 use std::io::Cursor;
 use std::time::Duration;
@@ -20,6 +21,7 @@
 
 // TODO parse/pack: is mutate-on-loop better for performance?
 
+#[timed]
 pub fn parse_dirstate(
 state_map:  StateMap,
 copy_map:  CopyMap,
diff --git a/rust/hg-core/Cargo.toml b/rust/hg-core/Cargo.toml
--- a/rust/hg-core/Cargo.toml
+++ b/rust/hg-core/Cargo.toml
@@ -22,6 +22,7 @@
 twox-hash = "1.5.0"
 same-file = "1.0.6"
 crossbeam = "0.7.3"
+micro-timer = "0.1.2"
 log = "0.4.8"
 
 [dev-dependencies]
diff --git a/rust/Cargo.lock b/rust/Cargo.lock
--- a/rust/Cargo.lock
+++ b/rust/Cargo.lock
@@ -235,6 +235,7 @@
  "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "micro-timer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "pretty_assertions 0.6.1 
(registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand_pcg 0.1.2 

D8252: rust: add logging utils

2020-03-11 Thread Raphaël Gomès
Closed by commit rHG82f51ab7a2dd: rust: add logging utils (authored by Alphare).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8252?vs=20709=20733

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8252/new/

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

AFFECTED FILES
  rust/Cargo.lock
  rust/hg-core/Cargo.toml
  rust/hg-cpython/Cargo.toml
  rust/hg-cpython/src/dirstate.rs

CHANGE DETAILS

diff --git a/rust/hg-cpython/src/dirstate.rs b/rust/hg-cpython/src/dirstate.rs
--- a/rust/hg-cpython/src/dirstate.rs
+++ b/rust/hg-cpython/src/dirstate.rs
@@ -107,6 +107,8 @@
 let dotted_name = !("{}.dirstate", package);
 let m = PyModule::new(py, dotted_name)?;
 
+simple_logger::init_by_env();
+
 m.add(py, "__package__", package)?;
 m.add(py, "__doc__", "Dirstate - Rust implementation")?;
 
diff --git a/rust/hg-cpython/Cargo.toml b/rust/hg-cpython/Cargo.toml
--- a/rust/hg-cpython/Cargo.toml
+++ b/rust/hg-cpython/Cargo.toml
@@ -24,6 +24,7 @@
 [dependencies]
 hg-core = { path = "../hg-core"}
 libc = '*'
+simple_logger = "1.6.0"
 
 [dependencies.cpython]
 version = "0.4"
diff --git a/rust/hg-core/Cargo.toml b/rust/hg-core/Cargo.toml
--- a/rust/hg-core/Cargo.toml
+++ b/rust/hg-core/Cargo.toml
@@ -22,6 +22,7 @@
 twox-hash = "1.5.0"
 same-file = "1.0.6"
 crossbeam = "0.7.3"
+log = "0.4.8"
 
 [dev-dependencies]
 clap = "*"
diff --git a/rust/Cargo.lock b/rust/Cargo.lock
--- a/rust/Cargo.lock
+++ b/rust/Cargo.lock
@@ -2,10 +2,10 @@
 # It is not intended for manual editing.
 [[package]]
 name = "aho-corasick"
-version = "0.7.8"
+version = "0.7.10"
 source = "registry+https://github.com/rust-lang/crates.io-index;
 dependencies = [
- "memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -21,8 +21,8 @@
 version = "0.2.14"
 source = "registry+https://github.com/rust-lang/crates.io-index;
 dependencies = [
- "hermit-abi 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
+ "hermit-abi 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.67 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -43,18 +43,10 @@
 
 [[package]]
 name = "byteorder"
-version = "1.3.2"
+version = "1.3.4"
 source = "registry+https://github.com/rust-lang/crates.io-index;
 
 [[package]]
-name = "c2-chacha"
-version = "0.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index;
-dependencies = [
- "ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
 name = "cc"
 version = "1.0.50"
 source = "registry+https://github.com/rust-lang/crates.io-index;
@@ -65,6 +57,16 @@
 source = "registry+https://github.com/rust-lang/crates.io-index;
 
 [[package]]
+name = "chrono"
+version = "0.4.11"
+source = "registry+https://github.com/rust-lang/crates.io-index;
+dependencies = [
+ "num-integer 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "clap"
 version = "2.33.0"
 source = "registry+https://github.com/rust-lang/crates.io-index;
@@ -87,11 +89,21 @@
 ]
 
 [[package]]
+name = "colored"
+version = "1.9.3"
+source = "registry+https://github.com/rust-lang/crates.io-index;
+dependencies = [
+ "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "cpython"
 version = "0.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index;
 dependencies = [
- "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.67 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "python27-sys 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "python3-sys 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -104,10 +116,10 @@
 dependencies = [
  "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "crossbeam-channel 0.4.2 
(registry+https://github.com/rust-lang/crates.io-index)",
- "crossbeam-deque 0.7.2 
(registry+https://github.com/rust-lang/crates.io-index)",
- "crossbeam-epoch 0.8.0 
(registry+https://github.com/rust-lang/crates.io-index)",
+ "crossbeam-deque 0.7.3 
(registry+https://github.com/rust-lang/crates.io-index)",
+ "crossbeam-epoch 0.8.2 

D8251: rust-status: traverse working directory in parallel

2020-03-11 Thread Raphaël Gomès
Closed by commit rHGfe7d2cf0b429: rust-status: traverse working directory in 
parallel (authored by Alphare).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8251?vs=20708=20732

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8251/new/

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

AFFECTED FILES
  rust/Cargo.lock
  rust/hg-core/Cargo.toml
  rust/hg-core/src/dirstate/status.rs

CHANGE DETAILS

diff --git a/rust/hg-core/src/dirstate/status.rs 
b/rust/hg-core/src/dirstate/status.rs
--- a/rust/hg-core/src/dirstate/status.rs
+++ b/rust/hg-core/src/dirstate/status.rs
@@ -300,61 +300,55 @@
 }
 
 /// Dispatch a single entry (file, folder, symlink...) found during `traverse`.
-/// If the entry is a folder that needs to be traversed, it will be pushed into
-/// `work`.
+/// If the entry is a folder that needs to be traversed, it will be handled
+/// in a separate thread.
+
 fn handle_traversed_entry<'a>(
-dir_entry: ,
-matcher: &(impl Matcher + Sync),
-root_dir: impl AsRef,
-dmap: ,
-filename: impl AsRef,
-old_results: , Dispatch>,
-ignore_fn: &(impl for<'r> Fn(&'r HgPath) -> bool + Sync),
-dir_ignore_fn: &(impl for<'r> Fn(&'r HgPath) -> bool + Sync),
+scope: ::Scope<'a>,
+files_sender: &'a crossbeam::Sender>,
+matcher: &'a (impl Matcher + Sync),
+root_dir: impl AsRef + Sync + Send + Copy + 'a,
+dmap: &'a DirstateMap,
+old_results: &'a FastHashMap, Dispatch>,
+ignore_fn: &'a (impl for<'r> Fn(&'r HgPath) -> bool + Sync),
+dir_ignore_fn: &'a (impl for<'r> Fn(&'r HgPath) -> bool + Sync),
 options: StatusOptions,
-) -> IoResult, Dispatch)>> {
+filename: HgPathBuf,
+dir_entry: DirEntry,
+) -> IoResult<()> {
 let file_type = dir_entry.file_type()?;
-let filename = filename.as_ref();
-let entry_option = dmap.get(filename);
+let entry_option = dmap.get();
 
 if file_type.is_dir() {
-// Do we need to traverse it?
-if !ignore_fn() || options.list_ignored {
-return traverse_dir(
-matcher,
-root_dir,
-dmap,
-filename.to_owned(),
-_results,
-ignore_fn,
-dir_ignore_fn,
-options,
-);
-}
-// Nested `if` until `rust-lang/rust#53668` is stable
-if let Some(entry) = entry_option {
-// Used to be a file, is now a folder
-if matcher.matches_everything() || matcher.matches() {
-return Ok(vec![(
-Cow::Owned(filename.to_owned()),
-dispatch_missing(entry.state),
-)]);
-}
-}
+handle_traversed_dir(
+scope,
+files_sender,
+matcher,
+root_dir,
+dmap,
+old_results,
+ignore_fn,
+dir_ignore_fn,
+options,
+entry_option,
+filename,
+);
 } else if file_type.is_file() || file_type.is_symlink() {
 if let Some(entry) = entry_option {
 if matcher.matches_everything() || matcher.matches() {
 let metadata = dir_entry.metadata()?;
-return Ok(vec![(
-Cow::Owned(filename.to_owned()),
-dispatch_found(
-,
-*entry,
-HgMetadata::from_metadata(metadata),
-_map,
-options,
-),
-)]);
+files_sender
+.send(Ok((
+filename.to_owned(),
+dispatch_found(
+,
+*entry,
+HgMetadata::from_metadata(metadata),
+_map,
+options,
+),
+)))
+.unwrap();
 }
 } else if (matcher.matches_everything() || matcher.matches())
 && !ignore_fn()
@@ -363,53 +357,96 @@
 && dir_ignore_fn()
 {
 if options.list_ignored {
-return Ok(vec![(
-Cow::Owned(filename.to_owned()),
-Dispatch::Ignored,
-)]);
+files_sender
+.send(Ok((filename.to_owned(), Dispatch::Ignored)))
+.unwrap();
 }
 } else {
-return Ok(vec![(
-Cow::Owned(filename.to_owned()),
-Dispatch::Unknown,
-)]);
+

D8250: rust-status: wrap `stat_dmap_entries` to ease profiling

2020-03-11 Thread Raphaël Gomès
Closed by commit rHGb8ba46c97cdd: rust-status: wrap `stat_dmap_entries` to ease 
profiling (authored by Alphare).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8250?vs=20564=20731

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8250/new/

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

AFFECTED FILES
  rust/hg-core/src/dirstate/status.rs

CHANGE DETAILS

diff --git a/rust/hg-core/src/dirstate/status.rs 
b/rust/hg-core/src/dirstate/status.rs
--- a/rust/hg-core/src/dirstate/status.rs
+++ b/rust/hg-core/src/dirstate/status.rs
@@ -508,6 +508,21 @@
 })
 }
 
+/// This takes a mutable reference to the results to account for the `extend`
+/// in timings
+fn extend_from_dmap<'a>(
+dmap: &'a DirstateMap,
+root_dir: impl AsRef + Sync + Send,
+options: StatusOptions,
+results:  Vec<(Cow<'a, HgPath>, Dispatch)>,
+) {
+results.par_extend(
+stat_dmap_entries(dmap, root_dir, options)
+.flatten()
+.map(|(filename, dispatch)| (Cow::Borrowed(filename), dispatch)),
+);
+}
+
 pub struct DirstateStatus<'a> {
 pub modified: Vec>,
 pub added: Vec>,
@@ -766,10 +781,7 @@
 } else {
 // We may not have walked the full directory tree above, so stat
 // and check everything we missed.
-let stat_results = stat_dmap_entries(, root_dir, options);
-results.par_extend(stat_results.flatten().map(
-|(filename, dispatch)| (Cow::Borrowed(filename), dispatch),
-));
+extend_from_dmap(, root_dir, options,  results);
 }
 }
 



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


D8226: debuginstall: add entry about re2 Rust bindings when applicable

2020-03-11 Thread Raphaël Gomès
Closed by commit rHGc989737158aa: debuginstall: add entry about re2 Rust 
bindings when applicable (authored by Alphare).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8226?vs=20707=20725

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8226/new/

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

AFFECTED FILES
  mercurial/debugcommands.py
  tests/test-install.t

CHANGE DETAILS

diff --git a/tests/test-install.t b/tests/test-install.t
--- a/tests/test-install.t
+++ b/tests/test-install.t
@@ -18,6 +18,7 @@
   checking available compression engines (*zlib*) (glob)
   checking available compression engines for wire protocol (*zlib*) (glob)
   checking "re2" regexp engine \((available|missing)\) (re)
+  checking "re2" regexp engine Rust bindings \((installed|missing)\) (re)
   checking templates (*mercurial?templates)... (glob)
   checking default template (*mercurial?templates?map-cmdline.default) (glob)
   checking commit editor... (*) (glob)
@@ -77,6 +78,7 @@
   checking available compression engines (*zlib*) (glob)
   checking available compression engines for wire protocol (*zlib*) (glob)
   checking "re2" regexp engine \((available|missing)\) (re)
+  checking "re2" regexp engine Rust bindings \((installed|missing)\) (re)
   checking templates (*mercurial?templates)... (glob)
   checking default template (*mercurial?templates?map-cmdline.default) (glob)
   checking commit editor... (*) (glob)
@@ -124,6 +126,7 @@
   checking available compression engines (*zlib*) (glob)
   checking available compression engines for wire protocol (*zlib*) (glob)
   checking "re2" regexp engine \((available|missing)\) (re)
+  checking "re2" regexp engine Rust bindings \((installed|missing)\) (re)
   checking templates (*mercurial?templates)... (glob)
   checking default template (*mercurial?templates?map-cmdline.default) (glob)
   checking commit editor... ($TESTTMP/tools/testeditor.exe)
@@ -151,6 +154,7 @@
   checking available compression engines (*zlib*) (glob)
   checking available compression engines for wire protocol (*zlib*) (glob)
   checking "re2" regexp engine \((available|missing)\) (re)
+  checking "re2" regexp engine Rust bindings \((installed|missing)\) (re)
   checking templates (*mercurial?templates)... (glob)
   checking default template (*mercurial?templates?map-cmdline.default) (glob)
   checking commit editor... (c:\foo\bar\baz.exe) (windows !)
@@ -207,6 +211,7 @@
   checking available compression engines (*) (glob)
   checking available compression engines for wire protocol (*) (glob)
   checking "re2" regexp engine \((available|missing)\) (re)
+  checking "re2" regexp engine Rust bindings \((installed|missing)\) (re)
   checking templates 
($TESTTMP/installenv/*/site-packages/mercurial/templates)... (glob)
   checking default template 
($TESTTMP/installenv/*/site-packages/mercurial/templates/map-cmdline.default) 
(glob)
   checking commit editor... (*) (glob)
@@ -247,6 +252,7 @@
   checking available compression engines (*) (glob)
   checking available compression engines for wire protocol (*) (glob)
   checking "re2" regexp engine \((available|missing)\) (re)
+  checking "re2" regexp engine Rust bindings \((installed|missing)\) (re)
   checking templates 
($TESTTMP/installenv/*/site-packages/mercurial/templates)... (glob)
   checking default template 
($TESTTMP/installenv/*/site-packages/mercurial/templates/map-cmdline.default) 
(glob)
   checking commit editor... (*) (glob)
diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py
--- a/mercurial/debugcommands.py
+++ b/mercurial/debugcommands.py
@@ -1650,6 +1650,13 @@
 fm.plain(_(b'checking "re2" regexp engine (%s)\n') % re2)
 fm.data(re2=bool(util._re2))
 
+rust_debug_mod = policy.importrust("debug")
+if rust_debug_mod is not None:
+re2_rust = b'installed' if rust_debug_mod.re2_installed else b'missing'
+
+msg = b'checking "re2" regexp engine Rust bindings (%s)\n'
+fm.plain(_(msg % re2_rust))
+
 # templates
 p = templater.templatepaths()
 fm.write(b'templatedirs', b'checking templates (%s)...\n', b' '.join(p))



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


D8213: rust-pathauditor: use interior mutability for use in multi-threaded contexts

2020-03-11 Thread Raphaël Gomès
Closed by commit rHG07d9fd6097e6: rust-pathauditor: use interior mutability for 
use in multi-threaded contexts (authored by Alphare).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8213?vs=20499=20728

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8213/new/

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

AFFECTED FILES
  rust/hg-core/src/dirstate/status.rs
  rust/hg-core/src/utils/files.rs
  rust/hg-core/src/utils/path_auditor.rs

CHANGE DETAILS

diff --git a/rust/hg-core/src/utils/path_auditor.rs 
b/rust/hg-core/src/utils/path_auditor.rs
--- a/rust/hg-core/src/utils/path_auditor.rs
+++ b/rust/hg-core/src/utils/path_auditor.rs
@@ -13,13 +13,14 @@
 };
 use std::collections::HashSet;
 use std::path::{Path, PathBuf};
+use std::sync::{Mutex, RwLock};
 
 /// Ensures that a path is valid for use in the repository i.e. does not use
 /// any banned components, does not traverse a symlink, etc.
 #[derive(Debug, Default)]
 pub struct PathAuditor {
-audited: HashSet,
-audited_dirs: HashSet,
+audited: Mutex>,
+audited_dirs: RwLock>,
 root: PathBuf,
 }
 
@@ -31,7 +32,7 @@
 }
 }
 pub fn audit_path(
- self,
+,
 path: impl AsRef,
 ) -> Result<(), HgPathError> {
 // TODO windows "localpath" normalization
@@ -40,7 +41,7 @@
 return Ok(());
 }
 // TODO case normalization
-if self.audited.contains(path) {
+if self.audited.lock().unwrap().contains(path) {
 return Ok(());
 }
 // AIX ignores "/" at end of path, others raise EISDIR.
@@ -113,14 +114,14 @@
 for index in 0..parts.len() {
 let prefix = [..index + 1].join('/');
 let prefix = HgPath::new(prefix);
-if self.audited_dirs.contains(prefix) {
+if self.audited_dirs.read().unwrap().contains(prefix) {
 continue;
 }
 self.check_filesystem(, )?;
-self.audited_dirs.insert(prefix.to_owned());
+self.audited_dirs.write().unwrap().insert(prefix.to_owned());
 }
 
-self.audited.insert(path.to_owned());
+self.audited.lock().unwrap().insert(path.to_owned());
 
 Ok(())
 }
@@ -171,7 +172,7 @@
 Ok(())
 }
 
-pub fn check( self, path: impl AsRef) -> bool {
+pub fn check(, path: impl AsRef) -> bool {
 self.audit_path(path).is_ok()
 }
 }
@@ -184,7 +185,7 @@
 
 #[test]
 fn test_path_auditor() {
-let mut auditor = PathAuditor::new(get_path_from_bytes(b"/tmp"));
+let auditor = PathAuditor::new(get_path_from_bytes(b"/tmp"));
 
 let path = HgPath::new(b".hg/00changelog.i");
 assert_eq!(
diff --git a/rust/hg-core/src/utils/files.rs b/rust/hg-core/src/utils/files.rs
--- a/rust/hg-core/src/utils/files.rs
+++ b/rust/hg-core/src/utils/files.rs
@@ -210,7 +210,7 @@
 } else {
 name.to_owned()
 };
-let mut auditor = PathAuditor::new();
+let auditor = PathAuditor::new();
 if name != root && name.starts_with() {
 let name = name.strip_prefix().unwrap();
 auditor.audit_path(path_to_hg_path_buf(name)?)?;
diff --git a/rust/hg-core/src/dirstate/status.rs 
b/rust/hg-core/src/dirstate/status.rs
--- a/rust/hg-core/src/dirstate/status.rs
+++ b/rust/hg-core/src/dirstate/status.rs
@@ -698,7 +698,7 @@
 // We walked all dirs under the roots that weren't ignored, and
 // everything that matched was stat'ed and is already in results.
 // The rest must thus be ignored or under a symlink.
-let mut path_auditor = PathAuditor::new(root_dir);
+let path_auditor = PathAuditor::new(root_dir);
 
 for (ref filename, entry) in to_visit {
 // Report ignored items in the dmap as long as they are not



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


D8215: rust-status: move to recursive traversal to prepare for parallel traversal

2020-03-11 Thread Raphaël Gomès
Closed by commit rHGf8a9922a02cb: rust-status: move to recursive traversal to 
prepare for parallel traversal (authored by Alphare).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8215?vs=20561=20729

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8215/new/

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

AFFECTED FILES
  rust/hg-core/src/dirstate/status.rs

CHANGE DETAILS

diff --git a/rust/hg-core/src/dirstate/status.rs 
b/rust/hg-core/src/dirstate/status.rs
--- a/rust/hg-core/src/dirstate/status.rs
+++ b/rust/hg-core/src/dirstate/status.rs
@@ -26,7 +26,6 @@
 };
 use lazy_static::lazy_static;
 use rayon::prelude::*;
-use std::collections::VecDeque;
 use std::{
 borrow::Cow,
 collections::HashSet,
@@ -38,7 +37,7 @@
 
 /// Wrong type of file from a `BadMatch`
 /// Note: a lot of those don't exist on all platforms.
-#[derive(Debug)]
+#[derive(Debug, Copy, Clone)]
 pub enum BadType {
 CharacterDevice,
 BlockDevice,
@@ -63,7 +62,7 @@
 }
 
 /// Was explicitly matched but cannot be found/accessed
-#[derive(Debug)]
+#[derive(Debug, Copy, Clone)]
 pub enum BadMatch {
 OsError(i32),
 BadType(BadType),
@@ -72,7 +71,7 @@
 /// Marker enum used to dispatch new status entries into the right collections.
 /// Is similar to `crate::EntryState`, but represents the transient state of
 /// entries during the lifetime of a command.
-#[derive(Debug)]
+#[derive(Debug, Copy, Clone)]
 enum Dispatch {
 Unsure,
 Modified,
@@ -300,49 +299,53 @@
 pub list_ignored: bool,
 }
 
-/// Dispatch a single file found during `traverse`.
-/// If `file` is a folder that needs to be traversed, it will be pushed into
+/// Dispatch a single entry (file, folder, symlink...) found during `traverse`.
+/// If the entry is a folder that needs to be traversed, it will be pushed into
 /// `work`.
-fn traverse_worker<'a>(
-work:  VecDeque,
-matcher:  Matcher,
+fn handle_traversed_entry<'a>(
+dir_entry: ,
+matcher: &(impl Matcher + Sync),
+root_dir: impl AsRef,
 dmap: ,
 filename: impl AsRef,
-dir_entry: ,
-ignore_fn:  for<'r> Fn(&'r HgPath) -> bool,
-dir_ignore_fn:  for<'r> Fn(&'r HgPath) -> bool,
+old_results: , Dispatch>,
+ignore_fn: &(impl for<'r> Fn(&'r HgPath) -> bool + Sync),
+dir_ignore_fn: &(impl for<'r> Fn(&'r HgPath) -> bool + Sync),
 options: StatusOptions,
-) -> Option, Dispatch)>> {
-let file_type = match dir_entry.file_type() {
-Ok(x) => x,
-Err(e) => return Some(Err(e.into())),
-};
+) -> IoResult, Dispatch)>> {
+let file_type = dir_entry.file_type()?;
 let filename = filename.as_ref();
 let entry_option = dmap.get(filename);
 
 if file_type.is_dir() {
 // Do we need to traverse it?
 if !ignore_fn() || options.list_ignored {
-work.push_front(filename.to_owned());
+return traverse_dir(
+matcher,
+root_dir,
+dmap,
+filename.to_owned(),
+_results,
+ignore_fn,
+dir_ignore_fn,
+options,
+);
 }
 // Nested `if` until `rust-lang/rust#53668` is stable
 if let Some(entry) = entry_option {
 // Used to be a file, is now a folder
 if matcher.matches_everything() || matcher.matches() {
-return Some(Ok((
+return Ok(vec![(
 Cow::Owned(filename.to_owned()),
 dispatch_missing(entry.state),
-)));
+)]);
 }
 }
 } else if file_type.is_file() || file_type.is_symlink() {
 if let Some(entry) = entry_option {
 if matcher.matches_everything() || matcher.matches() {
-let metadata = match dir_entry.metadata() {
-Ok(x) => x,
-Err(e) => return Some(Err(e.into())),
-};
-return Some(Ok((
+let metadata = dir_entry.metadata()?;
+return Ok(vec![(
 Cow::Owned(filename.to_owned()),
 dispatch_found(
 ,
@@ -351,7 +354,7 @@
 _map,
 options,
 ),
-)));
+)]);
 }
 } else if (matcher.matches_everything() || matcher.matches())
 && !ignore_fn()
@@ -360,113 +363,105 @@
 && dir_ignore_fn()
 {
 if options.list_ignored {
-return Some(Ok((
+return Ok(vec![(
 Cow::Owned(filename.to_owned()),
 Dispatch::Ignored,
-)));
+   

D8249: rust-status: refactor handling of unknown files

2020-03-11 Thread Raphaël Gomès
Closed by commit rHG5f6a504dc0bd: rust-status: refactor handling of unknown 
files (authored by Alphare).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8249?vs=20563=20730

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8249/new/

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

AFFECTED FILES
  rust/hg-core/src/dirstate/status.rs

CHANGE DETAILS

diff --git a/rust/hg-core/src/dirstate/status.rs 
b/rust/hg-core/src/dirstate/status.rs
--- a/rust/hg-core/src/dirstate/status.rs
+++ b/rust/hg-core/src/dirstate/status.rs
@@ -597,6 +597,85 @@
 }
 }
 
+/// This takes a mutable reference to the results to account for the `extend`
+/// in timings
+fn handle_unknowns<'a>(
+dmap: &'a DirstateMap,
+matcher: &(impl Matcher + Sync),
+root_dir: impl AsRef + Sync + Send + Copy,
+options: StatusOptions,
+results:  Vec<(Cow<'a, HgPath>, Dispatch)>,
+) -> IoResult<()> {
+let to_visit: Vec<(, )> = if results.is_empty()
+&& matcher.matches_everything()
+{
+dmap.iter().map(|(f, e)| (f.deref(), e)).collect()
+} else {
+// Only convert to a hashmap if needed.
+let old_results: FastHashMap<_, _> = results.iter().cloned().collect();
+dmap.iter()
+.filter_map(move |(f, e)| {
+if !old_results.contains_key(f.deref()) && matcher.matches(f) {
+Some((f.deref(), e))
+} else {
+None
+}
+})
+.collect()
+};
+
+// We walked all dirs under the roots that weren't ignored, and
+// everything that matched was stat'ed and is already in results.
+// The rest must thus be ignored or under a symlink.
+let path_auditor = PathAuditor::new(root_dir);
+
+// TODO don't collect. Find a way of replicating the behavior of
+// `itertools::process_results`, but for `rayon::ParallelIterator`
+let new_results: IoResult> = to_visit
+.into_par_iter()
+.filter_map(|(filename, entry)| -> Option> {
+// Report ignored items in the dmap as long as they are not
+// under a symlink directory.
+if path_auditor.check(filename) {
+// TODO normalize for case-insensitive filesystems
+let buf = match hg_path_to_path_buf(filename) {
+Ok(x) => x,
+Err(e) => return Some(Err(e.into())),
+};
+Some(Ok((
+Cow::Borrowed(filename),
+match root_dir.as_ref().join().symlink_metadata() {
+// File was just ignored, no links, and exists
+Ok(meta) => {
+let metadata = HgMetadata::from_metadata(meta);
+dispatch_found(
+filename,
+*entry,
+metadata,
+_map,
+options,
+)
+}
+// File doesn't exist
+Err(_) => dispatch_missing(entry.state),
+},
+)))
+} else {
+// It's either missing or under a symlink directory which
+// we, in this case, report as missing.
+Some(Ok((
+Cow::Borrowed(filename),
+dispatch_missing(entry.state),
+)))
+}
+})
+.collect();
+
+results.par_extend(new_results?);
+
+Ok(())
+}
+
 /// Get the status of files in the working directory.
 ///
 /// This is the current entry-point for `hg-core` and is realistically unusable
@@ -683,64 +762,7 @@
 // symlink directory.
 
 if options.list_unknown {
-let to_visit: Box> =
-if results.is_empty() && matcher.matches_everything() {
-Box::new(dmap.iter().map(|(f, e)| (f.deref(), e)))
-} else {
-// Only convert to a hashmap if needed.
-let old_results: FastHashMap<_, _> =
-results.iter().cloned().collect();
-Box::new(dmap.iter().filter_map(move |(f, e)| {
-if !old_results.contains_key(f.deref())
-&& matcher.matches(f)
-{
-Some((f.deref(), e))
-} else {
-None
-}
-}))
-};
-let mut to_visit: Vec<_> = to_visit.collect();
-to_visit.sort_by(|a, b| a.0.cmp());
-
-// 

D8212: rust-pathauditor: actually populate the `audited_dirs` cache

2020-03-11 Thread Raphaël Gomès
Closed by commit rHG8a237131ff0f: rust-pathauditor: actually populate the 
`audited_dirs` cache (authored by Alphare).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8212?vs=20447=20727

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8212/new/

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

AFFECTED FILES
  rust/hg-core/src/utils/path_auditor.rs

CHANGE DETAILS

diff --git a/rust/hg-core/src/utils/path_auditor.rs 
b/rust/hg-core/src/utils/path_auditor.rs
--- a/rust/hg-core/src/utils/path_auditor.rs
+++ b/rust/hg-core/src/utils/path_auditor.rs
@@ -117,6 +117,7 @@
 continue;
 }
 self.check_filesystem(, )?;
+self.audited_dirs.insert(prefix.to_owned());
 }
 
 self.audited.insert(path.to_owned());



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


D7931: rust-status: use bare hg status fastpath from Python

2020-03-11 Thread Raphaël Gomès
Closed by commit rHG4d1634e59f13: rust-status: use bare hg status fastpath from 
Python (authored by Alphare).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7931?vs=20706=20723

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7931/new/

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

AFFECTED FILES
  mercurial/dirstate.py
  mercurial/match.py
  tests/test-subrepo-deep-nested-change.t

CHANGE DETAILS

diff --git a/tests/test-subrepo-deep-nested-change.t 
b/tests/test-subrepo-deep-nested-change.t
--- a/tests/test-subrepo-deep-nested-change.t
+++ b/tests/test-subrepo-deep-nested-change.t
@@ -355,6 +355,11 @@
   R sub1/sub2/folder/test.txt
   ! sub1/.hgsub
   ? sub1/x.hgsub
+  $ hg status -R sub1
+  warning: subrepo spec file 'sub1/.hgsub' not found
+  R .hgsubstate
+  ! .hgsub
+  ? x.hgsub
   $ mv sub1/x.hgsub sub1/.hgsub
   $ hg update -Cq
   $ touch sub1/foo
diff --git a/mercurial/match.py b/mercurial/match.py
--- a/mercurial/match.py
+++ b/mercurial/match.py
@@ -666,7 +666,10 @@
 class includematcher(basematcher):
 def __init__(self, root, kindpats, badfn=None):
 super(includematcher, self).__init__(badfn)
-
+if rustmod is not None:
+# We need to pass the patterns to Rust because they can contain
+# patterns from the user interface
+self._kindpats = kindpats
 self._pats, self.matchfn = _buildmatch(kindpats, b'(?:/|$)', root)
 self._prefix = _prefix(kindpats)
 roots, dirs, parents = _rootsdirsandparents(kindpats)
diff --git a/mercurial/dirstate.py b/mercurial/dirstate.py
--- a/mercurial/dirstate.py
+++ b/mercurial/dirstate.py
@@ -27,6 +27,7 @@
 policy,
 pycompat,
 scmutil,
+sparse,
 txnutil,
 util,
 )
@@ -1083,7 +1084,7 @@
 results[next(iv)] = st
 return results
 
-def _rust_status(self, matcher, list_clean):
+def _rust_status(self, matcher, list_clean, list_ignored, list_unknown):
 # Force Rayon (Rust parallelism library) to respect the number of
 # workers. This is a temporary workaround until Rust code knows
 # how to read the config file.
@@ -1101,16 +1102,45 @@
 added,
 removed,
 deleted,
+clean,
+ignored,
 unknown,
-clean,
+warnings,
+bad,
 ) = rustmod.status(
 self._map._rustmap,
 matcher,
 self._rootdir,
-bool(list_clean),
+self._ignorefiles(),
+self._checkexec,
 self._lastnormaltime,
-self._checkexec,
+bool(list_clean),
+bool(list_ignored),
+bool(list_unknown),
 )
+if self._ui.warn:
+for item in warnings:
+if isinstance(item, tuple):
+file_path, syntax = item
+msg = _(b"%s: ignoring invalid syntax '%s'\n") % (
+file_path,
+syntax,
+)
+self._ui.warn(msg)
+else:
+msg = _(b"skipping unreadable pattern file '%s': %s\n")
+self._ui.warn(
+msg
+% (
+pathutil.canonpath(
+self._rootdir, self._rootdir, item
+),
+b"No such file or directory",
+)
+)
+
+for (fn, message) in bad:
+matcher.bad(fn, encoding.strtolocal(message))
 
 status = scmutil.status(
 modified=modified,
@@ -1118,7 +1148,7 @@
 removed=removed,
 deleted=deleted,
 unknown=unknown,
-ignored=[],
+ignored=ignored,
 clean=clean,
 )
 return (lookup, status)
@@ -1148,26 +1178,34 @@
 
 use_rust = True
 
-allowed_matchers = (matchmod.alwaysmatcher, matchmod.exactmatcher)
+allowed_matchers = (
+matchmod.alwaysmatcher,
+matchmod.exactmatcher,
+matchmod.includematcher,
+)
 
 if rustmod is None:
 use_rust = False
+elif self._checkcase:
+# Case-insensitive filesystems are not handled yet
+use_rust = False
 elif subrepos:
 use_rust = False
-elif bool(listunknown):
-# Pathauditor does not exist yet in Rust, unknown files
-# can't be trusted.
+elif sparse.enabled:
 use_rust = False
-elif self._ignorefiles() and listignored:
-# Rust has no ignore mechanism yet, so don't use Rust 

D8211: rust-pathauditor: actually split Windows shortname aliases at `~`

2020-03-11 Thread Raphaël Gomès
Closed by commit rHGe63b4a1f2271: rust-pathauditor: actually split Windows 
shortname aliases at `~` (authored by Alphare).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8211?vs=20446=20726

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8211/new/

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

AFFECTED FILES
  rust/hg-core/src/utils/path_auditor.rs

CHANGE DETAILS

diff --git a/rust/hg-core/src/utils/path_auditor.rs 
b/rust/hg-core/src/utils/path_auditor.rs
--- a/rust/hg-core/src/utils/path_auditor.rs
+++ b/rust/hg-core/src/utils/path_auditor.rs
@@ -67,7 +67,7 @@
 // Windows shortname aliases
 for part in parts.iter() {
 if part.contains('~') {
-let mut split = part.splitn(1, |b| *b == b'~');
+let mut split = part.splitn(2, |b| *b == b'~');
 let first =
 split.next().unwrap().to_owned().to_ascii_uppercase();
 let last = split.next().unwrap();



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


D7930: rust-status: update rust-cpython bridge to account for the changes in core

2020-03-11 Thread Raphaël Gomès
Closed by commit rHGf96b28aa4b79: rust-status: update rust-cpython bridge to 
account for the changes in core (authored by Alphare).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7930?vs=20498=20722

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7930/new/

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

AFFECTED FILES
  rust/hg-core/src/dirstate/status.rs
  rust/hg-cpython/src/dirstate.rs
  rust/hg-cpython/src/dirstate/status.rs
  rust/hg-cpython/src/exceptions.rs

CHANGE DETAILS

diff --git a/rust/hg-cpython/src/exceptions.rs 
b/rust/hg-cpython/src/exceptions.rs
--- a/rust/hg-cpython/src/exceptions.rs
+++ b/rust/hg-cpython/src/exceptions.rs
@@ -40,3 +40,5 @@
 }
 
 py_exception!(rustext, HgPathPyError, RuntimeError);
+py_exception!(rustext, FallbackError, RuntimeError);
+py_exception!(shared_ref, AlreadyBorrowed, RuntimeError);
diff --git a/rust/hg-cpython/src/dirstate/status.rs 
b/rust/hg-cpython/src/dirstate/status.rs
--- a/rust/hg-cpython/src/dirstate/status.rs
+++ b/rust/hg-cpython/src/dirstate/status.rs
@@ -9,33 +9,34 @@
 //! `hg-core` crate. From Python, this will be seen as
 //! `rustext.dirstate.status`.
 
-use crate::dirstate::DirstateMap;
-use cpython::exc::ValueError;
+use crate::{dirstate::DirstateMap, exceptions::FallbackError};
 use cpython::{
-ObjectProtocol, PyBytes, PyErr, PyList, PyObject, PyResult, PyTuple,
-Python, PythonObject, ToPyObject,
+exc::ValueError, ObjectProtocol, PyBytes, PyErr, PyList, PyObject,
+PyResult, PyTuple, Python, PythonObject, ToPyObject,
 };
-use hg::utils::hg_path::HgPathBuf;
 use hg::{
-matchers::{AlwaysMatcher, FileMatcher},
-status,
-utils::{files::get_path_from_bytes, hg_path::HgPath},
-DirstateStatus,
+matchers::{AlwaysMatcher, FileMatcher, IncludeMatcher},
+parse_pattern_syntax, status,
+utils::{
+files::{get_bytes_from_path, get_path_from_bytes},
+hg_path::{HgPath, HgPathBuf},
+},
+BadMatch, DirstateStatus, IgnorePattern, PatternFileWarning, StatusError,
+StatusOptions,
 };
-use std::borrow::Borrow;
+use std::borrow::{Borrow, Cow};
 
 /// This will be useless once trait impls for collection are added to `PyBytes`
 /// upstream.
-fn collect_pybytes_list>(
+fn collect_pybytes_list(
 py: Python,
-collection: &[P],
+collection: &[impl AsRef],
 ) -> PyList {
 let list = PyList::new(py, &[]);
 
-for (i, path) in collection.iter().enumerate() {
-list.insert(
+for path in collection.iter() {
+list.append(
 py,
-i,
 PyBytes::new(py, path.as_ref().as_bytes()).into_object(),
 )
 }
@@ -43,34 +44,97 @@
 list
 }
 
+fn collect_bad_matches(
+py: Python,
+collection: &[(impl AsRef, BadMatch)],
+) -> PyResult {
+let list = PyList::new(py, &[]);
+
+let os = py.import("os")?;
+let get_error_message = |code: i32| -> PyResult<_> {
+os.call(
+py,
+"strerror",
+PyTuple::new(py, &[code.to_py_object(py).into_object()]),
+None,
+)
+};
+
+for (path, bad_match) in collection.iter() {
+let message = match bad_match {
+BadMatch::OsError(code) => get_error_message(*code)?,
+BadMatch::BadType(bad_type) => format!(
+"unsupported file type (type is {})",
+bad_type.to_string()
+)
+.to_py_object(py)
+.into_object(),
+};
+list.append(
+py,
+(PyBytes::new(py, path.as_ref().as_bytes()), message)
+.to_py_object(py)
+.into_object(),
+)
+}
+
+Ok(list)
+}
+
+fn handle_fallback(py: Python, err: StatusError) -> PyErr {
+match err {
+StatusError::Pattern(e) => {
+PyErr::new::(py, e.to_string())
+}
+e => PyErr::new::(py, e.to_string()),
+}
+}
+
 pub fn status_wrapper(
 py: Python,
 dmap: DirstateMap,
 matcher: PyObject,
 root_dir: PyObject,
-list_clean: bool,
+ignore_files: PyList,
+check_exec: bool,
 last_normal_time: i64,
-check_exec: bool,
-) -> PyResult<(PyList, PyList, PyList, PyList, PyList, PyList, PyList)> {
+list_clean: bool,
+list_ignored: bool,
+list_unknown: bool,
+) -> PyResult {
 let bytes = root_dir.extract::(py)?;
 let root_dir = get_path_from_bytes(bytes.data(py));
 
 let dmap: DirstateMap = dmap.to_py_object(py);
 let dmap = dmap.get_inner(py);
 
+let ignore_files: PyResult> = ignore_files
+.iter(py)
+.map(|b| {
+let file = b.extract::(py)?;
+Ok(get_path_from_bytes(file.data(py)).to_owned())
+})
+.collect();
+let ignore_files = ignore_files?;
+
 match 

D8225: rust-cpython: add `debug` module to expose debug information to Python

2020-03-11 Thread Raphaël Gomès
Closed by commit rHGd4f19eb471ca: rust-cpython: add `debug` module to expose 
debug information to Python (authored by Alphare).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8225?vs=20503=20724

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8225/new/

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

AFFECTED FILES
  rust/hg-cpython/src/debug.rs
  rust/hg-cpython/src/lib.rs

CHANGE DETAILS

diff --git a/rust/hg-cpython/src/lib.rs b/rust/hg-cpython/src/lib.rs
--- a/rust/hg-cpython/src/lib.rs
+++ b/rust/hg-cpython/src/lib.rs
@@ -30,6 +30,7 @@
 #[macro_use]
 pub mod ref_sharing;
 pub mod dagops;
+pub mod debug;
 pub mod dirstate;
 pub mod discovery;
 pub mod exceptions;
@@ -47,6 +48,7 @@
 let dotted_name: String = m.get(py, "__name__")?.extract(py)?;
 m.add(py, "ancestor", ancestors::init_module(py, _name)?)?;
 m.add(py, "dagop", dagops::init_module(py, _name)?)?;
+m.add(py, "debug", debug::init_module(py, _name)?)?;
 m.add(py, "discovery", discovery::init_module(py, _name)?)?;
 m.add(py, "dirstate", dirstate::init_module(py, _name)?)?;
 m.add(py, "revlog", revlog::init_module(py, _name)?)?;
diff --git a/rust/hg-cpython/src/debug.rs b/rust/hg-cpython/src/debug.rs
new file mode 100644
--- /dev/null
+++ b/rust/hg-cpython/src/debug.rs
@@ -0,0 +1,26 @@
+// debug.rs
+//
+// Copyright 2020 Raphaël Gomès 
+//
+// This software may be used and distributed according to the terms of the
+// GNU General Public License version 2 or any later version.
+
+//! Module to get debug information about Rust extensions.
+use cpython::{PyDict, PyModule, PyResult, Python};
+
+/// Create the module, with `__package__` given from parent
+pub fn init_module(py: Python, package: ) -> PyResult {
+let dotted_name = !("{}.debug", package);
+let m = PyModule::new(py, dotted_name)?;
+
+m.add(py, "__package__", package)?;
+m.add(py, "__doc__", "Rust debugging information")?;
+
+m.add(py, "re2_installed", cfg!(feature = "with-re2"))?;
+
+let sys = PyModule::import(py, "sys")?;
+let sys_modules: PyDict = sys.get(py, "modules")?.extract(py)?;
+sys_modules.set_item(py, dotted_name, )?;
+
+Ok(m)
+}



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


D7929: rust-status: add bare `hg status` support in hg-core

2020-03-11 Thread Raphaël Gomès
Closed by commit rHGc8891bca40fb: rust-status: add bare `hg status` support in 
hg-core (authored by Alphare).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7929?vs=20497=20721

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7929/new/

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

AFFECTED FILES
  rust/hg-core/src/dirstate/status.rs
  rust/hg-core/src/lib.rs

CHANGE DETAILS

diff --git a/rust/hg-core/src/lib.rs b/rust/hg-core/src/lib.rs
--- a/rust/hg-core/src/lib.rs
+++ b/rust/hg-core/src/lib.rs
@@ -13,7 +13,9 @@
 dirs_multiset::{DirsMultiset, DirsMultisetIter},
 dirstate_map::DirstateMap,
 parsers::{pack_dirstate, parse_dirstate, PARENT_SIZE},
-status::{status, DirstateStatus, StatusOptions},
+status::{
+status, BadMatch, BadType, DirstateStatus, StatusError, StatusOptions,
+},
 CopyMap, CopyMapIter, DirstateEntry, DirstateParents, EntryState,
 StateMap, StateMapIter,
 };
diff --git a/rust/hg-core/src/dirstate/status.rs 
b/rust/hg-core/src/dirstate/status.rs
--- a/rust/hg-core/src/dirstate/status.rs
+++ b/rust/hg-core/src/dirstate/status.rs
@@ -11,22 +11,30 @@
 
 use crate::{
 dirstate::SIZE_FROM_OTHER_PARENT,
-matchers::{Matcher, VisitChildrenSet},
+filepatterns::PatternFileWarning,
+matchers::{get_ignore_function, Matcher, VisitChildrenSet},
 utils::{
-files::HgMetadata,
+files::{find_dirs, HgMetadata},
 hg_path::{
 hg_path_to_path_buf, os_string_to_hg_path_buf, HgPath, HgPathBuf,
+HgPathError,
 },
+path_auditor::PathAuditor,
 },
 CopyMap, DirstateEntry, DirstateMap, EntryState, FastHashMap,
+PatternError,
 };
+use lazy_static::lazy_static;
 use rayon::prelude::*;
-use std::borrow::Cow;
-use std::collections::{HashSet, VecDeque};
-use std::fs::{read_dir, DirEntry};
-use std::io::ErrorKind;
-use std::ops::Deref;
-use std::path::Path;
+use std::collections::VecDeque;
+use std::{
+borrow::Cow,
+collections::HashSet,
+fs::{read_dir, DirEntry},
+io::ErrorKind,
+ops::Deref,
+path::Path,
+};
 
 /// Wrong type of file from a `BadMatch`
 /// Note: a lot of those don't exist on all platforms.
@@ -50,6 +58,7 @@
 /// Marker enum used to dispatch new status entries into the right collections.
 /// Is similar to `crate::EntryState`, but represents the transient state of
 /// entries during the lifetime of a command.
+#[derive(Debug)]
 enum Dispatch {
 Unsure,
 Modified,
@@ -155,7 +164,7 @@
 } else if options.list_clean {
 Dispatch::Clean
 } else {
-Dispatch::Unknown
+Dispatch::None
 }
 }
 EntryState::Merged => Dispatch::Modified,
@@ -179,57 +188,89 @@
 }
 }
 
+lazy_static! {
+static ref DEFAULT_WORK: HashSet<&'static HgPath> = {
+let mut h = HashSet::new();
+h.insert(HgPath::new(b""));
+h
+};
+}
+
 /// Get stat data about the files explicitly specified by match.
 /// TODO subrepos
 fn walk_explicit<'a>(
-files: &'a HashSet<>,
+files: Option<&'a HashSet<>>,
 dmap: &'a DirstateMap,
-root_dir: impl AsRef + Sync + Send,
+root_dir: impl AsRef + Sync + Send + 'a,
 options: StatusOptions,
 ) -> impl ParallelIterator> {
-files.par_iter().filter_map(move |filename| {
-// TODO normalization
-let normalized = filename.as_ref();
+files
+.unwrap_or(_WORK)
+.par_iter()
+.map(move |filename| {
+// TODO normalization
+let normalized = filename.as_ref();
 
-let buf = match hg_path_to_path_buf(normalized) {
-Ok(x) => x,
-Err(e) => return Some(Err(e.into())),
-};
-let target = root_dir.as_ref().join(buf);
-let st = target.symlink_metadata();
-match st {
-Ok(meta) => {
-let file_type = meta.file_type();
-if file_type.is_file() || file_type.is_symlink() {
-if let Some(entry) = dmap.get(normalized) {
+let buf = match hg_path_to_path_buf(normalized) {
+Ok(x) => x,
+Err(e) => return Some(Err(e.into())),
+};
+let target = root_dir.as_ref().join(buf);
+let st = target.symlink_metadata();
+let in_dmap = dmap.get(normalized);
+match st {
+Ok(meta) => {
+let file_type = meta.file_type();
+return if file_type.is_file() || file_type.is_symlink() {
+if let Some(entry) = in_dmap {
+return Some(Ok((
+normalized,
+dispatch_found(
+ 

D8087: rust-status: rename `StatusResult` to `DirstateStatus`

2020-03-11 Thread Raphaël Gomès
Closed by commit rHGf13d19549efd: rust-status: rename `StatusResult` to 
`DirstateStatus` (authored by Alphare).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8087?vs=20185=20718

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8087/new/

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

AFFECTED FILES
  rust/hg-core/src/dirstate/status.rs
  rust/hg-core/src/lib.rs
  rust/hg-cpython/src/dirstate/status.rs

CHANGE DETAILS

diff --git a/rust/hg-cpython/src/dirstate/status.rs 
b/rust/hg-cpython/src/dirstate/status.rs
--- a/rust/hg-cpython/src/dirstate/status.rs
+++ b/rust/hg-cpython/src/dirstate/status.rs
@@ -20,7 +20,7 @@
 matchers::{AlwaysMatcher, FileMatcher},
 status,
 utils::{files::get_path_from_bytes, hg_path::HgPath},
-StatusResult,
+DirstateStatus,
 };
 use std::borrow::Borrow;
 
@@ -114,7 +114,7 @@
 
 fn build_response(
 lookup: Vec<>,
-status_res: StatusResult,
+status_res: DirstateStatus,
 py: Python,
 ) -> PyResult<(PyList, PyList, PyList, PyList, PyList, PyList, PyList)> {
 let modified = collect_pybytes_list(py, status_res.modified.as_ref());
diff --git a/rust/hg-core/src/lib.rs b/rust/hg-core/src/lib.rs
--- a/rust/hg-core/src/lib.rs
+++ b/rust/hg-core/src/lib.rs
@@ -13,7 +13,7 @@
 dirs_multiset::{DirsMultiset, DirsMultisetIter},
 dirstate_map::DirstateMap,
 parsers::{pack_dirstate, parse_dirstate, PARENT_SIZE},
-status::{status, StatusOptions, StatusResult},
+status::{status, DirstateStatus, StatusOptions},
 CopyMap, CopyMapIter, DirstateEntry, DirstateParents, EntryState,
 StateMap, StateMapIter,
 };
diff --git a/rust/hg-core/src/dirstate/status.rs 
b/rust/hg-core/src/dirstate/status.rs
--- a/rust/hg-core/src/dirstate/status.rs
+++ b/rust/hg-core/src/dirstate/status.rs
@@ -255,7 +255,7 @@
 })
 }
 
-pub struct StatusResult<'a> {
+pub struct DirstateStatus<'a> {
 pub modified: Vec<&'a HgPath>,
 pub added: Vec<&'a HgPath>,
 pub removed: Vec<&'a HgPath>,
@@ -267,7 +267,7 @@
 
 fn build_response<'a>(
 results: impl IntoIterator>,
-) -> IoResult<(Vec<&'a HgPath>, StatusResult<'a>)> {
+) -> IoResult<(Vec<&'a HgPath>, DirstateStatus<'a>)> {
 let mut lookup = vec![];
 let mut modified = vec![];
 let mut added = vec![];
@@ -290,7 +290,7 @@
 
 Ok((
 lookup,
-StatusResult {
+DirstateStatus {
 modified,
 added,
 removed,
@@ -305,7 +305,7 @@
 matcher: &'b impl Matcher,
 root_dir: impl AsRef + Sync + Send + Copy,
 options: StatusOptions,
-) -> IoResult<(Vec<&'c HgPath>, StatusResult<'c>)> {
+) -> IoResult<(Vec<&'c HgPath>, DirstateStatus<'c>)> {
 let files = matcher.file_set();
 let mut results = vec![];
 if let Some(files) = files {



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


D8086: rust-status: refactor options into a `StatusOptions` struct

2020-03-11 Thread Raphaël Gomès
Closed by commit rHG483fce658e43: rust-status: refactor options into a 
`StatusOptions` struct (authored by Alphare).
This revision was automatically updated to reflect the committed changes.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8086?vs=20496=20717

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8086/new/

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

AFFECTED FILES
  rust/hg-core/src/dirstate/status.rs
  rust/hg-core/src/lib.rs
  rust/hg-core/src/matchers.rs

CHANGE DETAILS

diff --git a/rust/hg-core/src/matchers.rs b/rust/hg-core/src/matchers.rs
--- a/rust/hg-core/src/matchers.rs
+++ b/rust/hg-core/src/matchers.rs
@@ -668,7 +668,11 @@
 
 assert_eq!(
 roots_dirs_and_parents().unwrap(),
-RootsDirsAndParents {roots, dirs, parents}
+RootsDirsAndParents {
+roots,
+dirs,
+parents
+}
 );
 }
 
diff --git a/rust/hg-core/src/lib.rs b/rust/hg-core/src/lib.rs
--- a/rust/hg-core/src/lib.rs
+++ b/rust/hg-core/src/lib.rs
@@ -13,7 +13,7 @@
 dirs_multiset::{DirsMultiset, DirsMultisetIter},
 dirstate_map::DirstateMap,
 parsers::{pack_dirstate, parse_dirstate, PARENT_SIZE},
-status::{status, StatusResult},
+status::{status, StatusOptions, StatusResult},
 CopyMap, CopyMapIter, DirstateEntry, DirstateParents, EntryState,
 StateMap, StateMapIter,
 };
diff --git a/rust/hg-core/src/dirstate/status.rs 
b/rust/hg-core/src/dirstate/status.rs
--- a/rust/hg-core/src/dirstate/status.rs
+++ b/rust/hg-core/src/dirstate/status.rs
@@ -83,9 +83,7 @@
 entry: DirstateEntry,
 metadata: HgMetadata,
 copy_map: ,
-check_exec: bool,
-list_clean: bool,
-last_normal_time: i64,
+options: StatusOptions,
 ) -> Dispatch {
 let DirstateEntry {
 state,
@@ -105,7 +103,7 @@
 EntryState::Normal => {
 let size_changed = mod_compare(size, st_size as i32);
 let mode_changed =
-(mode ^ st_mode as i32) & 0o100 != 0o000 && check_exec;
+(mode ^ st_mode as i32) & 0o100 != 0o000 && options.check_exec;
 let metadata_changed = size >= 0 && (size_changed || mode_changed);
 let other_parent = size == SIZE_FROM_OTHER_PARENT;
 if metadata_changed
@@ -115,14 +113,14 @@
 Dispatch::Modified
 } else if mod_compare(mtime, st_mtime as i32) {
 Dispatch::Unsure
-} else if st_mtime == last_normal_time {
+} else if st_mtime == options.last_normal_time {
 // the file may have just been marked as normal and
 // it may have changed in the same second without
 // changing its size. This can happen if we quickly
 // do multiple commits. Force lookup, so we don't
 // miss such a racy file change.
 Dispatch::Unsure
-} else if list_clean {
+} else if options.list_clean {
 Dispatch::Clean
 } else {
 Dispatch::Unknown
@@ -155,9 +153,7 @@
 files: &'a HashSet<>,
 dmap: &'a DirstateMap,
 root_dir: impl AsRef + Sync + Send,
-check_exec: bool,
-list_clean: bool,
-last_normal_time: i64,
+options: StatusOptions,
 ) -> impl ParallelIterator> {
 files.par_iter().filter_map(move |filename| {
 // TODO normalization
@@ -181,9 +177,7 @@
 *entry,
 HgMetadata::from_metadata(meta),
 _map,
-check_exec,
-list_clean,
-last_normal_time,
+options,
 ),
 )));
 }
@@ -206,14 +200,23 @@
 })
 }
 
+#[derive(Debug, Copy, Clone)]
+pub struct StatusOptions {
+/// Remember the most recent modification timeslot for status, to make
+/// sure we won't miss future size-preserving file content modifications
+/// that happen within the same timeslot.
+pub last_normal_time: i64,
+/// Whether we are on a filesystem with UNIX-like exec flags
+pub check_exec: bool,
+pub list_clean: bool,
+}
+
 /// Stat all entries in the `DirstateMap` and mark them for dispatch into
 /// the relevant collections.
 fn stat_dmap_entries(
 dmap: ,
 root_dir: impl AsRef + Sync + Send,
-check_exec: bool,
-list_clean: bool,
-last_normal_time: i64,
+options: StatusOptions,
 ) -> impl ParallelIterator> {
 dmap.par_iter().map(move |(filename, entry)| {
 let filename:  = filename;
@@ -234,9 +237,7 @@
 *entry,
 HgMetadata::from_metadata(m),
 _map,
-check_exec,
-list_clean,
-   

D7928: rust-status: add function for sequential traversal of the working directory

2020-03-11 Thread Raphaël Gomès
Closed by commit rHG1debb5894b39: rust-status: add function for sequential 
traversal of the working directory (authored by Alphare).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7928?vs=20461=20720

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7928/new/

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

AFFECTED FILES
  rust/hg-core/src/dirstate/status.rs

CHANGE DETAILS

diff --git a/rust/hg-core/src/dirstate/status.rs 
b/rust/hg-core/src/dirstate/status.rs
--- a/rust/hg-core/src/dirstate/status.rs
+++ b/rust/hg-core/src/dirstate/status.rs
@@ -11,18 +11,21 @@
 
 use crate::{
 dirstate::SIZE_FROM_OTHER_PARENT,
-matchers::Matcher,
+matchers::{Matcher, VisitChildrenSet},
 utils::{
 files::HgMetadata,
 hg_path::{
 hg_path_to_path_buf, os_string_to_hg_path_buf, HgPath, HgPathBuf,
 },
 },
-CopyMap, DirstateEntry, DirstateMap, EntryState,
+CopyMap, DirstateEntry, DirstateMap, EntryState, FastHashMap,
 };
 use rayon::prelude::*;
-use std::collections::HashSet;
+use std::borrow::Cow;
+use std::collections::{HashSet, VecDeque};
 use std::fs::{read_dir, DirEntry};
+use std::io::ErrorKind;
+use std::ops::Deref;
 use std::path::Path;
 
 /// Wrong type of file from a `BadMatch`
@@ -238,6 +241,178 @@
 /// Whether we are on a filesystem with UNIX-like exec flags
 pub check_exec: bool,
 pub list_clean: bool,
+pub list_unknown: bool,
+pub list_ignored: bool,
+}
+
+/// Dispatch a single file found during `traverse`.
+/// If `file` is a folder that needs to be traversed, it will be pushed into
+/// `work`.
+fn traverse_worker<'a>(
+work:  VecDeque,
+matcher:  Matcher,
+dmap: ,
+filename: impl AsRef,
+dir_entry: ,
+ignore_fn:  for<'r> Fn(&'r HgPath) -> bool,
+dir_ignore_fn:  for<'r> Fn(&'r HgPath) -> bool,
+options: StatusOptions,
+) -> Option, Dispatch)>> {
+let file_type = match dir_entry.file_type() {
+Ok(x) => x,
+Err(e) => return Some(Err(e.into())),
+};
+let filename = filename.as_ref();
+let entry_option = dmap.get(filename);
+
+if file_type.is_dir() {
+// Do we need to traverse it?
+if !ignore_fn() || options.list_ignored {
+work.push_front(filename.to_owned());
+}
+// Nested `if` until `rust-lang/rust#53668` is stable
+if let Some(entry) = entry_option {
+// Used to be a file, is now a folder
+if matcher.matches_everything() || matcher.matches() {
+return Some(Ok((
+Cow::Owned(filename.to_owned()),
+dispatch_missing(entry.state),
+)));
+}
+}
+} else if file_type.is_file() || file_type.is_symlink() {
+if let Some(entry) = entry_option {
+if matcher.matches_everything() || matcher.matches() {
+let metadata = match dir_entry.metadata() {
+Ok(x) => x,
+Err(e) => return Some(Err(e.into())),
+};
+return Some(Ok((
+Cow::Owned(filename.to_owned()),
+dispatch_found(
+,
+*entry,
+HgMetadata::from_metadata(metadata),
+_map,
+options,
+),
+)));
+}
+} else if (matcher.matches_everything() || matcher.matches())
+&& !ignore_fn()
+{
+if (options.list_ignored || matcher.exact_match())
+&& dir_ignore_fn()
+{
+if options.list_ignored {
+return Some(Ok((
+Cow::Owned(filename.to_owned()),
+Dispatch::Ignored,
+)));
+}
+} else {
+return Some(Ok((
+Cow::Owned(filename.to_owned()),
+Dispatch::Unknown,
+)));
+}
+}
+} else if let Some(entry) = entry_option {
+// Used to be a file or a folder, now something else.
+if matcher.matches_everything() || matcher.matches() {
+return Some(Ok((
+Cow::Owned(filename.to_owned()),
+dispatch_missing(entry.state),
+)));
+}
+}
+None
+}
+
+/// Walk the working directory recursively to look for changes compared to the
+/// current `DirstateMap`.
+fn traverse<'a>(
+matcher: &(impl Matcher + Sync),
+root_dir: impl AsRef,
+dmap: ,
+path: impl AsRef,
+old_results: FastHashMap, Dispatch>,
+ignore_fn: &(impl for<'r> Fn(&'r HgPath) -> bool + Sync),
+dir_ignore_fn: 

D8088: rust-status: add missing variants to `Dispatch` enum

2020-03-11 Thread Raphaël Gomès
Closed by commit rHG61709b844420: rust-status: add missing variants to 
`Dispatch` enum (authored by Alphare).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8088?vs=20186=20719

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8088/new/

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

AFFECTED FILES
  rust/hg-core/src/dirstate/status.rs

CHANGE DETAILS

diff --git a/rust/hg-core/src/dirstate/status.rs 
b/rust/hg-core/src/dirstate/status.rs
--- a/rust/hg-core/src/dirstate/status.rs
+++ b/rust/hg-core/src/dirstate/status.rs
@@ -25,6 +25,25 @@
 use std::fs::{read_dir, DirEntry};
 use std::path::Path;
 
+/// Wrong type of file from a `BadMatch`
+/// Note: a lot of those don't exist on all platforms.
+#[derive(Debug)]
+pub enum BadType {
+CharacterDevice,
+BlockDevice,
+FIFO,
+Socket,
+Directory,
+Unknown,
+}
+
+/// Was explicitly matched but cannot be found/accessed
+#[derive(Debug)]
+pub enum BadMatch {
+OsError(i32),
+BadType(BadType),
+}
+
 /// Marker enum used to dispatch new status entries into the right collections.
 /// Is similar to `crate::EntryState`, but represents the transient state of
 /// entries during the lifetime of a command.
@@ -36,6 +55,16 @@
 Deleted,
 Clean,
 Unknown,
+Ignored,
+/// Empty dispatch, the file is not worth listing
+None,
+/// Was explicitly matched but cannot be found/accessed
+Bad(BadMatch),
+Directory {
+/// True if the directory used to be a file in the dmap so we can say
+/// that it's been removed.
+was_file: bool,
+},
 }
 
 type IoResult = std::io::Result;
@@ -261,8 +290,9 @@
 pub removed: Vec<&'a HgPath>,
 pub deleted: Vec<&'a HgPath>,
 pub clean: Vec<&'a HgPath>,
-/* TODO ignored
- * TODO unknown */
+pub ignored: Vec<&'a HgPath>,
+pub unknown: Vec<&'a HgPath>,
+pub bad: Vec<(&'a HgPath, BadMatch)>,
 }
 
 fn build_response<'a>(
@@ -274,17 +304,24 @@
 let mut removed = vec![];
 let mut deleted = vec![];
 let mut clean = vec![];
+let mut ignored = vec![];
+let mut unknown = vec![];
+let mut bad = vec![];
 
 for res in results.into_iter() {
 let (filename, dispatch) = res?;
 match dispatch {
-Dispatch::Unknown => {}
+Dispatch::Unknown => unknown.push(filename),
 Dispatch::Unsure => lookup.push(filename),
 Dispatch::Modified => modified.push(filename),
 Dispatch::Added => added.push(filename),
 Dispatch::Removed => removed.push(filename),
 Dispatch::Deleted => deleted.push(filename),
 Dispatch::Clean => clean.push(filename),
+Dispatch::Ignored => ignored.push(filename),
+Dispatch::None => {}
+Dispatch::Bad(reason) => bad.push((filename, reason)),
+Dispatch::Directory { .. } => {}
 }
 }
 
@@ -296,6 +333,9 @@
 removed,
 deleted,
 clean,
+ignored,
+unknown,
+bad,
 },
 ))
 }



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


D7927: rust-status: add util for listing a directory

2020-03-11 Thread Raphaël Gomès
Closed by commit rHG0d97bcb3cee9: rust-status: add util for listing a directory 
(authored by Alphare).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7927?vs=20183=20716

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7927/new/

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

AFFECTED FILES
  rust/hg-core/src/dirstate/status.rs

CHANGE DETAILS

diff --git a/rust/hg-core/src/dirstate/status.rs 
b/rust/hg-core/src/dirstate/status.rs
--- a/rust/hg-core/src/dirstate/status.rs
+++ b/rust/hg-core/src/dirstate/status.rs
@@ -14,12 +14,15 @@
 matchers::Matcher,
 utils::{
 files::HgMetadata,
-hg_path::{hg_path_to_path_buf, HgPath},
+hg_path::{
+hg_path_to_path_buf, os_string_to_hg_path_buf, HgPath, HgPathBuf,
+},
 },
 CopyMap, DirstateEntry, DirstateMap, EntryState,
 };
 use rayon::prelude::*;
 use std::collections::HashSet;
+use std::fs::{read_dir, DirEntry};
 use std::path::Path;
 
 /// Marker enum used to dispatch new status entries into the right collections.
@@ -48,6 +51,32 @@
 a & i32::max_value() != b & i32::max_value()
 }
 
+/// Return a sorted list containing information about the entries
+/// in the directory.
+///
+/// * `skip_dot_hg` - Return an empty vec if `path` contains a `.hg` directory
+fn list_directory(
+path: impl AsRef,
+skip_dot_hg: bool,
+) -> std::io::Result> {
+let mut results = vec![];
+let entries = read_dir(path.as_ref())?;
+
+for entry in entries {
+let entry = entry?;
+let filename = os_string_to_hg_path_buf(entry.file_name())?;
+let file_type = entry.file_type()?;
+if skip_dot_hg && filename.as_bytes() == b".hg" && file_type.is_dir() {
+return Ok(vec![]);
+} else {
+results.push((HgPathBuf::from(filename), entry))
+}
+}
+
+results.sort_unstable_by_key(|e| e.0.clone());
+Ok(results)
+}
+
 /// The file corresponding to the dirstate entry was found on the filesystem.
 fn dispatch_found(
 filename: impl AsRef,



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


D7925: rust-matchers: add `IgnoreMatcher`

2020-03-11 Thread Raphaël Gomès
Closed by commit rHGc697638e0e91: rust-matchers: add `IgnoreMatcher` (authored 
by Alphare).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7925?vs=20495=20715

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7925/new/

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

AFFECTED FILES
  rust/hg-core/src/matchers.rs

CHANGE DETAILS

diff --git a/rust/hg-core/src/matchers.rs b/rust/hg-core/src/matchers.rs
--- a/rust/hg-core/src/matchers.rs
+++ b/rust/hg-core/src/matchers.rs
@@ -10,14 +10,25 @@
 #[cfg(feature = "with-re2")]
 use crate::re2::Re2;
 use crate::{
-filepatterns::{build_single_regex, PatternResult},
-utils::hg_path::{HgPath, HgPathBuf},
-DirsMultiset, DirstateMapError, IgnorePattern, PatternError,
+dirstate::dirs_multiset::DirsChildrenMultiset,
+filepatterns::{
+build_single_regex, filter_subincludes, get_patterns_from_file,
+PatternFileWarning, PatternResult, SubInclude,
+},
+utils::{
+files::find_dirs,
+hg_path::{HgPath, HgPathBuf},
+Escaped,
+},
+DirsMultiset, DirstateMapError, FastHashMap, IgnorePattern, PatternError,
 PatternSyntax,
 };
+
 use std::collections::HashSet;
+use std::fmt::{Display, Error, Formatter};
 use std::iter::FromIterator;
 use std::ops::Deref;
+use std::path::Path;
 
 #[derive(Debug, PartialEq)]
 pub enum VisitChildrenSet<'a> {
@@ -223,6 +234,87 @@
 }
 }
 
+/// Matches files that are included in the ignore rules.
+#[cfg_attr(
+feature = "with-re2",
+doc = r##"
+```
+use hg::{
+matchers::{IncludeMatcher, Matcher},
+IgnorePattern,
+PatternSyntax,
+utils::hg_path::HgPath
+};
+use std::path::Path;
+///
+let ignore_patterns =
+vec![IgnorePattern::new(PatternSyntax::RootGlob, b"this*", Path::new(""))];
+let (matcher, _) = IncludeMatcher::new(ignore_patterns, "").unwrap();
+///
+assert_eq!(matcher.matches(HgPath::new(b"testing")), false);
+assert_eq!(matcher.matches(HgPath::new(b"this should work")), true);
+assert_eq!(matcher.matches(HgPath::new(b"this also")), true);
+assert_eq!(matcher.matches(HgPath::new(b"but not this")), false);
+```
+"##
+)]
+pub struct IncludeMatcher<'a> {
+patterns: Vec,
+match_fn: Box Fn(&'r HgPath) -> bool + 'a + Sync>,
+/// Whether all the patterns match a prefix (i.e. recursively)
+prefix: bool,
+roots: HashSet,
+dirs: HashSet,
+parents: HashSet,
+}
+
+impl<'a> Matcher for IncludeMatcher<'a> {
+fn file_set() -> Option<<>> {
+None
+}
+
+fn exact_match(, _filename: impl AsRef) -> bool {
+false
+}
+
+fn matches(, filename: impl AsRef) -> bool {
+(self.match_fn)(filename.as_ref())
+}
+
+fn visit_children_set(
+,
+directory: impl AsRef,
+) -> VisitChildrenSet {
+let dir = directory.as_ref();
+if self.prefix && self.roots.contains(dir) {
+return VisitChildrenSet::Recursive;
+}
+if self.roots.contains(HgPath::new(b""))
+|| self.roots.contains(dir)
+|| self.dirs.contains(dir)
+|| find_dirs(dir).any(|parent_dir| self.roots.contains(parent_dir))
+{
+return VisitChildrenSet::This;
+}
+
+if self.parents.contains(directory.as_ref()) {
+let multiset = self.get_all_parents_children();
+if let Some(children) = multiset.get(dir) {
+return VisitChildrenSet::Set(children.to_owned());
+}
+}
+VisitChildrenSet::Empty
+}
+
+fn matches_everything() -> bool {
+false
+}
+
+fn is_exact() -> bool {
+false
+}
+}
+
 #[cfg(feature = "with-re2")]
 /// Returns a function that matches an `HgPath` against the given regex
 /// pattern.
@@ -361,6 +453,175 @@
 })
 }
 
+/// Returns a function that checks whether a given file (in the general sense)
+/// should be matched.
+fn build_match<'a, 'b>(
+ignore_patterns: &'a [IgnorePattern],
+root_dir: impl AsRef,
+) -> PatternResult<(
+Vec,
+Box bool + 'b + Sync>,
+Vec,
+)> {
+let mut match_funcs: Vec bool + Sync>> = vec![];
+// For debugging and printing
+let mut patterns = vec![];
+let mut all_warnings = vec![];
+
+let (subincludes, ignore_patterns) =
+filter_subincludes(ignore_patterns, root_dir)?;
+
+if !subincludes.is_empty() {
+// Build prefix-based matcher functions for subincludes
+let mut submatchers = FastHashMap::default();
+let mut prefixes = vec![];
+
+for SubInclude { prefix, root, path } in subincludes.into_iter() {
+let (match_fn, warnings) = get_ignore_function(&[path], root)?;
+all_warnings.extend(warnings);
+prefixes.push(prefix.to_owned());
+

D8270: run-tests: restrict Rust thread pool to 3 threads during tests

2020-03-11 Thread Raphaël Gomès
Closed by commit rHGb2e41723f886: run-tests: restrict Rust thread pool to 3 
threads during tests (authored by Alphare).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

CHANGED PRIOR TO COMMIT
  https://phab.mercurial-scm.org/D8270?vs=20663=20711#toc

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8270?vs=20663=20711

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8270/new/

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

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
@@ -2995,6 +2995,12 @@
 # we do the randomness ourself to know what seed is used
 os.environ['PYTHONHASHSEED'] = str(random.getrandbits(32))
 
+# Rayon (Rust crate for multi-threading) will use all logical CPU cores
+# by default, causing thrashing on high-cpu-count systems.
+# Setting its limit to 3 during tests should still let us uncover
+# multi-threading bugs while keeping the thrashing reasonable.
+os.environ.setdefault("RAYON_NUM_THREADS", "3")
+
 if self.options.tmpdir:
 self.options.keep_tmpdir = True
 tmpdir = _sys2bytes(self.options.tmpdir)



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


D7924: rust-matchers: add `build_regex_match` function

2020-03-11 Thread Raphaël Gomès
Closed by commit rHGa21881b40942: rust-matchers: add `build_regex_match` 
function (authored by Alphare).
This revision was automatically updated to reflect the committed changes.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7924?vs=20162=20714

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7924/new/

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

AFFECTED FILES
  rust/hg-core/src/matchers.rs

CHANGE DETAILS

diff --git a/rust/hg-core/src/matchers.rs b/rust/hg-core/src/matchers.rs
--- a/rust/hg-core/src/matchers.rs
+++ b/rust/hg-core/src/matchers.rs
@@ -10,7 +10,7 @@
 #[cfg(feature = "with-re2")]
 use crate::re2::Re2;
 use crate::{
-filepatterns::PatternResult,
+filepatterns::{build_single_regex, PatternResult},
 utils::hg_path::{HgPath, HgPathBuf},
 DirsMultiset, DirstateMapError, IgnorePattern, PatternError,
 PatternSyntax,
@@ -242,6 +242,24 @@
 Err(PatternError::Re2NotInstalled)
 }
 
+/// Returns the regex pattern and a function that matches an `HgPath` against
+/// said regex formed by the given ignore patterns.
+fn build_regex_match<'a>(
+ignore_patterns: &'a [&'a IgnorePattern],
+) -> PatternResult<(Vec, Box bool + Sync>)> {
+let regexps: Result, PatternError> = ignore_patterns
+.into_iter()
+.map(|k| build_single_regex(*k))
+.collect();
+let regexps = regexps?;
+let full_regex = regexps.join('|');
+
+let matcher = re_matcher(_regex)?;
+let func = Box::new(move |filename: | matcher(filename));
+
+Ok((full_regex, func))
+}
+
 /// Returns roots and directories corresponding to each pattern.
 ///
 /// This calculates the roots and directories exactly matching the patterns and



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


D7922: rust-matchers: add function to generate a regex matcher function

2020-03-11 Thread Raphaël Gomès
Closed by commit rHG52d40f8fb82d: rust-matchers: add function to generate a 
regex matcher function (authored by Alphare).
This revision was automatically updated to reflect the committed changes.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7922?vs=20160=20712

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7922/new/

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

AFFECTED FILES
  rust/hg-core/src/lib.rs
  rust/hg-core/src/matchers.rs

CHANGE DETAILS

diff --git a/rust/hg-core/src/matchers.rs b/rust/hg-core/src/matchers.rs
--- a/rust/hg-core/src/matchers.rs
+++ b/rust/hg-core/src/matchers.rs
@@ -7,7 +7,12 @@
 
 //! Structs and types for matching files and directories.
 
-use crate::{utils::hg_path::HgPath, DirsMultiset, DirstateMapError};
+#[cfg(feature = "with-re2")]
+use crate::re2::Re2;
+use crate::{
+filepatterns::PatternResult, utils::hg_path::HgPath, DirsMultiset,
+DirstateMapError, PatternError,
+};
 use std::collections::HashSet;
 use std::iter::FromIterator;
 use std::ops::Deref;
@@ -215,6 +220,26 @@
 true
 }
 }
+
+#[cfg(feature = "with-re2")]
+/// Returns a function that matches an `HgPath` against the given regex
+/// pattern.
+///
+/// This can fail when the pattern is invalid or not supported by the
+/// underlying engine `Re2`, for instance anything with back-references.
+fn re_matcher(
+pattern: &[u8],
+) -> PatternResult bool + Sync> {
+let regex = Re2::new(pattern);
+let regex = regex.map_err(|e| PatternError::UnsupportedSyntax(e))?;
+Ok(move |path: | regex.is_match(path.as_bytes()))
+}
+
+#[cfg(not(feature = "with-re2"))]
+fn re_matcher(_: &[u8]) -> PatternResult bool + Sync>> {
+Err(PatternError::Re2NotInstalled)
+}
+
 #[cfg(test)]
 mod tests {
 use super::*;
diff --git a/rust/hg-core/src/lib.rs b/rust/hg-core/src/lib.rs
--- a/rust/hg-core/src/lib.rs
+++ b/rust/hg-core/src/lib.rs
@@ -126,6 +126,9 @@
 /// Needed a pattern that can be turned into a regex but got one that
 /// can't. This should only happen through programmer error.
 NonRegexPattern(IgnorePattern),
+/// This is temporary, see `re2/mod.rs`.
+/// This will cause a fallback to Python.
+Re2NotInstalled,
 }
 
 impl ToString for PatternError {
@@ -148,6 +151,10 @@
 PatternError::NonRegexPattern(pattern) => {
 format!("'{:?}' cannot be turned into a regex", pattern)
 }
+PatternError::Re2NotInstalled => {
+"Re2 is not installed, cannot use regex functionality."
+.to_string()
+}
 }
 }
 }



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


D7923: rust-matchers: add functions to get roots, dirs and parents from patterns

2020-03-11 Thread Raphaël Gomès
Closed by commit rHGd4e8cfcde012: rust-matchers: add functions to get roots, 
dirs and parents from patterns (authored by Alphare).
This revision was automatically updated to reflect the committed changes.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7923?vs=20161=20713

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7923/new/

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

AFFECTED FILES
  rust/hg-core/src/matchers.rs

CHANGE DETAILS

diff --git a/rust/hg-core/src/matchers.rs b/rust/hg-core/src/matchers.rs
--- a/rust/hg-core/src/matchers.rs
+++ b/rust/hg-core/src/matchers.rs
@@ -10,8 +10,10 @@
 #[cfg(feature = "with-re2")]
 use crate::re2::Re2;
 use crate::{
-filepatterns::PatternResult, utils::hg_path::HgPath, DirsMultiset,
-DirstateMapError, PatternError,
+filepatterns::PatternResult,
+utils::hg_path::{HgPath, HgPathBuf},
+DirsMultiset, DirstateMapError, IgnorePattern, PatternError,
+PatternSyntax,
 };
 use std::collections::HashSet;
 use std::iter::FromIterator;
@@ -240,10 +242,156 @@
 Err(PatternError::Re2NotInstalled)
 }
 
+/// Returns roots and directories corresponding to each pattern.
+///
+/// This calculates the roots and directories exactly matching the patterns and
+/// returns a tuple of (roots, dirs). It does not return other directories
+/// which may also need to be considered, like the parent directories.
+fn roots_and_dirs(
+ignore_patterns: &[IgnorePattern],
+) -> (Vec, Vec) {
+let mut roots = Vec::new();
+let mut dirs = Vec::new();
+
+for ignore_pattern in ignore_patterns {
+let IgnorePattern {
+syntax, pattern, ..
+} = ignore_pattern;
+match syntax {
+PatternSyntax::RootGlob | PatternSyntax::Glob => {
+let mut root = vec![];
+
+for p in pattern.split(|c| *c == b'/') {
+if p.iter().any(|c| match *c {
+b'[' | b'{' | b'*' | b'?' => true,
+_ => false,
+}) {
+break;
+}
+root.push(HgPathBuf::from_bytes(p));
+}
+let buf =
+root.iter().fold(HgPathBuf::new(), |acc, r| acc.join(r));
+roots.push(buf);
+}
+PatternSyntax::Path | PatternSyntax::RelPath => {
+let pat = HgPath::new(if pattern == b"." {
+&[] as &[u8]
+} else {
+pattern
+});
+roots.push(pat.to_owned());
+}
+PatternSyntax::RootFiles => {
+let pat = if pattern == b"." {
+&[] as &[u8]
+} else {
+pattern
+};
+dirs.push(HgPathBuf::from_bytes(pat));
+}
+_ => {
+roots.push(HgPathBuf::new());
+}
+}
+}
+(roots, dirs)
+}
+
+/// Paths extracted from patterns
+#[derive(Debug, PartialEq)]
+struct RootsDirsAndParents {
+/// Directories to match recursively
+pub roots: HashSet,
+/// Directories to match non-recursively
+pub dirs: HashSet,
+/// Implicitly required directories to go to items in either roots or dirs
+pub parents: HashSet,
+}
+
+/// Extract roots, dirs and parents from patterns.
+fn roots_dirs_and_parents(
+ignore_patterns: &[IgnorePattern],
+) -> PatternResult {
+let (roots, dirs) = roots_and_dirs(ignore_patterns);
+
+let mut parents = HashSet::new();
+
+parents.extend(
+DirsMultiset::from_manifest()
+.map_err(|e| match e {
+DirstateMapError::InvalidPath(e) => e,
+_ => unreachable!(),
+})?
+.iter()
+.map(|k| k.to_owned()),
+);
+parents.extend(
+DirsMultiset::from_manifest()
+.map_err(|e| match e {
+DirstateMapError::InvalidPath(e) => e,
+_ => unreachable!(),
+})?
+.iter()
+.map(|k| k.to_owned()),
+);
+
+Ok(RootsDirsAndParents {
+roots: HashSet::from_iter(roots),
+dirs: HashSet::from_iter(dirs),
+parents,
+})
+}
+
 #[cfg(test)]
 mod tests {
 use super::*;
 use pretty_assertions::assert_eq;
+use std::path::Path;
+
+#[test]
+fn test_roots_and_dirs() {
+let pats = vec![
+IgnorePattern::new(PatternSyntax::Glob, b"g/h/*", Path::new("")),
+IgnorePattern::new(PatternSyntax::Glob, b"g/h", Path::new("")),
+IgnorePattern::new(PatternSyntax::Glob, b"g*", Path::new("")),
+];
+let (roots, dirs) = roots_and_dirs();
+
+assert_eq!(
+roots,
+vec!(
+HgPathBuf::from_bytes(b"g/h"),
+HgPathBuf::from_bytes(b"g/h"),
+

D8253: hg-core: add function timing information

2020-03-11 Thread Raphaël Gomès
Alphare updated this revision to Diff 20710.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8253?vs=20567=20710

BRANCH
  default

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8253/new/

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

AFFECTED FILES
  rust/Cargo.lock
  rust/hg-core/Cargo.toml
  rust/hg-core/src/dirstate/parsers.rs
  rust/hg-core/src/dirstate/status.rs
  rust/hg-core/src/lib.rs
  rust/hg-core/src/matchers.rs

CHANGE DETAILS

diff --git a/rust/hg-core/src/matchers.rs b/rust/hg-core/src/matchers.rs
--- a/rust/hg-core/src/matchers.rs
+++ b/rust/hg-core/src/matchers.rs
@@ -24,6 +24,7 @@
 PatternSyntax,
 };
 
+use micro_timer::timed;
 use std::collections::HashSet;
 use std::fmt::{Display, Error, Formatter};
 use std::iter::FromIterator;
@@ -548,6 +549,7 @@
 /// Parses all "ignore" files with their recursive includes and returns a
 /// function that checks whether a given file (in the general sense) should be
 /// ignored.
+#[timed]
 pub fn get_ignore_function<'a>(
 all_pattern_files: &[impl AsRef],
 root_dir: impl AsRef,
diff --git a/rust/hg-core/src/lib.rs b/rust/hg-core/src/lib.rs
--- a/rust/hg-core/src/lib.rs
+++ b/rust/hg-core/src/lib.rs
@@ -35,6 +35,10 @@
 use std::collections::HashMap;
 use twox_hash::RandomXxHashBuilder64;
 
+/// This is a contract between the `micro-timer` crate and us, to expose
+/// the `log` crate as `crate::log`.
+use log;
+
 pub type LineNumber = usize;
 
 /// Rust's default hasher is too slow because it tries to prevent collision
diff --git a/rust/hg-core/src/dirstate/status.rs 
b/rust/hg-core/src/dirstate/status.rs
--- a/rust/hg-core/src/dirstate/status.rs
+++ b/rust/hg-core/src/dirstate/status.rs
@@ -25,6 +25,7 @@
 PatternError,
 };
 use lazy_static::lazy_static;
+use micro_timer::timed;
 use rayon::prelude::*;
 use std::{
 borrow::Cow,
@@ -211,6 +212,7 @@
 
 /// Get stat data about the files explicitly specified by match.
 /// TODO subrepos
+#[timed]
 fn walk_explicit<'a>(
 files: Option<&'a HashSet<>>,
 dmap: &'a DirstateMap,
@@ -513,6 +515,7 @@
 ///
 /// This takes a mutable reference to the results to account for the `extend`
 /// in timings
+#[timed]
 fn traverse<'a>(
 matcher: &'a (impl Matcher + Sync),
 root_dir: impl AsRef + Sync + Send + Copy,
@@ -606,6 +609,7 @@
 
 /// This takes a mutable reference to the results to account for the `extend`
 /// in timings
+#[timed]
 fn extend_from_dmap<'a>(
 dmap: &'a DirstateMap,
 root_dir: impl AsRef + Sync + Send,
@@ -630,6 +634,7 @@
 pub bad: Vec<(Cow<'a, HgPath>, BadMatch)>,
 }
 
+#[timed]
 fn build_response<'a>(
 results: impl IntoIterator, Dispatch)>,
 ) -> (Vec>, DirstateStatus<'a>) {
@@ -710,6 +715,7 @@
 
 /// This takes a mutable reference to the results to account for the `extend`
 /// in timings
+#[timed]
 fn handle_unknowns<'a>(
 dmap: &'a DirstateMap,
 matcher: &(impl Matcher + Sync),
@@ -792,6 +798,7 @@
 /// This is the current entry-point for `hg-core` and is realistically unusable
 /// outside of a Python context because its arguments need to provide a lot of
 /// information that will not be necessary in the future.
+#[timed]
 pub fn status<'a: 'c, 'b: 'c, 'c>(
 dmap: &'a DirstateMap,
 matcher: &'b (impl Matcher + Sync),
diff --git a/rust/hg-core/src/dirstate/parsers.rs 
b/rust/hg-core/src/dirstate/parsers.rs
--- a/rust/hg-core/src/dirstate/parsers.rs
+++ b/rust/hg-core/src/dirstate/parsers.rs
@@ -9,6 +9,7 @@
 DirstateEntry, DirstatePackError, DirstateParents, DirstateParseError,
 };
 use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
+use micro_timer::timed;
 use std::convert::{TryFrom, TryInto};
 use std::io::Cursor;
 use std::time::Duration;
@@ -20,6 +21,7 @@
 
 // TODO parse/pack: is mutate-on-loop better for performance?
 
+#[timed]
 pub fn parse_dirstate(
 state_map:  StateMap,
 copy_map:  CopyMap,
diff --git a/rust/hg-core/Cargo.toml b/rust/hg-core/Cargo.toml
--- a/rust/hg-core/Cargo.toml
+++ b/rust/hg-core/Cargo.toml
@@ -22,6 +22,7 @@
 twox-hash = "1.5.0"
 same-file = "1.0.6"
 crossbeam = "0.7.3"
+micro-timer = "0.1.2"
 log = "0.4.8"
 
 [dev-dependencies]
diff --git a/rust/Cargo.lock b/rust/Cargo.lock
--- a/rust/Cargo.lock
+++ b/rust/Cargo.lock
@@ -235,6 +235,7 @@
  "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "micro-timer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "pretty_assertions 0.6.1 
(registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -301,6 +302,16 @@
 ]
 
 [[package]]
+name = "micro-timer"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index;
+dependencies 

D8252: rust: add logging utils

2020-03-11 Thread Raphaël Gomès
Alphare updated this revision to Diff 20709.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8252?vs=20566=20709

BRANCH
  default

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8252/new/

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

AFFECTED FILES
  rust/Cargo.lock
  rust/hg-core/Cargo.toml
  rust/hg-cpython/Cargo.toml
  rust/hg-cpython/src/dirstate.rs

CHANGE DETAILS

diff --git a/rust/hg-cpython/src/dirstate.rs b/rust/hg-cpython/src/dirstate.rs
--- a/rust/hg-cpython/src/dirstate.rs
+++ b/rust/hg-cpython/src/dirstate.rs
@@ -107,6 +107,8 @@
 let dotted_name = !("{}.dirstate", package);
 let m = PyModule::new(py, dotted_name)?;
 
+simple_logger::init_by_env();
+
 m.add(py, "__package__", package)?;
 m.add(py, "__doc__", "Dirstate - Rust implementation")?;
 
diff --git a/rust/hg-cpython/Cargo.toml b/rust/hg-cpython/Cargo.toml
--- a/rust/hg-cpython/Cargo.toml
+++ b/rust/hg-cpython/Cargo.toml
@@ -24,6 +24,7 @@
 [dependencies]
 hg-core = { path = "../hg-core"}
 libc = '*'
+simple_logger = "1.6.0"
 
 [dependencies.cpython]
 version = "0.4"
diff --git a/rust/hg-core/Cargo.toml b/rust/hg-core/Cargo.toml
--- a/rust/hg-core/Cargo.toml
+++ b/rust/hg-core/Cargo.toml
@@ -22,6 +22,7 @@
 twox-hash = "1.5.0"
 same-file = "1.0.6"
 crossbeam = "0.7.3"
+log = "0.4.8"
 
 [dev-dependencies]
 clap = "*"
diff --git a/rust/Cargo.lock b/rust/Cargo.lock
--- a/rust/Cargo.lock
+++ b/rust/Cargo.lock
@@ -2,10 +2,10 @@
 # It is not intended for manual editing.
 [[package]]
 name = "aho-corasick"
-version = "0.7.8"
+version = "0.7.10"
 source = "registry+https://github.com/rust-lang/crates.io-index;
 dependencies = [
- "memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -21,8 +21,8 @@
 version = "0.2.14"
 source = "registry+https://github.com/rust-lang/crates.io-index;
 dependencies = [
- "hermit-abi 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
+ "hermit-abi 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.67 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -43,18 +43,10 @@
 
 [[package]]
 name = "byteorder"
-version = "1.3.2"
+version = "1.3.4"
 source = "registry+https://github.com/rust-lang/crates.io-index;
 
 [[package]]
-name = "c2-chacha"
-version = "0.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index;
-dependencies = [
- "ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
 name = "cc"
 version = "1.0.50"
 source = "registry+https://github.com/rust-lang/crates.io-index;
@@ -65,6 +57,16 @@
 source = "registry+https://github.com/rust-lang/crates.io-index;
 
 [[package]]
+name = "chrono"
+version = "0.4.11"
+source = "registry+https://github.com/rust-lang/crates.io-index;
+dependencies = [
+ "num-integer 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "clap"
 version = "2.33.0"
 source = "registry+https://github.com/rust-lang/crates.io-index;
@@ -87,11 +89,21 @@
 ]
 
 [[package]]
+name = "colored"
+version = "1.9.3"
+source = "registry+https://github.com/rust-lang/crates.io-index;
+dependencies = [
+ "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "cpython"
 version = "0.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index;
 dependencies = [
- "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.67 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "python27-sys 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "python3-sys 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -104,10 +116,10 @@
 dependencies = [
  "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "crossbeam-channel 0.4.2 
(registry+https://github.com/rust-lang/crates.io-index)",
- "crossbeam-deque 0.7.2 
(registry+https://github.com/rust-lang/crates.io-index)",
- "crossbeam-epoch 0.8.0 
(registry+https://github.com/rust-lang/crates.io-index)",
+ "crossbeam-deque 0.7.3 
(registry+https://github.com/rust-lang/crates.io-index)",
+ "crossbeam-epoch 0.8.2 
(registry+https://github.com/rust-lang/crates.io-index)",
  "crossbeam-queue 0.2.1 
(registry+https://github.com/rust-lang/crates.io-index)",
- "crossbeam-utils 0.7.0 

D8251: rust-status: traverse working directory in parallel

2020-03-11 Thread Raphaël Gomès
Alphare updated this revision to Diff 20708.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8251?vs=20565=20708

BRANCH
  default

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8251/new/

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

AFFECTED FILES
  rust/Cargo.lock
  rust/hg-core/Cargo.toml
  rust/hg-core/src/dirstate/status.rs

CHANGE DETAILS

diff --git a/rust/hg-core/src/dirstate/status.rs 
b/rust/hg-core/src/dirstate/status.rs
--- a/rust/hg-core/src/dirstate/status.rs
+++ b/rust/hg-core/src/dirstate/status.rs
@@ -300,61 +300,55 @@
 }
 
 /// Dispatch a single entry (file, folder, symlink...) found during `traverse`.
-/// If the entry is a folder that needs to be traversed, it will be pushed into
-/// `work`.
+/// If the entry is a folder that needs to be traversed, it will be handled
+/// in a separate thread.
+
 fn handle_traversed_entry<'a>(
-dir_entry: ,
-matcher: &(impl Matcher + Sync),
-root_dir: impl AsRef,
-dmap: ,
-filename: impl AsRef,
-old_results: , Dispatch>,
-ignore_fn: &(impl for<'r> Fn(&'r HgPath) -> bool + Sync),
-dir_ignore_fn: &(impl for<'r> Fn(&'r HgPath) -> bool + Sync),
+scope: ::Scope<'a>,
+files_sender: &'a crossbeam::Sender>,
+matcher: &'a (impl Matcher + Sync),
+root_dir: impl AsRef + Sync + Send + Copy + 'a,
+dmap: &'a DirstateMap,
+old_results: &'a FastHashMap, Dispatch>,
+ignore_fn: &'a (impl for<'r> Fn(&'r HgPath) -> bool + Sync),
+dir_ignore_fn: &'a (impl for<'r> Fn(&'r HgPath) -> bool + Sync),
 options: StatusOptions,
-) -> IoResult, Dispatch)>> {
+filename: HgPathBuf,
+dir_entry: DirEntry,
+) -> IoResult<()> {
 let file_type = dir_entry.file_type()?;
-let filename = filename.as_ref();
-let entry_option = dmap.get(filename);
+let entry_option = dmap.get();
 
 if file_type.is_dir() {
-// Do we need to traverse it?
-if !ignore_fn() || options.list_ignored {
-return traverse_dir(
-matcher,
-root_dir,
-dmap,
-filename.to_owned(),
-_results,
-ignore_fn,
-dir_ignore_fn,
-options,
-);
-}
-// Nested `if` until `rust-lang/rust#53668` is stable
-if let Some(entry) = entry_option {
-// Used to be a file, is now a folder
-if matcher.matches_everything() || matcher.matches() {
-return Ok(vec![(
-Cow::Owned(filename.to_owned()),
-dispatch_missing(entry.state),
-)]);
-}
-}
+handle_traversed_dir(
+scope,
+files_sender,
+matcher,
+root_dir,
+dmap,
+old_results,
+ignore_fn,
+dir_ignore_fn,
+options,
+entry_option,
+filename,
+);
 } else if file_type.is_file() || file_type.is_symlink() {
 if let Some(entry) = entry_option {
 if matcher.matches_everything() || matcher.matches() {
 let metadata = dir_entry.metadata()?;
-return Ok(vec![(
-Cow::Owned(filename.to_owned()),
-dispatch_found(
-,
-*entry,
-HgMetadata::from_metadata(metadata),
-_map,
-options,
-),
-)]);
+files_sender
+.send(Ok((
+filename.to_owned(),
+dispatch_found(
+,
+*entry,
+HgMetadata::from_metadata(metadata),
+_map,
+options,
+),
+)))
+.unwrap();
 }
 } else if (matcher.matches_everything() || matcher.matches())
 && !ignore_fn()
@@ -363,53 +357,96 @@
 && dir_ignore_fn()
 {
 if options.list_ignored {
-return Ok(vec![(
-Cow::Owned(filename.to_owned()),
-Dispatch::Ignored,
-)]);
+files_sender
+.send(Ok((filename.to_owned(), Dispatch::Ignored)))
+.unwrap();
 }
 } else {
-return Ok(vec![(
-Cow::Owned(filename.to_owned()),
-Dispatch::Unknown,
-)]);
+files_sender
+.send(Ok((filename.to_owned(), Dispatch::Unknown)))
+.unwrap();
 }
 } else if ignore_fn() && options.list_ignored {
-return 

D8226: debuginstall: add entry about re2 Rust bindings when applicable

2020-03-11 Thread Raphaël Gomès
Alphare updated this revision to Diff 20707.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8226?vs=20562=20707

BRANCH
  default

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8226/new/

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

AFFECTED FILES
  mercurial/debugcommands.py
  tests/test-install.t

CHANGE DETAILS

diff --git a/tests/test-install.t b/tests/test-install.t
--- a/tests/test-install.t
+++ b/tests/test-install.t
@@ -18,6 +18,7 @@
   checking available compression engines (*zlib*) (glob)
   checking available compression engines for wire protocol (*zlib*) (glob)
   checking "re2" regexp engine \((available|missing)\) (re)
+  checking "re2" regexp engine Rust bindings \((installed|missing)\) (re)
   checking templates (*mercurial?templates)... (glob)
   checking default template (*mercurial?templates?map-cmdline.default) (glob)
   checking commit editor... (*) (glob)
@@ -77,6 +78,7 @@
   checking available compression engines (*zlib*) (glob)
   checking available compression engines for wire protocol (*zlib*) (glob)
   checking "re2" regexp engine \((available|missing)\) (re)
+  checking "re2" regexp engine Rust bindings \((installed|missing)\) (re)
   checking templates (*mercurial?templates)... (glob)
   checking default template (*mercurial?templates?map-cmdline.default) (glob)
   checking commit editor... (*) (glob)
@@ -124,6 +126,7 @@
   checking available compression engines (*zlib*) (glob)
   checking available compression engines for wire protocol (*zlib*) (glob)
   checking "re2" regexp engine \((available|missing)\) (re)
+  checking "re2" regexp engine Rust bindings \((installed|missing)\) (re)
   checking templates (*mercurial?templates)... (glob)
   checking default template (*mercurial?templates?map-cmdline.default) (glob)
   checking commit editor... ($TESTTMP/tools/testeditor.exe)
@@ -151,6 +154,7 @@
   checking available compression engines (*zlib*) (glob)
   checking available compression engines for wire protocol (*zlib*) (glob)
   checking "re2" regexp engine \((available|missing)\) (re)
+  checking "re2" regexp engine Rust bindings \((installed|missing)\) (re)
   checking templates (*mercurial?templates)... (glob)
   checking default template (*mercurial?templates?map-cmdline.default) (glob)
   checking commit editor... (c:\foo\bar\baz.exe) (windows !)
@@ -207,6 +211,7 @@
   checking available compression engines (*) (glob)
   checking available compression engines for wire protocol (*) (glob)
   checking "re2" regexp engine \((available|missing)\) (re)
+  checking "re2" regexp engine Rust bindings \((installed|missing)\) (re)
   checking templates 
($TESTTMP/installenv/*/site-packages/mercurial/templates)... (glob)
   checking default template 
($TESTTMP/installenv/*/site-packages/mercurial/templates/map-cmdline.default) 
(glob)
   checking commit editor... (*) (glob)
@@ -247,6 +252,7 @@
   checking available compression engines (*) (glob)
   checking available compression engines for wire protocol (*) (glob)
   checking "re2" regexp engine \((available|missing)\) (re)
+  checking "re2" regexp engine Rust bindings \((installed|missing)\) (re)
   checking templates 
($TESTTMP/installenv/*/site-packages/mercurial/templates)... (glob)
   checking default template 
($TESTTMP/installenv/*/site-packages/mercurial/templates/map-cmdline.default) 
(glob)
   checking commit editor... (*) (glob)
diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py
--- a/mercurial/debugcommands.py
+++ b/mercurial/debugcommands.py
@@ -1650,6 +1650,13 @@
 fm.plain(_(b'checking "re2" regexp engine (%s)\n') % re2)
 fm.data(re2=bool(util._re2))
 
+rust_debug_mod = policy.importrust("debug")
+if rust_debug_mod is not None:
+re2_rust = b'installed' if rust_debug_mod.re2_installed else b'missing'
+
+msg = b'checking "re2" regexp engine Rust bindings (%s)\n'
+fm.plain(_(msg % re2_rust))
+
 # templates
 p = templater.templatepaths()
 fm.write(b'templatedirs', b'checking templates (%s)...\n', b' '.join(p))



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


D7931: rust-status: use bare hg status fastpath from Python

2020-03-11 Thread Raphaël Gomès
Alphare updated this revision to Diff 20706.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7931?vs=20559=20706

BRANCH
  default

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7931/new/

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

AFFECTED FILES
  mercurial/dirstate.py
  mercurial/match.py
  tests/test-subrepo-deep-nested-change.t

CHANGE DETAILS

diff --git a/tests/test-subrepo-deep-nested-change.t 
b/tests/test-subrepo-deep-nested-change.t
--- a/tests/test-subrepo-deep-nested-change.t
+++ b/tests/test-subrepo-deep-nested-change.t
@@ -355,6 +355,11 @@
   R sub1/sub2/folder/test.txt
   ! sub1/.hgsub
   ? sub1/x.hgsub
+  $ hg status -R sub1
+  warning: subrepo spec file 'sub1/.hgsub' not found
+  R .hgsubstate
+  ! .hgsub
+  ? x.hgsub
   $ mv sub1/x.hgsub sub1/.hgsub
   $ hg update -Cq
   $ touch sub1/foo
diff --git a/mercurial/match.py b/mercurial/match.py
--- a/mercurial/match.py
+++ b/mercurial/match.py
@@ -666,7 +666,10 @@
 class includematcher(basematcher):
 def __init__(self, root, kindpats, badfn=None):
 super(includematcher, self).__init__(badfn)
-
+if rustmod is not None:
+# We need to pass the patterns to Rust because they can contain
+# patterns from the user interface
+self._kindpats = kindpats
 self._pats, self.matchfn = _buildmatch(kindpats, b'(?:/|$)', root)
 self._prefix = _prefix(kindpats)
 roots, dirs, parents = _rootsdirsandparents(kindpats)
diff --git a/mercurial/dirstate.py b/mercurial/dirstate.py
--- a/mercurial/dirstate.py
+++ b/mercurial/dirstate.py
@@ -27,6 +27,7 @@
 policy,
 pycompat,
 scmutil,
+sparse,
 txnutil,
 util,
 )
@@ -1083,7 +1084,7 @@
 results[next(iv)] = st
 return results
 
-def _rust_status(self, matcher, list_clean):
+def _rust_status(self, matcher, list_clean, list_ignored, list_unknown):
 # Force Rayon (Rust parallelism library) to respect the number of
 # workers. This is a temporary workaround until Rust code knows
 # how to read the config file.
@@ -1101,16 +1102,45 @@
 added,
 removed,
 deleted,
+clean,
+ignored,
 unknown,
-clean,
+warnings,
+bad,
 ) = rustmod.status(
 self._map._rustmap,
 matcher,
 self._rootdir,
-bool(list_clean),
+self._ignorefiles(),
+self._checkexec,
 self._lastnormaltime,
-self._checkexec,
+bool(list_clean),
+bool(list_ignored),
+bool(list_unknown),
 )
+if self._ui.warn:
+for item in warnings:
+if isinstance(item, tuple):
+file_path, syntax = item
+msg = _(b"%s: ignoring invalid syntax '%s'\n") % (
+file_path,
+syntax,
+)
+self._ui.warn(msg)
+else:
+msg = _(b"skipping unreadable pattern file '%s': %s\n")
+self._ui.warn(
+msg
+% (
+pathutil.canonpath(
+self._rootdir, self._rootdir, item
+),
+b"No such file or directory",
+)
+)
+
+for (fn, message) in bad:
+matcher.bad(fn, encoding.strtolocal(message))
 
 status = scmutil.status(
 modified=modified,
@@ -1118,7 +1148,7 @@
 removed=removed,
 deleted=deleted,
 unknown=unknown,
-ignored=[],
+ignored=ignored,
 clean=clean,
 )
 return (lookup, status)
@@ -1148,26 +1178,34 @@
 
 use_rust = True
 
-allowed_matchers = (matchmod.alwaysmatcher, matchmod.exactmatcher)
+allowed_matchers = (
+matchmod.alwaysmatcher,
+matchmod.exactmatcher,
+matchmod.includematcher,
+)
 
 if rustmod is None:
 use_rust = False
+elif self._checkcase:
+# Case-insensitive filesystems are not handled yet
+use_rust = False
 elif subrepos:
 use_rust = False
-elif bool(listunknown):
-# Pathauditor does not exist yet in Rust, unknown files
-# can't be trusted.
+elif sparse.enabled:
 use_rust = False
-elif self._ignorefiles() and listignored:
-# Rust has no ignore mechanism yet, so don't use Rust for
-# commands that need ignore.
+elif match.traversedir is not None:
 use_rust = False
 elif not isinstance(match, allowed_matchers):
 # Matchers have 

D8184: nodemap: track the tip_node for validation

2020-03-11 Thread marmoute (Pierre-Yves David)
Closed by commit rHG6c906eaedd0d: nodemap: track the tip_node for validation 
(authored by marmoute).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8184?vs=20681=20703

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8184/new/

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

AFFECTED FILES
  mercurial/configitems.py
  mercurial/debugcommands.py
  mercurial/revlog.py
  mercurial/revlogutils/nodemap.py
  tests/test-persistent-nodemap.t

CHANGE DETAILS

diff --git a/tests/test-persistent-nodemap.t b/tests/test-persistent-nodemap.t
--- a/tests/test-persistent-nodemap.t
+++ b/tests/test-persistent-nodemap.t
@@ -14,10 +14,11 @@
   $ hg debugnodemap --metadata
   uid:  (glob)
   tip-rev: 5000
+  tip-node: 06ddac466af534d365326c13c3879f97caca3cb1
   data-length: 122880
   data-unused: 0
   $ f --size .hg/store/00changelog.n
-  .hg/store/00changelog.n: size=42
+  .hg/store/00changelog.n: size=70
 
 Simple lookup works
 
@@ -95,18 +96,20 @@
   $ hg debugnodemap --metadata
   uid:  (glob)
   tip-rev: 5001
+  tip-node: 2dd9b5258caa46469ff07d4a3da1eb3529a51f49
   data-length: 122880
   data-unused: 0
 #else
   $ hg debugnodemap --metadata
   uid:  (glob)
   tip-rev: 5001
+  tip-node: 2dd9b5258caa46469ff07d4a3da1eb3529a51f49
   data-length: 123072
   data-unused: 192
 #endif
 
   $ f --size .hg/store/00changelog.n
-  .hg/store/00changelog.n: size=42
+  .hg/store/00changelog.n: size=70
 
 (The pure code use the debug code that perform incremental update, the C code 
reencode from scratch)
 
@@ -148,6 +151,7 @@
   $ hg debugnodemap --metadata
   uid:  (glob)
   tip-rev: 5002
+  tip-node: 6ce944fafcee85af91f29ea5b51654cc6101ad7e
   data-length: 123328
   data-unused: 384
   $ f --sha256 .hg/store/00changelog-*.nd --size
@@ -157,6 +161,7 @@
   $ hg debugnodemap --metadata
   uid:  (glob)
   tip-rev: 5002
+  tip-node: 6ce944fafcee85af91f29ea5b51654cc6101ad7e
   data-length: 123328
   data-unused: 384
   $ f --sha256 .hg/store/00changelog-*.nd --size
@@ -166,6 +171,7 @@
   $ hg debugnodemap --metadata
   uid:  (glob)
   tip-rev: 5002
+  tip-node: 6ce944fafcee85af91f29ea5b51654cc6101ad7e
   data-length: 122944
   data-unused: 0
   $ f --sha256 .hg/store/00changelog-*.nd --size
@@ -181,12 +187,14 @@
   $ hg debugnodemap --metadata
   uid:  (glob)
   tip-rev: 5002
+  tip-node: 6ce944fafcee85af91f29ea5b51654cc6101ad7e
   data-length: 122944
   data-unused: 0
 #else
   $ hg debugnodemap --metadata
   uid:  (glob)
   tip-rev: 5002
+  tip-node: 6ce944fafcee85af91f29ea5b51654cc6101ad7e
   data-length: 122944
   data-unused: 0
 #endif
@@ -215,6 +223,7 @@
   $ hg debugnodemap --metadata
   uid:  (glob)
   tip-rev: 5003
+  tip-node: 5c049e9c4a4af159bdcd65dce1b6bf303a0da6cf
   data-length: 123200 (pure !)
   data-length: 123200 (rust !)
   data-length: 122944 (no-rust no-pure !)
@@ -225,7 +234,50 @@
   $ hg debugnodemap --metadata
   uid:  (glob)
   tip-rev: 5002
+  tip-node: 6ce944fafcee85af91f29ea5b51654cc6101ad7e
   data-length: 122944
   data-unused: 0
   $ hg log -r "$NODE" -T '{rev}\n'
   5003
+
+changelog altered
+-
+
+If the nodemap is not gated behind a requirements, an unaware client can alter
+the repository so the revlog used to generate the nodemap is not longer
+compatible with the persistent nodemap. We need to detect that.
+
+  $ hg up "$NODE~5"
+  0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+  $ echo bar > babar
+  $ hg add babar
+  $ hg ci -m 'babar'
+  created new head
+  $ OTHERNODE=`hg log -r tip -T '{node}\n'`
+  $ hg log -r "$OTHERNODE" -T '{rev}\n'
+  5004
+
+  $ hg --config extensions.strip= strip --rev "$NODE~1" --no-backup
+
+the nodemap should detect the changelog have been tampered with and recover.
+
+  $ hg debugnodemap --metadata
+  uid:  (glob)
+  tip-rev: 5002
+  tip-node: 42bf3068c7ddfdfded53c4eb11d02266faeebfee
+  data-length: 123456 (pure !)
+  data-length: 246464 (rust !)
+  data-length: 123008 (no-pure no-rust !)
+  data-unused: 448 (pure !)
+  data-unused: 123904 (rust !)
+  data-unused: 0 (no-pure no-rust !)
+
+  $ cp -f ../tmp-copies/* .hg/store/
+  $ hg debugnodemap --metadata
+  uid:  (glob)
+  tip-rev: 5002
+  tip-node: 6ce944fafcee85af91f29ea5b51654cc6101ad7e
+  data-length: 122944
+  data-unused: 0
+  $ hg log -r "$OTHERNODE" -T '{rev}\n'
+  5002
diff --git a/mercurial/revlogutils/nodemap.py b/mercurial/revlogutils/nodemap.py
--- a/mercurial/revlogutils/nodemap.py
+++ b/mercurial/revlogutils/nodemap.py
@@ -38,10 +38,12 @@
 return None
 offset += S_VERSION.size
 headers = S_HEADER.unpack(pdata[offset : offset + S_HEADER.size])
-

D8187: nodemap: make sure hooks have access to an up-to-date version

2020-03-11 Thread marmoute (Pierre-Yves David)
Closed by commit rHG64e2f603de9d: nodemap: make sure hooks have access to an 
up-to-date version (authored by marmoute).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8187?vs=20684=20704

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8187/new/

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

AFFECTED FILES
  mercurial/configitems.py
  mercurial/revlog.py
  mercurial/revlogutils/nodemap.py
  tests/test-persistent-nodemap.t

CHANGE DETAILS

diff --git a/tests/test-persistent-nodemap.t b/tests/test-persistent-nodemap.t
--- a/tests/test-persistent-nodemap.t
+++ b/tests/test-persistent-nodemap.t
@@ -281,3 +281,39 @@
   data-unused: 0
   $ hg log -r "$OTHERNODE" -T '{rev}\n'
   5002
+
+Check transaction related property
+==
+
+An up to date nodemap should be available to shell hooks,
+
+  $ echo dsljfl > a
+  $ hg add a
+  $ hg ci -m a
+  $ hg debugnodemap --metadata
+  uid:  (glob)
+  tip-rev: 5003
+  tip-node: c91af76d172f1053cca41b83f7c2e4e514fe2bcf
+  data-length: 123008
+  data-unused: 0
+  $ echo babar2 > babar
+  $ hg ci -m 'babar2' --config "hooks.pretxnclose.nodemap-test=hg debugnodemap 
--metadata"
+  uid:  (glob)
+  tip-rev: 5004
+  tip-node: ba87cd9559559e4b91b28cb140d003985315e031
+  data-length: 123328 (pure !)
+  data-length: 123328 (rust !)
+  data-length: 123136 (no-pure no-rust !)
+  data-unused: 192 (pure !)
+  data-unused: 192 (rust !)
+  data-unused: 0 (no-pure no-rust !)
+  $ hg debugnodemap --metadata
+  uid:  (glob)
+  tip-rev: 5004
+  tip-node: ba87cd9559559e4b91b28cb140d003985315e031
+  data-length: 123328 (pure !)
+  data-length: 123328 (rust !)
+  data-length: 123136 (no-pure no-rust !)
+  data-unused: 192 (pure !)
+  data-unused: 192 (rust !)
+  data-unused: 0 (no-pure no-rust !)
diff --git a/mercurial/revlogutils/nodemap.py b/mercurial/revlogutils/nodemap.py
--- a/mercurial/revlogutils/nodemap.py
+++ b/mercurial/revlogutils/nodemap.py
@@ -75,6 +75,9 @@
 callback_id = b"revlog-persistent-nodemap-%s" % revlog.nodemap_file
 if tr.hasfinalize(callback_id):
 return  # no need to register again
+tr.addpending(
+callback_id, lambda tr: _persist_nodemap(tr, revlog, pending=True)
+)
 tr.addfinalize(callback_id, lambda tr: _persist_nodemap(tr, revlog))
 
 
@@ -101,7 +104,7 @@
 notr._postclose[k](None)
 
 
-def _persist_nodemap(tr, revlog):
+def _persist_nodemap(tr, revlog, pending=False):
 """Write nodemap data on disk for a given revlog
 """
 if getattr(revlog, 'filteredrevs', ()):
@@ -169,7 +172,10 @@
 target_docket.tip_node = revlog.node(target_docket.tip_rev)
 # EXP-TODO: if this is a cache, this should use a cache vfs, not a
 # store vfs
-with revlog.opener(revlog.nodemap_file, b'w', atomictemp=True) as fp:
+file_path = revlog.nodemap_file
+if pending:
+file_path += b'.a'
+with revlog.opener(file_path, b'w', atomictemp=True) as fp:
 fp.write(target_docket.serialize())
 revlog._nodemap_docket = target_docket
 if feed_data:
@@ -304,7 +310,10 @@
 
 def _rawdata_filepath(revlog, docket):
 """The (vfs relative) nodemap's rawdata file for a given uid"""
-prefix = revlog.nodemap_file[:-2]
+if revlog.nodemap_file.endswith(b'.n.a'):
+prefix = revlog.nodemap_file[:-4]
+else:
+prefix = revlog.nodemap_file[:-2]
 return b"%s-%s.nd" % (prefix, docket.uid)
 
 
diff --git a/mercurial/revlog.py b/mercurial/revlog.py
--- a/mercurial/revlog.py
+++ b/mercurial/revlog.py
@@ -436,7 +436,14 @@
 self.datafile = datafile or (indexfile[:-2] + b".d")
 self.nodemap_file = None
 if persistentnodemap:
-self.nodemap_file = indexfile[:-2] + b".n"
+if indexfile.endswith(b'.a'):
+pending_path = indexfile[:-4] + b".n.a"
+if opener.exists(pending_path):
+self.nodemap_file = pending_path
+else:
+self.nodemap_file = indexfile[:-4] + b".n"
+else:
+self.nodemap_file = indexfile[:-2] + b".n"
 
 self.opener = opener
 #  When True, indexfile is opened with checkambig=True at writing, to
diff --git a/mercurial/configitems.py b/mercurial/configitems.py
--- a/mercurial/configitems.py
+++ b/mercurial/configitems.py
@@ -408,7 +408,6 @@
 # TODO before getting `persistent-nodemap` out of experimental
 #
 # * code/tests around aborted transaction
-# * code/tests around pending data for hooks
 # * regenerate a new nodemap when the unused/total ration is to high
 # * decide for a "status" of the persistent nodemap and associated location
 #   - part of the store next the revlog itself (new requirements)



To: marmoute, 

D8188: nodemap: make sure the nodemap docket is updated after the changelog

2020-03-11 Thread marmoute (Pierre-Yves David)
Closed by commit rHG448d700e0d27: nodemap: make sure the nodemap docket is 
updated after the changelog (authored by marmoute).
This revision was automatically updated to reflect the committed changes.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8188?vs=20685=20705

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8188/new/

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

AFFECTED FILES
  mercurial/revlogutils/nodemap.py

CHANGE DETAILS

diff --git a/mercurial/revlogutils/nodemap.py b/mercurial/revlogutils/nodemap.py
--- a/mercurial/revlogutils/nodemap.py
+++ b/mercurial/revlogutils/nodemap.py
@@ -72,7 +72,9 @@
 return  # inlined revlog are too small for this to be relevant
 if revlog.nodemap_file is None:
 return  # we do not use persistent_nodemap on this revlog
-callback_id = b"revlog-persistent-nodemap-%s" % revlog.nodemap_file
+
+# we need to happen after the changelog finalization, in that use "cl-"
+callback_id = b"nm-revlog-persistent-nodemap-%s" % revlog.nodemap_file
 if tr.hasfinalize(callback_id):
 return  # no need to register again
 tr.addpending(



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


D8163: nodemap: use data from the index in debugnodemap --dump-new

2020-03-11 Thread marmoute (Pierre-Yves David)
Closed by commit rHGfebe88a6f7f7: nodemap: use data from the index in 
debugnodemap --dump-new (authored by marmoute).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8163?vs=20661=20700

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8163/new/

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

AFFECTED FILES
  mercurial/debugcommands.py

CHANGE DETAILS

diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py
--- a/mercurial/debugcommands.py
+++ b/mercurial/debugcommands.py
@@ -2109,7 +2109,10 @@
 if opts['dump_new']:
 unfi = repo.unfiltered()
 cl = unfi.changelog
-data = nodemap.persistent_data(cl.index)
+if util.safehasattr(cl.index, "nodemap_data_all"):
+data = cl.index.nodemap_data_all()
+else:
+data = nodemap.persistent_data(cl.index)
 ui.write(data)
 elif opts['dump_disk']:
 unfi = repo.unfiltered()



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


D8164: rust-nodemap: automatically use the rust index for persistent nodemap

2020-03-11 Thread marmoute (Pierre-Yves David)
Closed by commit rHGe7fff9c3cdac: rust-nodemap: automatically use the rust 
index for persistent nodemap (authored by marmoute).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8164?vs=20679=20701

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8164/new/

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

AFFECTED FILES
  mercurial/revlog.py
  tests/test-persistent-nodemap.t

CHANGE DETAILS

diff --git a/tests/test-persistent-nodemap.t b/tests/test-persistent-nodemap.t
--- a/tests/test-persistent-nodemap.t
+++ b/tests/test-persistent-nodemap.t
@@ -2,7 +2,6 @@
 Test the persistent on-disk nodemap
 ===
 
-
   $ hg init test-repo
   $ cd test-repo
   $ cat << EOF >> .hg/hgrc
@@ -26,6 +25,35 @@
   $ hg log -r "$ANYNODE" --template '{rev}\n'
   5000
 
+
+#if rust
+
+  $ f --sha256 .hg/store/00changelog-*.nd
+  .hg/store/00changelog-.nd: 
sha256=1e38e9ffaa45cad13f15c1a9880ad606f4241e8beea2f61b4d5365abadfb55f6 (glob)
+  $ hg debugnodemap --dump-new | f --sha256 --size
+  size=122880, 
sha256=1e38e9ffaa45cad13f15c1a9880ad606f4241e8beea2f61b4d5365abadfb55f6
+  $ hg debugnodemap --dump-disk | f --sha256 --bytes=256 --hexdump --size
+  size=122880, 
sha256=1e38e9ffaa45cad13f15c1a9880ad606f4241e8beea2f61b4d5365abadfb55f6
+  : 00 00 00 76 00 00 01 65 00 00 00 95 00 00 01 34 |...v...e...4|
+  0010: 00 00 00 19 00 00 01 69 00 00 00 ab 00 00 00 4b |...i...K|
+  0020: 00 00 00 07 00 00 01 4c 00 00 00 f8 00 00 00 8f |...L|
+  0030: 00 00 00 c0 00 00 00 a7 00 00 00 89 00 00 01 46 |...F|
+  0040: 00 00 00 92 00 00 01 bc 00 00 00 71 00 00 00 ac |...q|
+  0050: 00 00 00 af 00 00 00 b4 00 00 00 34 00 00 01 ca |...4|
+  0060: 00 00 00 23 00 00 01 45 00 00 00 2d 00 00 00 b2 |...#...E...-|
+  0070: 00 00 00 56 00 00 01 0f 00 00 00 4e 00 00 02 4c |...V...N...L|
+  0080: 00 00 00 e7 00 00 00 cd 00 00 01 5b 00 00 00 78 |...[...x|
+  0090: 00 00 00 e3 00 00 01 8e 00 00 00 4f 00 00 00 b1 |...O|
+  00a0: 00 00 00 30 00 00 00 11 00 00 00 25 00 00 00 d2 |...0...%|
+  00b0: 00 00 00 ec 00 00 00 69 00 00 01 2b 00 00 01 2e |...i...+|
+  00c0: 00 00 00 aa 00 00 00 15 00 00 00 3a 00 00 01 4e |...:...N|
+  00d0: 00 00 00 4d 00 00 00 9d 00 00 00 8e 00 00 00 a4 |...M|
+  00e0: 00 00 00 c3 00 00 00 eb 00 00 00 29 00 00 00 ad |...)|
+  00f0: 00 00 01 3a 00 00 01 32 00 00 00 04 00 00 00 53 |...:...2...S|
+
+
+#else
+
   $ f --sha256 .hg/store/00changelog-*.nd
   .hg/store/00changelog-.nd: 
sha256=b961925120e1c9bc345c199b2cc442abc477029fdece37ef9d99cbe59c0558b7 (glob)
   $ hg debugnodemap --dump-new | f --sha256 --size
@@ -48,6 +76,9 @@
   00d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ||
   00e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ||
   00f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ||
+
+#endif
+
   $ hg debugnodemap --check
   revision in index:   5001
   revision in nodemap: 5001
@@ -60,19 +91,20 @@
   $ hg add foo
   $ hg ci -m 'foo'
 
-#if pure
+#if no-pure no-rust
+  $ hg debugnodemap --metadata
+  uid:  (glob)
+  tip-rev: 5001
+  data-length: 122880
+  data-unused: 0
+#else
   $ hg debugnodemap --metadata
   uid:  (glob)
   tip-rev: 5001
   data-length: 123072
   data-unused: 192
-#else
-  $ hg debugnodemap --metadata
-  uid:  (glob)
-  tip-rev: 5001
-  data-length: 122880
-  data-unused: 0
 #endif
+
   $ f --size .hg/store/00changelog.n
   .hg/store/00changelog.n: size=42
 
@@ -81,11 +113,16 @@
 #if pure
   $ f --sha256 .hg/store/00changelog-*.nd --size
   .hg/store/00changelog-.nd: size=123072, 
sha256=136472751566c8198ff09e306a7d2f9bd18bd32298d614752b73da4d6df23340 (glob)
+#endif
 
-#else
+#if rust
+  $ f --sha256 .hg/store/00changelog-*.nd --size
+  .hg/store/00changelog-.nd: size=123072, 
sha256=ccc8a43310ace13812fcc648683e259346754ef934c12dd238cf9b7fadfe9a4b (glob)
+#endif
+
+#if no-pure no-rust
   $ f --sha256 .hg/store/00changelog-*.nd --size
   .hg/store/00changelog-.nd: size=122880, 
sha256=bfafebd751c4f6d116a76a37a1dee2a251747affe7efbcc4f4842ccc746d4db9 (glob)
-
 #endif
 
   $ hg debugnodemap --check
@@ -115,8 +152,17 @@
   data-unused: 384
   $ f --sha256 .hg/store/00changelog-*.nd --size
   .hg/store/00changelog-.nd: size=123328, 
sha256=10d26e9776b6596af0f89143a54eba8cc581e929c38242a02a7b0760698c6c70 (glob)
-
-#else
+#endif
+#if rust
+  $ hg debugnodemap --metadata
+  uid:  (glob)
+  tip-rev: 5002
+  data-length: 123328
+  data-unused: 384
+  $ f --sha256 .hg/store/00changelog-*.nd --size
+  

D8181: nodemap: add a todo list for getting out of experimental

2020-03-11 Thread marmoute (Pierre-Yves David)
Closed by commit rHG15a033cabc19: nodemap: add a todo list for getting out of 
experimental (authored by marmoute).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8181?vs=20580=20702

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8181/new/

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

AFFECTED FILES
  mercurial/configitems.py

CHANGE DETAILS

diff --git a/mercurial/configitems.py b/mercurial/configitems.py
--- a/mercurial/configitems.py
+++ b/mercurial/configitems.py
@@ -405,6 +405,23 @@
 coreconfigitem(
 b'devel', b'legacy.exchange', default=list,
 )
+# TODO before getting `persistent-nodemap` out of experimental
+#
+# * code/tests around aborted transaction
+# * code/tests around pending data for hooks
+# * code/tests around detection of invalid cache
+#   (eg: after strip from an incompatible client)
+# * regenerate a new nodemap when the unused/total ration is to high
+# * decide for a "status" of the persistent nodemap and associated location
+#   - part of the store next the revlog itself (new requirements)
+#   - part of the cache directory
+#   - part of an `index` directory
+# (https://www.mercurial-scm.org/wiki/ComputedIndexPlan)
+# * do we want to use this for more than just changelog? if so we need:
+#   - simpler "pending" logic for them
+#   - double check the memory story (we dont want to keep all revlog in memory)
+#   - think about the naming scheme if we are in "cache"
+# * increment the version format to "1" and freeze it.
 coreconfigitem(
 b'devel', b'persistent-nodemap', default=False,
 )



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


D8161: rust-nodemap: also clear Rust data in `clearcaches`

2020-03-11 Thread gracinet (Georges Racinet)
Closed by commit rHGcadcc8c20860: rust-nodemap: also clear Rust data in 
`clearcaches` (authored by gracinet).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8161?vs=20660=20699

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8161/new/

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

AFFECTED FILES
  rust/hg-cpython/src/revlog.rs

CHANGE DETAILS

diff --git a/rust/hg-cpython/src/revlog.rs b/rust/hg-cpython/src/revlog.rs
--- a/rust/hg-cpython/src/revlog.rs
+++ b/rust/hg-cpython/src/revlog.rs
@@ -161,8 +161,12 @@
 self.call_cindex(py, "commonancestorsheads", args, kw)
 }
 
-/// clear the index caches
+/// Clear the index caches and inner py_class data.
+/// It is Python's responsibility to call `update_nodemap_data` again.
 def clearcaches(, *args, **kw) -> PyResult {
+self.nt(py).borrow_mut().take();
+self.docket(py).borrow_mut().take();
+self.mmap(py).borrow_mut().take();
 self.call_cindex(py, "clearcaches", args, kw)
 }
 
@@ -231,7 +235,7 @@
 // `index_getitem` does not handle conversion from PyLong,
 // which expressions such as [e for e in index] internally use.
 // Note that we don't seem to have a direct way to call
-// PySequence_GetItem (does the job), which would be better for
+// PySequence_GetItem (does the job), which would possibly be better
 // for performance
 let key = match key.extract::(py) {
 Ok(rev) => rev.to_py_object(py).into_object(),



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


D8160: rust-nodemap: add binding to `nodemap_update_data`

2020-03-11 Thread gracinet (Georges Racinet)
Closed by commit rHG15febf99a9c6: rust-nodemap: add binding to 
`nodemap_update_data` (authored by gracinet).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8160?vs=20659=20698

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8160/new/

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

AFFECTED FILES
  rust/hg-cpython/src/revlog.rs

CHANGE DETAILS

diff --git a/rust/hg-cpython/src/revlog.rs b/rust/hg-cpython/src/revlog.rs
--- a/rust/hg-cpython/src/revlog.rs
+++ b/rust/hg-cpython/src/revlog.rs
@@ -10,6 +10,7 @@
 utils::{node_from_py_bytes, node_from_py_object},
 };
 use cpython::{
+buffer::{Element, PyBuffer},
 exc::{IndexError, ValueError},
 ObjectProtocol, PyBytes, PyClone, PyDict, PyErr, PyModule, PyObject,
 PyResult, PyString, PyTuple, Python, PythonObject, ToPyObject,
@@ -36,6 +37,8 @@
 data cindex: RefCell;
 data nt: RefCell>;
 data docket: RefCell>;
+// Holds a reference to the mmap'ed persistent nodemap data
+data mmap: RefCell>;
 
 def __new__(_cls, cindex: PyObject) -> PyResult {
 Self::new(py, cindex)
@@ -268,6 +271,14 @@
 def nodemap_data_incremental() -> PyResult {
 self.inner_nodemap_data_incremental(py)
 }
+def update_nodemap_data(
+,
+docket: PyObject,
+nm_data: PyObject
+) -> PyResult {
+self.inner_update_nodemap_data(py, docket, nm_data)
+}
+
 
 });
 
@@ -278,6 +289,7 @@
 RefCell::new(cindex::Index::new(py, cindex)?),
 RefCell::new(None),
 RefCell::new(None),
+RefCell::new(None),
 )
 }
 
@@ -374,6 +386,56 @@
 .to_py_object(py)
 .into_object())
 }
+
+/// Update the nodemap from the new (mmaped) data.
+/// The docket is kept as a reference for later incremental calls.
+fn inner_update_nodemap_data(
+,
+py: Python,
+docket: PyObject,
+nm_data: PyObject,
+) -> PyResult {
+let buf = PyBuffer::get(py, _data)?;
+let len = buf.item_count();
+
+// Build a slice from the mmap'ed buffer data
+let cbuf = buf.buf_ptr();
+let bytes = if std::mem::size_of::() == buf.item_size()
+&& buf.is_c_contiguous()
+&& u8::is_compatible_format(buf.format())
+{
+unsafe { std::slice::from_raw_parts(cbuf as *const u8, len) }
+} else {
+return Err(PyErr::new::(
+py,
+"Nodemap data buffer has an invalid memory representation"
+.to_string(),
+));
+};
+
+// Keep a reference to the mmap'ed buffer, otherwise we get a dangling
+// pointer.
+self.mmap(py).borrow_mut().replace(buf);
+
+let mut nt = NodeTree::load_bytes(Box::new(bytes), len);
+
+let data_tip =
+docket.getattr(py, "tip_rev")?.extract::(py)?;
+self.docket(py).borrow_mut().replace(docket.clone_ref(py));
+let idx = self.cindex(py).borrow();
+let current_tip = idx.len();
+
+for r in (data_tip + 1)..current_tip as Revision {
+let rev = r as Revision;
+// in this case node() won't ever return None
+nt.insert(&*idx, idx.node(rev).unwrap(), rev)
+.map_err(|e| nodemap_error(py, e))?
+}
+
+*self.nt(py).borrow_mut() = Some(nt);
+
+Ok(py.None())
+}
 }
 
 fn revlog_error(py: Python) -> PyErr {



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


D8159: rust-nodemap: add binding for `nodemap_data_incremental`

2020-03-11 Thread gracinet (Georges Racinet)
Closed by commit rHG5bbf887275b0: rust-nodemap: add binding for 
`nodemap_data_incremental` (authored by gracinet).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8159?vs=20658=20697

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8159/new/

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

AFFECTED FILES
  rust/hg-cpython/src/revlog.rs

CHANGE DETAILS

diff --git a/rust/hg-cpython/src/revlog.rs b/rust/hg-cpython/src/revlog.rs
--- a/rust/hg-cpython/src/revlog.rs
+++ b/rust/hg-cpython/src/revlog.rs
@@ -15,7 +15,7 @@
 PyResult, PyString, PyTuple, Python, PythonObject, ToPyObject,
 };
 use hg::{
-nodemap::{NodeMapError, NodeTree},
+nodemap::{Block, NodeMapError, NodeTree},
 revlog::{nodemap::NodeMap, RevlogIndex},
 NodeError, Revision,
 };
@@ -35,6 +35,7 @@
 py_class!(pub class MixedIndex |py| {
 data cindex: RefCell;
 data nt: RefCell>;
+data docket: RefCell>;
 
 def __new__(_cls, cindex: PyObject) -> PyResult {
 Self::new(py, cindex)
@@ -264,6 +265,9 @@
 self.inner_nodemap_data_all(py)
 }
 
+def nodemap_data_incremental() -> PyResult {
+self.inner_nodemap_data_incremental(py)
+}
 
 });
 
@@ -273,6 +277,7 @@
 py,
 RefCell::new(cindex::Index::new(py, cindex)?),
 RefCell::new(None),
+RefCell::new(None),
 )
 }
 
@@ -347,6 +352,28 @@
 let bytes = PyBytes::new(py, );
 Ok(bytes)
 }
+
+/// Returns the last saved docket along with the size of any changed data
+/// (in number of blocks), and said data as bytes.
+fn inner_nodemap_data_incremental(
+,
+py: Python,
+) -> PyResult {
+let docket = self.docket(py).borrow();
+let docket = match docket.as_ref() {
+Some(d) => d,
+None => return Ok(py.None()),
+};
+
+let node_tree = self.get_nodetree(py)?.borrow_mut().take().unwrap();
+let masked_blocks = node_tree.masked_readonly_blocks();
+let (_, data) = node_tree.into_readonly_and_added_bytes();
+let changed = masked_blocks * std::mem::size_of::();
+
+Ok((docket, changed, PyBytes::new(py, ))
+.to_py_object(py)
+.into_object())
+}
 }
 
 fn revlog_error(py: Python) -> PyErr {



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


D8158: rust-nodemap: add binding for `nodemap_data_all`

2020-03-11 Thread gracinet (Georges Racinet)
Closed by commit rHGb581231ae9d1: rust-nodemap: add binding for 
`nodemap_data_all` (authored by gracinet).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8158?vs=20657=20696

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8158/new/

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

AFFECTED FILES
  rust/hg-cpython/src/revlog.rs

CHANGE DETAILS

diff --git a/rust/hg-cpython/src/revlog.rs b/rust/hg-cpython/src/revlog.rs
--- a/rust/hg-cpython/src/revlog.rs
+++ b/rust/hg-cpython/src/revlog.rs
@@ -260,6 +260,10 @@
 }
 }
 
+def nodemap_data_all() -> PyResult {
+self.inner_nodemap_data_all(py)
+}
+
 
 });
 
@@ -320,6 +324,29 @@
 pub fn clone_cindex(, py: Python) -> cindex::Index {
 self.cindex(py).borrow().clone_ref(py)
 }
+
+/// Returns the full nodemap bytes to be written as-is to disk
+fn inner_nodemap_data_all(, py: Python) -> PyResult {
+let nodemap = self.get_nodetree(py)?.borrow_mut().take().unwrap();
+let (readonly, bytes) = nodemap.into_readonly_and_added_bytes();
+
+// If there's anything readonly, we need to build the data again from
+// scratch
+let bytes = if readonly.len() > 0 {
+let mut nt = NodeTree::load_bytes(Box::new(vec![]), 0);
+self.fill_nodemap(py,  nt)?;
+
+let (readonly, bytes) = nt.into_readonly_and_added_bytes();
+assert_eq!(readonly.len(), 0);
+
+bytes
+} else {
+bytes
+};
+
+let bytes = PyBytes::new(py, );
+Ok(bytes)
+}
 }
 
 fn revlog_error(py: Python) -> PyErr {



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


D8157: rust-nodemap: use proper Index API instead of using the C API

2020-03-11 Thread Raphaël Gomès
Closed by commit rHG857cc79247ac: rust-nodemap: use proper Index API instead of 
using the C API (authored by Alphare).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8157?vs=20656=20695

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8157/new/

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

AFFECTED FILES
  rust/hg-cpython/src/revlog.rs

CHANGE DETAILS

diff --git a/rust/hg-cpython/src/revlog.rs b/rust/hg-cpython/src/revlog.rs
--- a/rust/hg-cpython/src/revlog.rs
+++ b/rust/hg-cpython/src/revlog.rs
@@ -5,12 +5,20 @@
 // This software may be used and distributed according to the terms of the
 // GNU General Public License version 2 or any later version.
 
-use crate::cindex;
+use crate::{
+cindex,
+utils::{node_from_py_bytes, node_from_py_object},
+};
 use cpython::{
-exc::ValueError, ObjectProtocol, PyClone, PyDict, PyErr, PyModule,
-PyObject, PyResult, PyTuple, Python, PythonObject, ToPyObject,
+exc::{IndexError, ValueError},
+ObjectProtocol, PyBytes, PyClone, PyDict, PyErr, PyModule, PyObject,
+PyResult, PyString, PyTuple, Python, PythonObject, ToPyObject,
 };
-use hg::{nodemap::NodeMapError, NodeError, Revision};
+use hg::{
+nodemap::{NodeMapError, NodeTree},
+revlog::{nodemap::NodeMap, RevlogIndex},
+NodeError, Revision,
+};
 use std::cell::RefCell;
 
 /// Return a Struct implementing the Graph trait
@@ -26,6 +34,7 @@
 
 py_class!(pub class MixedIndex |py| {
 data cindex: RefCell;
+data nt: RefCell>;
 
 def __new__(_cls, cindex: PyObject) -> PyResult {
 Self::new(py, cindex)
@@ -42,8 +51,99 @@
 Ok(self.cindex(py).borrow().inner().clone_ref(py))
 }
 
+// Index API involving nodemap, as defined in mercurial/pure/parsers.py
 
+/// Return Revision if found, raises a bare `error.RevlogError`
+/// in case of ambiguity, same as C version does
+def get_rev(, node: PyBytes) -> PyResult> {
+let opt = self.get_nodetree(py)?.borrow();
+let nt = opt.as_ref().unwrap();
+let idx = &*self.cindex(py).borrow();
+let node = node_from_py_bytes(py, )?;
+nt.find_bin(idx, ().into()).map_err(|e| nodemap_error(py, e))
+}
+
+/// same as `get_rev()` but raises a bare `error.RevlogError` if node
+/// is not found.
+///
+/// No need to repeat `node` in the exception, `mercurial/revlog.py`
+/// will catch and rewrap with it
+def rev(, node: PyBytes) -> PyResult {
+self.get_rev(py, node)?.ok_or_else(|| revlog_error(py))
+}
+
+/// return True if the node exist in the index
+def has_node(, node: PyBytes) -> PyResult {
+self.get_rev(py, node).map(|opt| opt.is_some())
+}
+
+/// find length of shortest hex nodeid of a binary ID
+def shortest(, node: PyBytes) -> PyResult {
+let opt = self.get_nodetree(py)?.borrow();
+let nt = opt.as_ref().unwrap();
+let idx = &*self.cindex(py).borrow();
+match nt.unique_prefix_len_node(idx, _from_py_bytes(py, )?)
+{
+Ok(Some(l)) => Ok(l),
+Ok(None) => Err(revlog_error(py)),
+Err(e) => Err(nodemap_error(py, e)),
+}
+}
+
+def partialmatch(, node: PyObject) -> PyResult> {
+let opt = self.get_nodetree(py)?.borrow();
+let nt = opt.as_ref().unwrap();
+let idx = &*self.cindex(py).borrow();
+
+let node_as_string = if cfg!(feature = "python3-sys") {
+node.cast_as::(py)?.to_string(py)?.to_string()
+}
+else {
+let node = node.extract::(py)?;
+String::from_utf8_lossy(node.data(py)).to_string()
+};
+
+nt.find_hex(idx, _as_string)
+// TODO make an inner API returning the node directly
+.map(|opt| opt.map(
+|rev| PyBytes::new(py, idx.node(rev).unwrap().as_bytes(
+.map_err(|e| nodemap_error(py, e))
+
+}
+
+/// append an index entry
+def append(, tup: PyTuple) -> PyResult {
+if tup.len(py) < 8 {
+// this is better than the panic promised by tup.get_item()
+return Err(
+PyErr::new::(py, "tuple index out of range"))
+}
+let node_bytes = tup.get_item(py, 7).extract(py)?;
+let node = node_from_py_object(py, _bytes)?;
+
+let mut idx = self.cindex(py).borrow_mut();
+let rev = idx.len() as Revision;
+
+idx.append(py, tup)?;
+self.get_nodetree(py)?.borrow_mut().as_mut().unwrap()
+.insert(&*idx, , rev)
+.map_err(|e| nodemap_error(py, e))?;
+Ok(py.None())
+}
+
+def __delitem__(, key: PyObject) -> PyResult<()> {
+// __delitem__ is both for `del idx[r]` and `del idx[r1:r2]`
+

D8152: revlog: using two new functions in C capsule from Rust code

2020-03-11 Thread gracinet (Georges Racinet)
Closed by commit rHG166349510398: revlog: using two new functions in C capsule 
from Rust code (authored by gracinet).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8152?vs=20678=20690

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8152/new/

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

AFFECTED FILES
  mercurial/cext/revlog.c
  rust/hg-core/src/revlog/node.rs
  rust/hg-cpython/src/cindex.rs

CHANGE DETAILS

diff --git a/rust/hg-cpython/src/cindex.rs b/rust/hg-cpython/src/cindex.rs
--- a/rust/hg-cpython/src/cindex.rs
+++ b/rust/hg-cpython/src/cindex.rs
@@ -11,14 +11,21 @@
 //! but this will take some time to get there.
 
 use cpython::{exc::ImportError, PyClone, PyErr, PyObject, PyResult, Python};
+use hg::revlog::{Node, RevlogIndex};
 use hg::{Graph, GraphError, Revision, WORKING_DIRECTORY_REVISION};
 use libc::c_int;
 
-const REVLOG_CABI_VERSION: c_int = 1;
+const REVLOG_CABI_VERSION: c_int = 2;
 
 #[repr(C)]
 pub struct Revlog_CAPI {
 abi_version: c_int,
+index_length:
+unsafe extern "C" fn(index: *mut revlog_capi::RawPyObject) -> c_int,
+index_node: unsafe extern "C" fn(
+index: *mut revlog_capi::RawPyObject,
+rev: c_int,
+) -> *const Node,
 index_parents: unsafe extern "C" fn(
 index: *mut revlog_capi::RawPyObject,
 rev: c_int,
@@ -131,3 +138,30 @@
 }
 }
 }
+
+impl RevlogIndex for Index {
+/// Note C return type is Py_ssize_t (hence signed), but we shall
+/// force it to unsigned, because it's a length
+fn len() -> usize {
+unsafe { (self.capi.index_length)(self.index.as_ptr()) as usize }
+}
+
+fn node<'a>(&'a self, rev: Revision) -> Option<&'a Node> {
+let raw = unsafe {
+(self.capi.index_node)(self.index.as_ptr(), rev as c_int)
+};
+if raw.is_null() {
+None
+} else {
+// TODO it would be much better for the C layer to give us
+// a length, since the hash length will change in the near
+// future, but that's probably out of scope for the nodemap
+// patch series.
+//
+// The root of that unsafety relies in the signature of
+// `capi.index_node()` itself: returning a `Node` pointer
+// whereas it's a `char *` in the C counterpart.
+Some(unsafe { &*raw })
+}
+}
+}
diff --git a/rust/hg-core/src/revlog/node.rs b/rust/hg-core/src/revlog/node.rs
--- a/rust/hg-core/src/revlog/node.rs
+++ b/rust/hg-core/src/revlog/node.rs
@@ -44,6 +44,7 @@
 /// [`nybbles_len`]: #method.nybbles_len
 /// [`ExactLengthRequired`]: struct.NodeError#variant.ExactLengthRequired
 #[derive(Clone, Debug, PartialEq)]
+#[repr(transparent)]
 pub struct Node {
 data: NodeData,
 }
diff --git a/mercurial/cext/revlog.c b/mercurial/cext/revlog.c
--- a/mercurial/cext/revlog.c
+++ b/mercurial/cext/revlog.c
@@ -39,6 +39,8 @@
 
 typedef struct {
int abi_version;
+   Py_ssize_t (*index_length)(const indexObject *);
+   const char *(*index_node)(indexObject *, Py_ssize_t);
int (*index_parents)(PyObject *, int, int *);
 } Revlog_CAPI;
 
@@ -2877,7 +2879,9 @@
 static Revlog_CAPI CAPI = {
 /* increment the abi_version field upon each change in the Revlog_CAPI
struct or in the ABI of the listed functions */
-1,
+2,
+index_length,
+index_node,
 HgRevlogIndex_GetParents,
 };
 



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


D8156: rust-nodemap: add utils for propagating errors

2020-03-11 Thread gracinet (Georges Racinet)
Closed by commit rHG26dd35ac59b8: rust-nodemap: add utils for propagating 
errors (authored by gracinet).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8156?vs=20655=20694

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8156/new/

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

AFFECTED FILES
  rust/hg-cpython/src/revlog.rs

CHANGE DETAILS

diff --git a/rust/hg-cpython/src/revlog.rs b/rust/hg-cpython/src/revlog.rs
--- a/rust/hg-cpython/src/revlog.rs
+++ b/rust/hg-cpython/src/revlog.rs
@@ -1,16 +1,16 @@
 // revlog.rs
 //
-// Copyright 2019 Georges Racinet 
+// Copyright 2019-2020 Georges Racinet 
 //
 // This software may be used and distributed according to the terms of the
 // GNU General Public License version 2 or any later version.
 
 use crate::cindex;
 use cpython::{
-ObjectProtocol, PyClone, PyDict, PyModule, PyObject, PyResult, PyTuple,
-Python, PythonObject, ToPyObject,
+exc::ValueError, ObjectProtocol, PyClone, PyDict, PyErr, PyModule,
+PyObject, PyResult, PyTuple, Python, PythonObject, ToPyObject,
 };
-use hg::Revision;
+use hg::{nodemap::NodeMapError, NodeError, Revision};
 use std::cell::RefCell;
 
 /// Return a Struct implementing the Graph trait
@@ -224,6 +224,43 @@
 }
 }
 
+fn revlog_error(py: Python) -> PyErr {
+match py
+.import("mercurial.error")
+.and_then(|m| m.get(py, "RevlogError"))
+{
+Err(e) => e,
+Ok(cls) => PyErr::from_instance(py, cls),
+}
+}
+
+fn rev_not_in_index(py: Python, rev: Revision) -> PyErr {
+PyErr::new::(
+py,
+format!(
+"Inconsistency: Revision {} found in nodemap \
+ is not in revlog index",
+rev
+),
+)
+}
+
+/// Standard treatment of NodeMapError
+fn nodemap_error(py: Python, err: NodeMapError) -> PyErr {
+match err {
+NodeMapError::MultipleResults => revlog_error(py),
+NodeMapError::RevisionNotInIndex(r) => rev_not_in_index(py, r),
+NodeMapError::InvalidNodePrefix(s) => invalid_node_prefix(py, ),
+}
+}
+
+fn invalid_node_prefix(py: Python, ne: ) -> PyErr {
+PyErr::new::(
+py,
+format!("Invalid node or prefix: {:?}", ne),
+)
+}
+
 /// Create the module, with __package__ given from parent
 pub fn init_module(py: Python, package: ) -> PyResult {
 let dotted_name = !("{}.revlog", package);



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


D8155: rust-nodemap: add utils to create `Node`s from Python objects

2020-03-11 Thread gracinet (Georges Racinet)
Closed by commit rHGd738b7a18438: rust-nodemap: add utils to create `Node`s 
from Python objects (authored by gracinet).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8155?vs=20654=20693

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8155/new/

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

AFFECTED FILES
  rust/hg-cpython/src/utils.rs

CHANGE DETAILS

diff --git a/rust/hg-cpython/src/utils.rs b/rust/hg-cpython/src/utils.rs
--- a/rust/hg-cpython/src/utils.rs
+++ b/rust/hg-cpython/src/utils.rs
@@ -1,4 +1,7 @@
-use cpython::{PyDict, PyObject, PyResult, PyTuple, Python};
+use cpython::exc::ValueError;
+use cpython::{PyBytes, PyDict, PyErr, PyObject, PyResult, PyTuple, Python};
+use hg::revlog::Node;
+use std::convert::TryFrom;
 
 #[allow(unused)]
 pub fn print_python_trace(py: Python) -> PyResult {
@@ -11,3 +14,34 @@
 kwargs.set_item(py, "file", sys.get(py, "stderr")?)?;
 traceback.call(py, "print_stack", PyTuple::new(py, &[]), Some())
 }
+
+// Necessary evil for the time being, could maybe be moved to
+// a TryFrom in Node itself
+const NODE_BYTES_LENGTH: usize = 20;
+type NodeData = [u8; NODE_BYTES_LENGTH];
+
+/// Copy incoming Python bytes given as `PyObject` into `Node`,
+/// doing the necessary checks
+pub fn node_from_py_object<'a>(
+py: Python,
+bytes: &'a PyObject,
+) -> PyResult {
+let as_py_bytes: &'a PyBytes = bytes.extract(py)?;
+node_from_py_bytes(py, as_py_bytes)
+}
+
+/// Clone incoming Python bytes given as `PyBytes` as a `Node`,
+/// doing the necessary checks.
+pub fn node_from_py_bytes<'a>(
+py: Python,
+bytes: &'a PyBytes,
+) -> PyResult {
+::try_from(bytes.data(py))
+.map_err(|_| {
+PyErr::new::(
+py,
+format!("{}-byte hash required", NODE_BYTES_LENGTH),
+)
+})
+.map(|n| n.into())
+}



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


D8174: nodemap: refresh the persistent data on nodemap creation

2020-03-11 Thread marmoute (Pierre-Yves David)
Closed by commit rHG87b327de772c: nodemap: refresh the persistent data on 
nodemap creation (authored by marmoute).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8174?vs=20677=20689

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8174/new/

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

AFFECTED FILES
  mercurial/revlog.py

CHANGE DETAILS

diff --git a/mercurial/revlog.py b/mercurial/revlog.py
--- a/mercurial/revlog.py
+++ b/mercurial/revlog.py
@@ -760,7 +760,20 @@
 self._chainbasecache.clear()
 self._chunkcache = (0, b'')
 self._pcache = {}
+self._nodemap_docket = None
 self.index.clearcaches()
+# The python code is the one responsible for validating the docket, we
+# end up having to refresh it here.
+use_nodemap = (
+not self._inline
+and self.nodemap_file is not None
+and util.safehasattr(self.index, 'update_nodemap_data')
+)
+if use_nodemap:
+nodemap_data = nodemaputil.persisted_data(self)
+if nodemap_data is not None:
+self._nodemap_docket = nodemap_data[0]
+self.index.update_nodemap_data(*nodemap_data)
 
 def rev(self, node):
 try:



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


D8154: rust-index: add `append` method to cindex/Index

2020-03-11 Thread gracinet (Georges Racinet)
Closed by commit rHGcefd130c98be: rust-index: add `append` method to 
cindex/Index (authored by gracinet).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8154?vs=20653=20692

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8154/new/

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

AFFECTED FILES
  rust/hg-cpython/src/cindex.rs

CHANGE DETAILS

diff --git a/rust/hg-cpython/src/cindex.rs b/rust/hg-cpython/src/cindex.rs
--- a/rust/hg-cpython/src/cindex.rs
+++ b/rust/hg-cpython/src/cindex.rs
@@ -10,7 +10,10 @@
 //! Ideally, we should use an Index entirely implemented in Rust,
 //! but this will take some time to get there.
 
-use cpython::{exc::ImportError, PyClone, PyErr, PyObject, PyResult, Python};
+use cpython::{
+exc::ImportError, ObjectProtocol, PyClone, PyErr, PyObject, PyResult,
+PyTuple, Python, PythonObject,
+};
 use hg::revlog::{Node, RevlogIndex};
 use hg::{Graph, GraphError, Revision, WORKING_DIRECTORY_REVISION};
 use libc::c_int;
@@ -97,6 +100,15 @@
 pub fn inner() ->  {
 
 }
+
+pub fn append( self, py: Python, tup: PyTuple) -> PyResult {
+self.index.call_method(
+py,
+"append",
+PyTuple::new(py, &[tup.into_object()]),
+None,
+)
+}
 }
 
 impl Clone for Index {



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


D8153: rust-index: moved constructor in separate impl block

2020-03-11 Thread gracinet (Georges Racinet)
Closed by commit rHG887d0f921b34: rust-index: moved constructor in separate 
impl block (authored by gracinet).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs 
Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8153?vs=20652=20691

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8153/new/

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

AFFECTED FILES
  rust/hg-cpython/src/revlog.rs

CHANGE DETAILS

diff --git a/rust/hg-cpython/src/revlog.rs b/rust/hg-cpython/src/revlog.rs
--- a/rust/hg-cpython/src/revlog.rs
+++ b/rust/hg-cpython/src/revlog.rs
@@ -28,8 +28,7 @@
 data cindex: RefCell;
 
 def __new__(_cls, cindex: PyObject) -> PyResult {
-Self::create_instance(py, RefCell::new(
-cindex::Index::new(py, cindex)?))
+Self::new(py, cindex)
 }
 
 /// Compatibility layer used for Python consumers needing access to the C 
index
@@ -199,6 +198,13 @@
 });
 
 impl MixedIndex {
+fn new(py: Python, cindex: PyObject) -> PyResult {
+Self::create_instance(
+py,
+RefCell::new(cindex::Index::new(py, cindex)?),
+)
+}
+
 /// forward a method call to the underlying C index
 fn call_cindex(
 ,



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


D8172: notify: optional mail threading based on obsmarker

2020-03-11 Thread durin42 (Augie Fackler)
durin42 added a comment.
durin42 added subscribers: marmoute, durin42.


  @marmoute

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8172/new/

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

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


D8189: testlib: add a small scrip to help process to synchronise using file

2020-03-11 Thread durin42 (Augie Fackler)
durin42 added a comment.


  In D8189#123280 , @marmoute 
wrote:
  
  > By using explicit wait on signal (through the fs) that each process reached 
the appropriate file. We avoid flackyness. There are already multiple use of 
this approach in the test suite, that does not suffer from flackyness (unlike 
the wheelbarrow of flaky test relying on sleep for sync).
  
  You avoid flakyness iff the test manages to finish this step in under 20 
seconds (in the next change, as an example). Which is to say, this is still a 
flake waiting to happen, you've just made it less likely. I think it might be 
better to poll more often in the script and not even take a timeout: sleep 
forever waiting for the condition, and if it never comes let the test timeout 
at the runner level. Thoughts?
  
  I'm also not happy about the 1-second floor this puts on the step. Doesn't 
sleep(1) support sub-second sleeps on all platforms at this point?

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8189/new/

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

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


D8187: nodemap: make sure hooks have access to an up-to-date version

2020-03-11 Thread durin42 (Augie Fackler)
durin42 added a comment.


  In D8187#123306 , @marmoute 
wrote:
  
  > In D8187#123258 , @durin42 
wrote:
  >
  >> No longer applies on top of @.
  >
  > I don't understand this feedback. There are about 15 other changesets 
before it in this stack, so this is not meant to be directly applied on the 
head of default.
  
  I mentioned this in IRC, but I'll put it here for completeness: the parent 
pointers in this series are borked, and yadda was showing them /extremely/ out 
of order, to the point that this was about the 5th change in the series. I 
think I've managed to piece together a correct order, but if it doesn't apply 
I'll drop the whole stack until the parent pointers are contiguous again.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8187/new/

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

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


mercurial@44475: 5 new changesets (5 on stable)

2020-03-11 Thread Mercurial Commits
5 new changesets (5 on stable) in mercurial:

https://www.mercurial-scm.org/repo/hg/rev/fb7da4759a18
changeset:   44471:fb7da4759a18
branch:  stable
parent:  44451:9803b374389a
user:Pierre-Yves David 
date:Tue Mar 10 16:47:02 2020 +0100
summary: run-tests: fix conditional when tests are run outside of `tests`

https://www.mercurial-scm.org/repo/hg/rev/b7760c2d33de
changeset:   44472:b7760c2d33de
branch:  stable
user:Pierre-Yves David 
date:Tue Mar 10 16:49:38 2020 +0100
summary: heptapod-ci: run the test from outside the test directory

https://www.mercurial-scm.org/repo/hg/rev/6c36a521572e
changeset:   44473:6c36a521572e
branch:  stable
user:Pierre-Yves David 
date:Tue Mar 10 18:57:49 2020 +0100
summary: gzip: rename the argument to `mtime` to match upstream python

https://www.mercurial-scm.org/repo/hg/rev/a23b859ad17d
changeset:   44474:a23b859ad17d
branch:  stable
user:Pierre-Yves David 
date:Tue Mar 10 18:53:19 2020 +0100
summary: gzip: indent the custom Gzip code

https://www.mercurial-scm.org/repo/hg/rev/b7ca03dff14c
changeset:   44475:b7ca03dff14c
branch:  stable
tag: tip
user:Pierre-Yves David 
date:Tue Mar 10 18:54:44 2020 +0100
summary: gzip: use the stdlib version with python 3 (issue6284)

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


Re: [PATCH] tests: check availability of pyflakes by trying to import pyflakes module

2020-03-11 Thread Yuya Nishihara
On Wed, 11 Mar 2020 05:41:11 +0100, Manuel Jacob wrote:
> # HG changeset patch
> # User Manuel Jacob 
> # Date 1583901662 -3600
> #  Wed Mar 11 05:41:02 2020 +0100
> # Node ID 14cffca0d2f0b0818ac98eefc432ba22b3d6e364
> # Parent  a08bbdf839ae08ff69c6f99a289ee85b3a012f03
> tests: check availability of pyflakes by trying to import pyflakes module

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