D5412: test: fix test-http-bad-server with current python 2.7

2018-12-11 Thread jcristau (Julien Cristau)
jcristau created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  https://github.com/python/cpython/pull/2825 changed the exception
  message for empty http status line.

REPOSITORY
  rHG Mercurial

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

AFFECTED FILES
  tests/test-http-bad-server.t

CHANGE DETAILS

diff --git a/tests/test-http-bad-server.t b/tests/test-http-bad-server.t
--- a/tests/test-http-bad-server.t
+++ b/tests/test-http-bad-server.t
@@ -69,7 +69,7 @@
   $ cat hg.pid > $DAEMON_PIDS
 
   $ hg clone http://localhost:$HGPORT/ clone
-  abort: error: bad HTTP status line: ''
+  abort: error: bad HTTP status line: * (glob)
   [255]
 
   $ killdaemons.py $DAEMON_PIDS
@@ -85,7 +85,7 @@
   $ hg serve --config badserver.closeafterrecvbytes=40 -p $HGPORT -d 
--pid-file=hg.pid -E error.log
   $ cat hg.pid > $DAEMON_PIDS
   $ hg clone http://localhost:$HGPORT/ clone
-  abort: error: bad HTTP status line: ''
+  abort: error: bad HTTP status line: * (glob)
   [255]
 
   $ killdaemons.py $DAEMON_PIDS
@@ -102,7 +102,7 @@
   $ hg serve --config badserver.closeafterrecvbytes=210,223 -p $HGPORT -d 
--pid-file=hg.pid -E error.log
   $ cat hg.pid > $DAEMON_PIDS
   $ hg clone http://localhost:$HGPORT/ clone
-  abort: error: bad HTTP status line: ''
+  abort: error: bad HTTP status line: * (glob)
   [255]
 
   $ killdaemons.py $DAEMON_PIDS
@@ -141,7 +141,7 @@
   $ cat hg.pid > $DAEMON_PIDS
   $ hg clone http://localhost:$HGPORT/ clone
   requesting all changes
-  abort: error: bad HTTP status line: ''
+  abort: error: bad HTTP status line: * (glob)
   [255]
 
   $ killdaemons.py $DAEMON_PIDS
@@ -200,7 +200,7 @@
   $ cat hg.pid > $DAEMON_PIDS
 
   $ hg clone http://localhost:$HGPORT/ clone
-  abort: error: bad HTTP status line: ''
+  abort: error: bad HTTP status line: * (glob)
   [255]
 
   $ killdaemons.py $DAEMON_PIDS



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


Re: [PATCH 5 of 5] py3: quote several instances of $PYTHON for Windows

2018-12-11 Thread Matt Harbison

On Mon, 10 Dec 2018 06:49:11 -0500, Yuya Nishihara  wrote:


On Sun, 09 Dec 2018 22:44:37 -0500, Matt Harbison wrote:

# HG changeset patch
# User Matt Harbison 
# Date 1544408614 18000
#  Sun Dec 09 21:23:34 2018 -0500
# Node ID 4b007df3bff23f32439e299d13ce1a808b857c4d
# Parent  e5b7d60068537baa1ffeeca4e1a81f7498d0d48e
py3: quote several instances of $PYTHON for Windows


Queued, thanks.


Any idea how to handle test-hghave.t?  Here are 3 failed attempts:

$ hg diff
diff -r 008f3491dc53 tests/test-hghave.t
--- a/tests/test-hghave.t   Mon Dec 10 20:01:07 2018 +
+++ b/tests/test-hghave.t   Tue Dec 11 23:12:11 2018 -0500
@@ -20,12 +20,16 @@
   >   $ echo foo
   >   foo
   > EOF
-  $ ( \
-  > testrepohgenv; \
-  > "$PYTHON" $TESTDIR/run-tests.py -j 1 \
-  >$HGTEST_RUN_TESTS_PURE test-hghaveaddon.t \
-  > )
-  running 1 tests using 1 parallel processes
+
+  $ cat > addontest.sh < #!/bin/sh
+  >
+  > . "$TESTDIR/helpers-testrepo.sh"
+  > testrepohgenv;
+  > '"$PYTHON"' "$TESTDIR/run-tests.py" -j 1 \
+  >$HGTEST_RUN_TESTS_PURE test-hghaveaddon.t
+  > EOF
+  $ sh addontest.sh
   .
   # Ran 1 tests, 0 skipped, 0 failed.

$  py -3 run-tests.py --local test-hghave.t
running 1 tests using 1 parallel processes

--- c:/Users/Matt/hg/tests/test-hghave.t
+++ c:/Users/Matt/hg/tests/test-hghave.t.err
@@ -30,8 +30,8 @@
   >$HGTEST_RUN_TESTS_PURE test-hghaveaddon.t
   > EOF
   $ sh addontest.sh
-  .
-  # Ran 1 tests, 0 skipped, 0 failed.
+  addontest.sh: line 5: "C:/Program Files/Python37/python.exe": $ENOENT$
+  [127]

 (invocation via command line)


ERROR: test-hghave.t output changed
!
Failed test-hghave.t: output changed
# Ran 1 tests, 0 skipped, 1 failed.
python hash seed: 3453714405


==

$ hg diff
diff -r 008f3491dc53 tests/test-hghave.t
--- a/tests/test-hghave.t   Mon Dec 10 20:01:07 2018 +
+++ b/tests/test-hghave.t   Tue Dec 11 23:13:22 2018 -0500
@@ -20,12 +20,16 @@
   >   $ echo foo
   >   foo
   > EOF
-  $ ( \
-  > testrepohgenv; \
-  > "$PYTHON" $TESTDIR/run-tests.py -j 1 \
-  >$HGTEST_RUN_TESTS_PURE test-hghaveaddon.t \
-  > )
-  running 1 tests using 1 parallel processes
+
+  $ cat > addontest.sh < #!/bin/sh
+  >
+  > . "$TESTDIR/helpers-testrepo.sh"
+  > testrepohgenv;
+  > "$PYTHON" "$TESTDIR/run-tests.py" -j 1 \
+  >$HGTEST_RUN_TESTS_PURE test-hghaveaddon.t
+  > EOF
+  $ sh addontest.sh
   .
   # Ran 1 tests, 0 skipped, 0 failed.

$  py -3 run-tests.py --local test-hghave.t
running 1 tests using 1 parallel processes

--- c:/Users/Matt/hg/tests/test-hghave.t
+++ c:/Users/Matt/hg/tests/test-hghave.t.err
@@ -30,8 +30,9 @@
   >$HGTEST_RUN_TESTS_PURE test-hghaveaddon.t
   > EOF
   $ sh addontest.sh
-  .
-  # Ran 1 tests, 0 skipped, 0 failed.
+  'c:\\Program' is not recognized as an internal or external command,\r  
(esc)

+  operable program or batch file.\r (esc)
+  [1]

 (invocation via command line)


ERROR: test-hghave.t output changed
!
Failed test-hghave.t: output changed
# Ran 1 tests, 0 skipped, 1 failed.
python hash seed: 300496195

===

$ hg diff
diff -r 008f3491dc53 tests/test-hghave.t
--- a/tests/test-hghave.t   Mon Dec 10 20:01:07 2018 +
+++ b/tests/test-hghave.t   Tue Dec 11 23:14:19 2018 -0500
@@ -20,12 +20,16 @@
   >   $ echo foo
   >   foo
   > EOF
-  $ ( \
-  > testrepohgenv; \
-  > "$PYTHON" $TESTDIR/run-tests.py -j 1 \
-  >$HGTEST_RUN_TESTS_PURE test-hghaveaddon.t \
-  > )
-  running 1 tests using 1 parallel processes
+
+  $ cat > addontest.sh < #!/bin/sh
+  >
+  > . "$TESTDIR/helpers-testrepo.sh"
+  > testrepohgenv;
+  > \"$PYTHON\" "$TESTDIR/run-tests.py" -j 1 \
+  >$HGTEST_RUN_TESTS_PURE test-hghaveaddon.t
+  > EOF
+  $ sh addontest.sh
   .
   # Ran 1 tests, 0 skipped, 0 failed.

$  py -3 run-tests.py --local test-hghave.t
running 1 tests using 1 parallel processes

--- c:/Users/Matt/hg/tests/test-hghave.t
+++ c:/Users/Matt/hg/tests/test-hghave.t.err
@@ -30,8 +30,8 @@
   >$HGTEST_RUN_TESTS_PURE test-hghaveaddon.t
   > EOF
   $ sh addontest.sh
-  .
-  # Ran 1 tests, 0 skipped, 0 failed.
+  addontest.sh: line 5: "C:/Program: $ENOENT$
+  [127]

 (invocation via command line)


ERROR: test-hghave.t output changed
!
Failed test-hghave.t: output changed
# Ran 1 tests, 0 skipped, 1 failed.
python hash seed: 2437087002
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH] win32: close the handles associated with a spawned child process

2018-12-11 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1544583474 18000
#  Tue Dec 11 21:57:54 2018 -0500
# Node ID ec40f2ca8ac974ef657d4d52ac78019e75444911
# Parent  76d8b20139a3b8b5835c7262216b97275845b582
win32: close the handles associated with a spawned child process

Probably not a big deal because at this point, the call is only used when
spawning a daemonized server.  In that case, the parent process goes away first,
so it won't prevent the child from being cleaned up.

diff --git a/mercurial/win32.py b/mercurial/win32.py
--- a/mercurial/win32.py
+++ b/mercurial/win32.py
@@ -588,6 +588,9 @@ def spawndetached(args):
 if not res:
 raise ctypes.WinError()
 
+_kernel32.CloseHandle(pi.hProcess)
+_kernel32.CloseHandle(pi.hThread)
+
 return pi.dwProcessId
 
 def unlink(f):
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D5411: sqlitestore: create new connections on new PIDs

2018-12-11 Thread indygreg (Gregory Szorc)
indygreg abandoned this revision.
indygreg added a comment.


  It turns out we were hitting a bug in an ancient version of SQLite. Upgrading 
from 3.11 to 3.22 fixed it. I don't think this patch is needed.

REPOSITORY
  rHG Mercurial

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

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


D5411: sqlitestore: create new connections on new PIDs

2018-12-11 Thread indygreg (Gregory Szorc)
indygreg planned changes to this revision.
indygreg added a comment.


  Hold off on reviewing this. I'm still debugging some issues at Mozilla and 
want to be sure this patch is correct...

REPOSITORY
  rHG Mercurial

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

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


D5411: sqlitestore: create new connections on new PIDs

2018-12-11 Thread indygreg (Gregory Szorc)
indygreg created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  If the Mercurial process fork()s, the Python thread ID remains
  unchanged. The previous code for returning a SQLite connection would
  recycle the existing connection among all children.
  
  Mercurial can fork() when performing working directory updates.
  For reasons I don't fully understand, the recycling of even a
  read-only SQLite connection was resulting in Python raising a
  "DatabaseError: database disk image is malformed" exception. This
  message comes from the bowels of SQLite. I suspect there is some
  internal client state in the SQLite database somewhere and having
  multiple clients race to update it results in badness. Who knows.
  
  This commit teaches the "get a SQLite connection" logic to also
  verify the PID matches before returning an existing connection.

REPOSITORY
  rHG Mercurial

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

AFFECTED FILES
  hgext/sqlitestore.py

CHANGE DETAILS

diff --git a/hgext/sqlitestore.py b/hgext/sqlitestore.py
--- a/hgext/sqlitestore.py
+++ b/hgext/sqlitestore.py
@@ -76,6 +76,7 @@
 )
 from mercurial.utils import (
 interfaceutil,
+procutil,
 storageutil,
 )
 
@@ -1005,17 +1006,18 @@
 
 @property
 def _dbconn(self):
-# SQLite connections can only be used on the thread that created
-# them. In most cases, this "just works." However, hgweb uses
-# multiple threads.
-tid = threading.current_thread().ident
+# SQLite connections can only be used on the OS and Python thread that
+# created them. In most cases, this "just works." However, hgweb uses
+# multiple Python threads. And Mercurial may fork. So we need to check
+# global state before returning an existing connection.
+key = (procutil.getpid(), threading.current_thread().ident)
 
 if self._db:
-if self._db[0] == tid:
+if self._db[0] == key:
 return self._db[1]
 
 db = makedb(self.svfs.join('db.sqlite'))
-self._db = (tid, db)
+self._db = (key, db)
 
 return db
 



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


[PATCH 2 of 2 evolve-ext] resolves 6028: return return (False, ".") instead of return (False, '')

2018-12-11 Thread James Reynolds
# HG changeset patch
# User James Reynolds 
# Date 1543952045 18000
#  Tue Dec 04 14:34:05 2018 -0500
# Branch stable
# Node ID 9bf7096a013cbbef97064b47fef069e8ac87356c
# Parent  710f32053ba340564ca9909b4dc7bef1fc1946fb
# EXP-Topic issue6028
resolves 6028: return return (False, ".") instead of return (False, '')
 - repo[] no longer takes an empty string

diff -r 710f32053ba3 -r 9bf7096a013c hgext3rd/evolve/evolvecmd.py
--- a/hgext3rd/evolve/evolvecmd.py  Tue Dec 04 14:56:19 2018 -0500
+++ b/hgext3rd/evolve/evolvecmd.py  Tue Dec 04 14:34:05 2018 -0500
@@ -61,7 +61,7 @@
 bool: a boolean value indicating whether the instability was solved
 newnode: if bool is True, then the newnode of the resultant commit
  formed. newnode can be node, when resolution led to no new
- commit. If bool is False, this is ''.
+ commit. If bool is False, this is ".".
 """
 displayer = None
 if stacktmplt:
@@ -101,7 +101,7 @@
 bool: a boolean value indicating whether the instability was solved
 newnode: if bool is True, then the newnode of the resultant commit
  formed. newnode can be node, when resolution led to no new
- commit. If bool is False, this is ''.
+ commit. If bool is False, this is ".".
 """
 pctx = orig.p1()
 keepbranch = orig.p1().branch() != orig.branch()
@@ -125,7 +125,7 @@
 
 if not pctx.obsolete():
 ui.warn(_("cannot solve instability of %s, skipping\n") % orig)
-return (False, '')
+return (False, ".")
 obs = pctx
 newer = obsutil.successorssets(repo, obs.node())
 # search of a parent which is not killed
@@ -139,7 +139,7 @@
 msg = _("skipping %s: divergent rewriting. can't choose "
 "destination\n") % obs
 ui.write_err(msg)
-return (False, '')
+return (False, ".")
 targets = newer[0]
 assert targets
 if len(targets) > 1:
@@ -157,7 +157,7 @@
 "ambiguous destination: "
 "parent split across two branches\n")
 ui.write_err(msg)
-return (False, '')
+return (False, ".")
 target = repo[selectedrev]
 else:
 target = repo[heads.first()]
@@ -177,7 +177,7 @@
 todo = 'hg rebase -r %s -d %s\n' % (orig, target)
 if dryrun:
 repo.ui.write(todo)
-return (False, '')
+return (False, ".")
 else:
 repo.ui.note(todo)
 if progresscb:
@@ -201,7 +201,7 @@
 bool: a boolean value indicating whether the instability was solved
 newnode: if bool is True, then the newnode of the resultant commit
  formed. newnode can be node, when resolution led to no new
- commit. If bool is False, this is ''.
+ commit. If bool is False, this is ".".
 """
 repo = repo.unfiltered()
 bumped = repo[bumped.rev()]
@@ -209,14 +209,14 @@
 if len(bumped.parents()) > 1:
 msg = _('skipping %s : we do not handle merge yet\n') % bumped
 ui.write_err(msg)
-return (False, '')
+return (False, ".")
 prec = repo.set('last(allprecursors(%d) and public())', 
bumped.rev()).next()
 # For now we deny target merge
 if len(prec.parents()) > 1:
 msg = _('skipping: %s: public version is a merge, '
 'this is not handled yet\n') % prec
 ui.write_err(msg)
-return (False, '')
+return (False, ".")
 
 if not ui.quiet or confirm:
 repo.ui.write(_('recreate:'), label='evolve.operation')
@@ -232,7 +232,7 @@
 repo.ui.write(('hg revert --all --rev %s;\n' % bumped))
 repo.ui.write(('hg commit --msg "%s update to %s"\n' %
(TROUBLES['PHASEDIVERGENT'], bumped)))
-return (False, '')
+return (False, ".")
 if progresscb:
 progresscb()
 tmpctx = bumped
@@ -343,7 +343,7 @@
 bool: a boolean value indicating whether the instability was solved
 newnode: if bool is True, then the newnode of the resultant commit
  formed. newnode can be node, when resolution led to no new
- commit. If bool is False, this is ''.
+ commit. If bool is False, this is ".".
 """
 repo = repo.unfiltered()
 divergent = repo[divergent.rev()]
@@ -376,7 +376,7 @@
 "| You should contact your local evolution Guru for help.\n"
 ) % (divergent, TROUBLES['CONTENTDIVERGENT'], othersstr)
 ui.write_err(msg)
-return (False, '')
+return (False, ".")
 other = others[0]
 evolvestate['other-divergent'] = other.node()
 evolvestate['base'] = base.node()
@@ -390,7 +390,7 @@
  "| This probably means redoing the merge and using \n"
  "| `hg prune` to kill older version.\n")
 

[PATCH 1 of 2 evolve-ext] issue-6028: failing test

2018-12-11 Thread James Reynolds
# HG changeset patch
# User James Reynolds 
# Date 1543953379 18000
#  Tue Dec 04 14:56:19 2018 -0500
# Branch stable
# Node ID 710f32053ba340564ca9909b4dc7bef1fc1946fb
# Parent  48da02d7f8ebd7d274ace7bb6c74a856c4a62882
# EXP-Topic issue6028
issue-6028: failing test

diff -r 48da02d7f8eb -r 710f32053ba3 tests/test-issue-6028.t
--- /dev/null   Thu Jan 01 00:00:00 1970 +
+++ b/tests/test-issue-6028.t   Tue Dec 04 14:56:19 2018 -0500
@@ -0,0 +1,123 @@
+This test file test the #6028 issue
+
+evolve fails with mercurial.error.ProgrammingError: unsupported changeid '' of 
type 
+
+https://bz.mercurial-scm.org/show_bug.cgi?id=6028
+
+Global setup
+
+
+  $ . $TESTDIR/testlib/common.sh
+  $ cat >> $HGRCPATH < [ui]
+  > interactive = true
+  > [phases]
+  > publish=False
+  > [extensions]
+  > evolve =
+  > topic =
+  > EOF
+
+Test
+
+
+  $ hg init $TESTTMP/issue-6028
+  $ cd $TESTTMP/issue-6028
+
+create initial commit
+  $ echo "0" > 0
+  $ hg ci -Am 0
+  adding 0
+
+
+  $ hg up default
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg topics a
+  marked working directory as topic: a
+  $ echo "a" > a
+  $ hg ci -Am a
+  adding a
+  active topic 'a' grew its first changeset
+  (see 'hg help topics' for more information)
+
+
+  $ hg up default
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ hg topics b
+  marked working directory as topic: b
+  $ echo "b" > b
+  $ hg ci -Am b
+  adding b
+  active topic 'b' grew its first changeset
+  (see 'hg help topics' for more information)
+
+  $ hg up default
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ hg branch integration
+  marked working directory as branch integration
+
+  $ hg merge a
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ hg ci -m "merged a"
+
+  $ hg merge b
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ hg ci -m "merged b"
+
+  $ hg up a
+  switching to topic a
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ echo "a bad commit" >> a_bad_commit
+  $ hg add a_bad_commit
+  $ hg ci -m "a bad commit"
+  $ hg up integration
+  1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ hg merge a
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ hg ci -m "merged a bad commit"
+
+  $ hg up a
+  switching to topic a
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ echo "aa" >> a
+  $ hg ci -m "aa"
+  $ hg up integration
+  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg merge a
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ hg ci -m "merged aa"
+
+  $ hg up b
+  switching to topic b
+  0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+  $ echo "bb" >> b
+  $ hg ci -m "bb"
+  $ hg up integration
+  3 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg merge b
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ hg ci -m "merged bb"
+
+create instability by pruning two changesets, one in a topic, one in a merge
+  $ hg prune -r 5:6
+  2 changesets pruned
+  3 new orphan changesets
+
+  $ hg up 4
+  2 files updated, 0 files merged, 1 files removed, 0 files unresolved
+
+start the evolve
+  $ hg evolve
+  move:[8] merged aa
+  atop:[4] merged b
+  working directory is now at c920dd828523
+
+evolve creates an obsolete changeset above as 11
+  $ hg evolve -r .
+  cannot solve instability of c920dd828523, skipping
+  cannot solve instability of c920dd828523, skipping
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 2 evolve-ext] resolves 6028: return return (False, ".") instead of return (False, '')

2018-12-11 Thread James Reynolds
# HG changeset patch
# User James Reynolds 
# Date 1543952045 18000
#  Tue Dec 04 14:34:05 2018 -0500
# Branch stable
# Node ID 4bbca2202a72adf5877e5d5a3d8850424a01cb6f
# Parent  710f32053ba340564ca9909b4dc7bef1fc1946fb
# EXP-Topic issue6028
resolves 6028: return return (False, ".") instead of return (False, '')
 - repo[] no longer takes an empty string

diff -r 710f32053ba3 -r 4bbca2202a72 hgext3rd/evolve/evolvecmd.py
--- a/hgext3rd/evolve/evolvecmd.py  Tue Dec 04 14:56:19 2018 -0500
+++ b/hgext3rd/evolve/evolvecmd.py  Tue Dec 04 14:34:05 2018 -0500
@@ -61,7 +61,7 @@
 bool: a boolean value indicating whether the instability was solved
 newnode: if bool is True, then the newnode of the resultant commit
  formed. newnode can be node, when resolution led to no new
- commit. If bool is False, this is ''.
+ commit. If bool is False, this is ".".
 """
 displayer = None
 if stacktmplt:
@@ -101,7 +101,7 @@
 bool: a boolean value indicating whether the instability was solved
 newnode: if bool is True, then the newnode of the resultant commit
  formed. newnode can be node, when resolution led to no new
- commit. If bool is False, this is ''.
+ commit. If bool is False, this is ".".
 """
 pctx = orig.p1()
 keepbranch = orig.p1().branch() != orig.branch()
@@ -125,7 +125,7 @@
 
 if not pctx.obsolete():
 ui.warn(_("cannot solve instability of %s, skipping\n") % orig)
-return (False, '')
+return return (False, ".")
 obs = pctx
 newer = obsutil.successorssets(repo, obs.node())
 # search of a parent which is not killed
@@ -139,7 +139,7 @@
 msg = _("skipping %s: divergent rewriting. can't choose "
 "destination\n") % obs
 ui.write_err(msg)
-return (False, '')
+return return (False, ".")
 targets = newer[0]
 assert targets
 if len(targets) > 1:
@@ -157,7 +157,7 @@
 "ambiguous destination: "
 "parent split across two branches\n")
 ui.write_err(msg)
-return (False, '')
+return return (False, ".")
 target = repo[selectedrev]
 else:
 target = repo[heads.first()]
@@ -177,7 +177,7 @@
 todo = 'hg rebase -r %s -d %s\n' % (orig, target)
 if dryrun:
 repo.ui.write(todo)
-return (False, '')
+return return (False, ".")
 else:
 repo.ui.note(todo)
 if progresscb:
@@ -201,7 +201,7 @@
 bool: a boolean value indicating whether the instability was solved
 newnode: if bool is True, then the newnode of the resultant commit
  formed. newnode can be node, when resolution led to no new
- commit. If bool is False, this is ''.
+ commit. If bool is False, this is ".".
 """
 repo = repo.unfiltered()
 bumped = repo[bumped.rev()]
@@ -209,14 +209,14 @@
 if len(bumped.parents()) > 1:
 msg = _('skipping %s : we do not handle merge yet\n') % bumped
 ui.write_err(msg)
-return (False, '')
+return return (False, ".")
 prec = repo.set('last(allprecursors(%d) and public())', 
bumped.rev()).next()
 # For now we deny target merge
 if len(prec.parents()) > 1:
 msg = _('skipping: %s: public version is a merge, '
 'this is not handled yet\n') % prec
 ui.write_err(msg)
-return (False, '')
+return return (False, ".")
 
 if not ui.quiet or confirm:
 repo.ui.write(_('recreate:'), label='evolve.operation')
@@ -232,7 +232,7 @@
 repo.ui.write(('hg revert --all --rev %s;\n' % bumped))
 repo.ui.write(('hg commit --msg "%s update to %s"\n' %
(TROUBLES['PHASEDIVERGENT'], bumped)))
-return (False, '')
+return return (False, ".")
 if progresscb:
 progresscb()
 tmpctx = bumped
@@ -343,7 +343,7 @@
 bool: a boolean value indicating whether the instability was solved
 newnode: if bool is True, then the newnode of the resultant commit
  formed. newnode can be node, when resolution led to no new
- commit. If bool is False, this is ''.
+ commit. If bool is False, this is ".".
 """
 repo = repo.unfiltered()
 divergent = repo[divergent.rev()]
@@ -376,7 +376,7 @@
 "| You should contact your local evolution Guru for help.\n"
 ) % (divergent, TROUBLES['CONTENTDIVERGENT'], othersstr)
 ui.write_err(msg)
-return (False, '')
+return return (False, ".")
 other = others[0]
 evolvestate['other-divergent'] = other.node()
 evolvestate['base'] = base.node()
@@ -390,7 +390,7 @@
  "| This probably means redoing the merge and using \n"
  "| 

[PATCH 1 of 2 evolve-ext] issue-6028: failing test

2018-12-11 Thread James Reynolds
# HG changeset patch
# User James Reynolds 
# Date 1543953379 18000
#  Tue Dec 04 14:56:19 2018 -0500
# Branch stable
# Node ID 710f32053ba340564ca9909b4dc7bef1fc1946fb
# Parent  48da02d7f8ebd7d274ace7bb6c74a856c4a62882
# EXP-Topic issue6028
issue-6028: failing test

diff -r 48da02d7f8eb -r 710f32053ba3 tests/test-issue-6028.t
--- /dev/null   Thu Jan 01 00:00:00 1970 +
+++ b/tests/test-issue-6028.t   Tue Dec 04 14:56:19 2018 -0500
@@ -0,0 +1,123 @@
+This test file test the #6028 issue
+
+evolve fails with mercurial.error.ProgrammingError: unsupported changeid '' of 
type 
+
+https://bz.mercurial-scm.org/show_bug.cgi?id=6028
+
+Global setup
+
+
+  $ . $TESTDIR/testlib/common.sh
+  $ cat >> $HGRCPATH < [ui]
+  > interactive = true
+  > [phases]
+  > publish=False
+  > [extensions]
+  > evolve =
+  > topic =
+  > EOF
+
+Test
+
+
+  $ hg init $TESTTMP/issue-6028
+  $ cd $TESTTMP/issue-6028
+
+create initial commit
+  $ echo "0" > 0
+  $ hg ci -Am 0
+  adding 0
+
+
+  $ hg up default
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg topics a
+  marked working directory as topic: a
+  $ echo "a" > a
+  $ hg ci -Am a
+  adding a
+  active topic 'a' grew its first changeset
+  (see 'hg help topics' for more information)
+
+
+  $ hg up default
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ hg topics b
+  marked working directory as topic: b
+  $ echo "b" > b
+  $ hg ci -Am b
+  adding b
+  active topic 'b' grew its first changeset
+  (see 'hg help topics' for more information)
+
+  $ hg up default
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ hg branch integration
+  marked working directory as branch integration
+
+  $ hg merge a
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ hg ci -m "merged a"
+
+  $ hg merge b
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ hg ci -m "merged b"
+
+  $ hg up a
+  switching to topic a
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ echo "a bad commit" >> a_bad_commit
+  $ hg add a_bad_commit
+  $ hg ci -m "a bad commit"
+  $ hg up integration
+  1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ hg merge a
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ hg ci -m "merged a bad commit"
+
+  $ hg up a
+  switching to topic a
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ echo "aa" >> a
+  $ hg ci -m "aa"
+  $ hg up integration
+  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg merge a
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ hg ci -m "merged aa"
+
+  $ hg up b
+  switching to topic b
+  0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+  $ echo "bb" >> b
+  $ hg ci -m "bb"
+  $ hg up integration
+  3 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg merge b
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ hg ci -m "merged bb"
+
+create instability by pruning two changesets, one in a topic, one in a merge
+  $ hg prune -r 5:6
+  2 changesets pruned
+  3 new orphan changesets
+
+  $ hg up 4
+  2 files updated, 0 files merged, 1 files removed, 0 files unresolved
+
+start the evolve
+  $ hg evolve
+  move:[8] merged aa
+  atop:[4] merged b
+  working directory is now at c920dd828523
+
+evolve creates an obsolete changeset above as 11
+  $ hg evolve -r .
+  cannot solve instability of c920dd828523, skipping
+  cannot solve instability of c920dd828523, skipping
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 2 of 2 evolve-ext] resolves 6028: return return (False, None) instead of return (False, '')

2018-12-11 Thread Pulkit Goyal
On Tue, Dec 11, 2018 at 7:18 PM James Reynolds <
james.glenn.reyno...@gmail.com> wrote:

>
> On Wed, Dec 5, 2018 at 5:15 PM Martin von Zweigbergk <
> martinv...@google.com> wrote:
>
>>
>>
>> On Tue, Dec 4, 2018 at 1:19 PM James Reynolds <
>> james.glenn.reyno...@gmail.com> wrote:
>>
>>> # HG changeset patch
>>> # User James Reynolds 
>>> # Date 1543952045 18000
>>> #  Tue Dec 04 14:34:05 2018 -0500
>>> # Branch stable
>>> # Node ID 6ea3ff2517b9ebf12f0678f28c9942c45c5924ce
>>> # Parent  91aec886fc8701398182ab83adcdc04c86735c1d
>>> # EXP-Topic issue6028
>>> resolves 6028: return return (False, None) instead of return (False, '')
>>>
>>
>> repo[''] used to mean repo['.']. Is the right return value still (False,
>> None)?
>>
>
> Makes sense to me. I think Pulkit Goyal said he was going to take a look
> at this.
>

Sorry for missing to have a look before. I agree with @martinvonz
suggestion and the default return value should be '.'.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 2 of 2 evolve-ext] resolves 6028: return return (False, None) instead of return (False, '')

2018-12-11 Thread James Reynolds
On Wed, Dec 5, 2018 at 5:15 PM Martin von Zweigbergk 
wrote:

>
>
> On Tue, Dec 4, 2018 at 1:19 PM James Reynolds <
> james.glenn.reyno...@gmail.com> wrote:
>
>> # HG changeset patch
>> # User James Reynolds 
>> # Date 1543952045 18000
>> #  Tue Dec 04 14:34:05 2018 -0500
>> # Branch stable
>> # Node ID 6ea3ff2517b9ebf12f0678f28c9942c45c5924ce
>> # Parent  91aec886fc8701398182ab83adcdc04c86735c1d
>> # EXP-Topic issue6028
>> resolves 6028: return return (False, None) instead of return (False, '')
>>
>
> repo[''] used to mean repo['.']. Is the right return value still (False,
> None)?
>

Makes sense to me. I think Pulkit Goyal said he was going to take a look at
this.

>
>
>>  - repo[] no longer takes an emptry string
>
>
>> diff -r 91aec886fc87 -r 6ea3ff2517b9 hgext3rd/evolve/evolvecmd.py
>> --- a/hgext3rd/evolve/evolvecmd.py  Tue Dec 04 14:56:19 2018 -0500
>> +++ b/hgext3rd/evolve/evolvecmd.py  Tue Dec 04 14:34:05 2018 -0500
>> @@ -61,7 +61,7 @@
>>  bool: a boolean value indicating whether the instability was
>> solved
>>  newnode: if bool is True, then the newnode of the resultant
>> commit
>>   formed. newnode can be node, when resolution led to no
>> new
>> - commit. If bool is False, this is ''.
>> + commit. If bool is False, this is None.
>>  """
>>  displayer = None
>>  if stacktmplt:
>> @@ -101,7 +101,7 @@
>>  bool: a boolean value indicating whether the instability was
>> solved
>>  newnode: if bool is True, then the newnode of the resultant
>> commit
>>   formed. newnode can be node, when resolution led to no
>> new
>> - commit. If bool is False, this is ''.
>> + commit. If bool is False, this is None.
>>  """
>>  pctx = orig.p1()
>>  keepbranch = orig.p1().branch() != orig.branch()
>> @@ -125,7 +125,7 @@
>>
>>  if not pctx.obsolete():
>>  ui.warn(_("cannot solve instability of %s, skipping\n") % orig)
>> -return (False, '')
>> +return (False, None)
>>  obs = pctx
>>  newer = obsutil.successorssets(repo, obs.node())
>>  # search of a parent which is not killed
>> @@ -139,7 +139,7 @@
>>  msg = _("skipping %s: divergent rewriting. can't choose "
>>  "destination\n") % obs
>>  ui.write_err(msg)
>> -return (False, '')
>> +return (False, None)
>>  targets = newer[0]
>>  assert targets
>>  if len(targets) > 1:
>> @@ -157,7 +157,7 @@
>>  "ambiguous destination: "
>>  "parent split across two branches\n")
>>  ui.write_err(msg)
>> -return (False, '')
>> +return (False, None)
>>  target = repo[selectedrev]
>>  else:
>>  target = repo[heads.first()]
>> @@ -177,7 +177,7 @@
>>  todo = 'hg rebase -r %s -d %s\n' % (orig, target)
>>  if dryrun:
>>  repo.ui.write(todo)
>> -return (False, '')
>> +return (False, None)
>>  else:
>>  repo.ui.note(todo)
>>  if progresscb:
>> @@ -201,7 +201,7 @@
>>  bool: a boolean value indicating whether the instability was
>> solved
>>  newnode: if bool is True, then the newnode of the resultant
>> commit
>>   formed. newnode can be node, when resolution led to no
>> new
>> - commit. If bool is False, this is ''.
>> + commit. If bool is False, this is None.
>>  """
>>  repo = repo.unfiltered()
>>  bumped = repo[bumped.rev()]
>> @@ -209,14 +209,14 @@
>>  if len(bumped.parents()) > 1:
>>  msg = _('skipping %s : we do not handle merge yet\n') % bumped
>>  ui.write_err(msg)
>> -return (False, '')
>> +return (False, None)
>>  prec = repo.set('last(allprecursors(%d) and public())',
>> bumped.rev()).next()
>>  # For now we deny target merge
>>  if len(prec.parents()) > 1:
>>  msg = _('skipping: %s: public version is a merge, '
>>  'this is not handled yet\n') % prec
>>  ui.write_err(msg)
>> -return (False, '')
>> +return (False, None)
>>
>>  if not ui.quiet or confirm:
>>  repo.ui.write(_('recreate:'), label='evolve.operation')
>> @@ -232,7 +232,7 @@
>>  repo.ui.write(('hg revert --all --rev %s;\n' % bumped))
>>  repo.ui.write(('hg commit --msg "%s update to %s"\n' %
>> (TROUBLES['PHASEDIVERGENT'], bumped)))
>> -return (False, '')
>> +return (False, None)
>>  if progresscb:
>>  progresscb()
>>  tmpctx = bumped
>> @@ -343,7 +343,7 @@
>>  bool: a boolean value indicating whether the instability was
>> solved
>>  newnode: if bool is True, then the newnode of the resultant
>> commit
>>   formed. newnode can be node, when resolution led to no
>> new
>> - 

D5410: merge: allow to merge non-conflicting changes outside narrowspec

2018-12-11 Thread martinvonz (Martin von Zweigbergk)
martinvonz requested changes to this revision.
martinvonz added a comment.
This revision now requires changes to proceed.


  I'm pretty sure this doesn't actually perform the merge, it just drops the 
changes outside the narrowspec. On commit, we need to record that outside/ has 
the new nodeid that we got from the side we merged in. To do that, we need to 
remember what that nodeid is, from the time of `hg merge` to the time of `hg 
commit`. That probably means storing the nodeid in the dirstate (like git 
does), or maybe in the merge state.

REPOSITORY
  rHG Mercurial

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

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


[PATCH STABLE] worker: do not swallow exception occurred in main process

2018-12-11 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1544535247 -32400
#  Tue Dec 11 22:34:07 2018 +0900
# Branch stable
# Node ID da41e2e94cfdddce12778d460d53cc7867f69f10
# Parent  4265bfb53dd3c8961993a8af8a41691bcf03d6d7
worker: do not swallow exception occurred in main process

Before, SystemExit(255) would be most likely raised since the worker processes
were terminated by the main process and the status would be set to 255 in
response. We should instead re-raise the exception occurred first. It's pretty
hard to debug problems like the issue 6035 with no traceback.

diff --git a/mercurial/worker.py b/mercurial/worker.py
--- a/mercurial/worker.py
+++ b/mercurial/worker.py
@@ -213,11 +213,7 @@ def _posixworker(ui, func, staticargs, a
 waitforworkers()
 signal.signal(signal.SIGCHLD, oldchldhandler)
 selector.close()
-status = problem[0]
-if status:
-if status < 0:
-os.kill(os.getpid(), -status)
-sys.exit(status)
+return problem[0]
 try:
 openpipes = len(pipes)
 while openpipes > 0:
@@ -236,7 +232,11 @@ def _posixworker(ui, func, staticargs, a
 killworkers()
 cleanup()
 raise
-cleanup()
+status = cleanup()
+if status:
+if status < 0:
+os.kill(os.getpid(), -status)
+sys.exit(status)
 
 def _posixexitstatus(code):
 '''convert a posix exit status into the same form returned by
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH] rust: remove comment about error handling of AncestorsIterator

2018-12-11 Thread Pulkit Goyal
On Tue, Dec 11, 2018 at 4:27 PM Yuya Nishihara  wrote:

> # HG changeset patch
> # User Yuya Nishihara 
> # Date 1544534619 -32400
> #  Tue Dec 11 22:23:39 2018 +0900
> # Node ID 76d8b20139a3b8b5835c7262216b97275845b582
> # Parent  4e17679c336bc38709c32d9b8972f0e402e0057a
> rust: remove comment about error handling of AncestorsIterator
>
> To be align with 443eb4bc41af "rust: propagate error of index_get_parents()
> properly."
>
> Spotted by Georges Racinet.
>
Queued, many thanks!
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D5408: progress: [RFC] avoid ui.configbool() lookup when progress bar is active

2018-12-11 Thread yuja (Yuya Nishihara)
yuja added a comment.


  The idea sounds good to me. Going further, maybe we can get rid of the `ui`
  reference from the progbar. There's a reference cycle.
  
  >   DO NOT LAND. test-check-config.t COMPLAINS FOR SOME REASON.
  
  Probably missing `# developer config: progress.debug`. The checker isn't
  aware of `self` being `ui`.

REPOSITORY
  rHG Mercurial

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

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


Re: D5408: progress: [RFC] avoid ui.configbool() lookup when progress bar is active

2018-12-11 Thread Yuya Nishihara
The idea sounds good to me. Going further, maybe we can get rid of the `ui`
reference from the progbar. There's a reference cycle.

>   DO NOT LAND. test-check-config.t COMPLAINS FOR SOME REASON.

Probably missing `# developer config: progress.debug`. The checker isn't
aware of `self` being `ui`.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH] rust: remove comment about error handling of AncestorsIterator

2018-12-11 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1544534619 -32400
#  Tue Dec 11 22:23:39 2018 +0900
# Node ID 76d8b20139a3b8b5835c7262216b97275845b582
# Parent  4e17679c336bc38709c32d9b8972f0e402e0057a
rust: remove comment about error handling of AncestorsIterator

To be align with 443eb4bc41af "rust: propagate error of index_get_parents()
properly."

Spotted by Georges Racinet.

diff --git a/rust/hg-core/src/ancestors.rs b/rust/hg-core/src/ancestors.rs
--- a/rust/hg-core/src/ancestors.rs
+++ b/rust/hg-core/src/ancestors.rs
@@ -105,18 +105,6 @@ impl AncestorsIterator {
 ///   (case where p1 == rev-1), because it amounts to update the first element
 ///   of the heap without sifting, which Rust's BinaryHeap doesn't let us do.
 /// - we save a few pushes by comparing with `stoprev` before pushing
-///
-/// Error treatment:
-/// We swallow the possible GraphError of conditionally_push_parents() to
-/// respect the Iterator trait in a simple manner: never emitting parents
-/// for the returned revision. We finds this good enough for now, because:
-///
-/// - there's a good chance that invalid revisionss are fed from the start,
-///   and `new()` doesn't swallow the error result.
-/// - this is probably what the Python implementation produces anyway, due
-///   to filtering at each step, and Python code is currently the only
-///   concrete caller we target, so we shouldn't need a finer error treatment
-///   for the time being.
 impl Iterator for AncestorsIterator {
 type Item = Result;
 
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


mercurial@40925: 4 new changesets

2018-12-11 Thread Mercurial Commits
4 new changesets in mercurial:

https://www.mercurial-scm.org/repo/hg/rev/ca6372b7e566
changeset:   40922:ca6372b7e566
user:Gregory Szorc 
date:Mon Dec 10 17:26:12 2018 +
summary: tests: add tests for server-side linknode adjustment with 
wireprotov2

https://www.mercurial-scm.org/repo/hg/rev/3ed77780f4a6
changeset:   40923:3ed77780f4a6
user:Gregory Szorc 
date:Mon Dec 10 18:04:12 2018 +
summary: wireprotov2: send linknodes to emitfilerevisions()

https://www.mercurial-scm.org/repo/hg/rev/08cfa77d7288
changeset:   40924:08cfa77d7288
user:Gregory Szorc 
date:Mon Dec 10 18:55:08 2018 +
summary: wireprotov2: unify file revision collection and linknode derivation

https://www.mercurial-scm.org/repo/hg/rev/008f3491dc53
changeset:   40925:008f3491dc53
bookmark:@
tag: tip
user:Gregory Szorc 
date:Mon Dec 10 20:01:07 2018 +
summary: perf: add perfprogress command

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


[PATCH 2 of 2 RESEND] commandserver: preload repository in master server and reuse its file cache

2018-12-11 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1540993388 -32400
#  Wed Oct 31 22:43:08 2018 +0900
# Node ID 9258d4940c6cd372d2a5bf59454fad81ef0f3e62
# Parent  96ba2adf8adbc016f1d4db03ab61429ad9618569
commandserver: preload repository in master server and reuse its file cache

This greatly speeds up repository operation with lots of obsolete markers:

  $ ls -lh .hg/store/obsstore
  -rw-r--r-- 1 yuya yuya 21M Dec  2 17:55 .hg/store/obsstore
  $ time hg log -G -l10 --pager no
  (hg)   1.79s user 0.13s system 99% cpu 1.919 total
  (chg uncached) 0.00s user 0.01s system 0% cpu 1.328 total
  (chg cached)   0.00s user 0.00s system 3% cpu 0.180 total

As you can see, the implementation of the preloader function is highly
experimental. It works, but I'm yet to be sure how things can be organized.
So I don't want to formalize the API at this point.

diff --git a/mercurial/commandserver.py b/mercurial/commandserver.py
--- a/mercurial/commandserver.py
+++ b/mercurial/commandserver.py
@@ -28,6 +28,7 @@ from . import (
 error,
 loggingutil,
 pycompat,
+repocache,
 util,
 vfs as vfsmod,
 )
@@ -511,6 +512,11 @@ class unixforkingservice(object):
 self._oldsigchldhandler = None
 self._workerpids = set()  # updated by signal handler; do not iterate
 self._socketunlinked = None
+# experimental config: cmdserver.max-repo-cache
+maxlen = ui.configint(b'cmdserver', b'max-repo-cache')
+if maxlen < 0:
+raise error.Abort(_('negative max-repo-cache size not allowed'))
+self._repoloader = repocache.repoloader(ui, maxlen)
 
 def init(self):
 self._sock = socket.socket(socket.AF_UNIX)
@@ -525,6 +531,7 @@ class unixforkingservice(object):
 o = signal.signal(signal.SIGCHLD, self._sigchldhandler)
 self._oldsigchldhandler = o
 self._socketunlinked = False
+self._repoloader.start()
 
 def _unlinksocket(self):
 if not self._socketunlinked:
@@ -537,6 +544,7 @@ class unixforkingservice(object):
 self._mainipc.close()
 self._workeripc.close()
 self._unlinksocket()
+self._repoloader.stop()
 # don't kill child processes as they have active clients, just wait
 self._reapworkers(0)
 
@@ -590,6 +598,10 @@ class unixforkingservice(object):
 return
 raise
 
+# Future improvement: On Python 3.7, maybe gc.freeze() can be used
+# to prevent COW memory from being touched by GC.
+# https://instagram-engineering.com/
+#   copy-on-write-friendly-python-garbage-collection-ad6ed5233ddf
 pid = os.fork()
 if pid:
 try:
@@ -622,8 +634,7 @@ class unixforkingservice(object):
 if inst.args[0] == errno.EINTR:
 return
 raise
-
-self.ui.log(b'cmdserver', b'repository: %s\n', path)
+self._repoloader.load(path)
 
 def _sigchldhandler(self, signal, frame):
 self._reapworkers(os.WNOHANG)
@@ -671,3 +682,9 @@ class unixforkingservice(object):
 
 repo.__class__ = unixcmdserverrepo
 repo._cmdserveripc = self._workeripc
+
+cachedrepo = self._repoloader.get(repo.root)
+if cachedrepo is None:
+return
+repo.ui.log(b'repocache', b'repo from cache: %s\n', repo.root)
+repocache.copycache(cachedrepo, repo)
diff --git a/mercurial/configitems.py b/mercurial/configitems.py
--- a/mercurial/configitems.py
+++ b/mercurial/configitems.py
@@ -179,11 +179,14 @@ coreconfigitem('cmdserver', 'max-log-fil
 coreconfigitem('cmdserver', 'max-log-size',
 default='1 MB',
 )
+coreconfigitem('cmdserver', 'max-repo-cache',
+default=0,
+)
 coreconfigitem('cmdserver', 'message-encodings',
 default=list,
 )
 coreconfigitem('cmdserver', 'track-log',
-default=lambda: ['chgserver', 'cmdserver'],
+default=lambda: ['chgserver', 'cmdserver', 'repocache'],
 )
 coreconfigitem('color', '.*',
 default=None,
diff --git a/mercurial/repocache.py b/mercurial/repocache.py
new file mode 100644
--- /dev/null
+++ b/mercurial/repocache.py
@@ -0,0 +1,131 @@
+# repocache.py - in-memory repository cache for long-running services
+#
+# Copyright 2018 Yuya Nishihara 
+#
+# 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
+
+import collections
+import gc
+import threading
+
+from . import (
+error,
+hg,
+obsolete,
+scmutil,
+util,
+)
+
+class repoloader(object):
+"""Load repositories in background thread
+
+This is designed for a forking server. A cached repo cannot be obtained
+until the server fork()s a worker and the loader thread stops.
+"""
+
+def __init__(self, ui, maxlen):
+self._ui = ui.copy()
+self._cache = util.lrucachedict(max=maxlen)
+# use deque and Event instead of Queue since deque 

[PATCH 1 of 2 RESEND] commandserver: add IPC channel to teach repository path on command finished

2018-12-11 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1540991943 -32400
#  Wed Oct 31 22:19:03 2018 +0900
# Node ID 96ba2adf8adbc016f1d4db03ab61429ad9618569
# Parent  4e17679c336bc38709c32d9b8972f0e402e0057a
commandserver: add IPC channel to teach repository path on command finished

The idea is to load recently-used repositories first in the master process,
and fork(). The forked worker can reuse a warm repository if it's preloaded.

There are a couple of ways of in-memory repository caching. They have pros
and cons:

 a. "preload by master"
pros: can use a single cache dict, maximizing cache hit rate
cons: need to reload a repo in master process (because worker process
  dies per command)
 b. "prefork"
pros: can cache a repo without reloading (as worker processes persist)
cons: lower cache hit rate since each worker has to maintain its own cache
 c. "shared memory" (or separate key-value store server)
pros: no need to reload a repo in master process, ideally
cons: need to serialize objects to sharable form

Since my primary goal is to get rid of the cost of loading obsstore without
massive rewrites, (c) doesn't work. (b) isn't ideal since it would require
much more SDRAMs than (a). So I take (a).

The idea credits to Jun Wu.

diff --git a/mercurial/commandserver.py b/mercurial/commandserver.py
--- a/mercurial/commandserver.py
+++ b/mercurial/commandserver.py
@@ -506,12 +506,19 @@ class unixforkingservice(object):
 raise error.Abort(_('no socket path specified with --address'))
 self._servicehandler = handler or unixservicehandler(ui)
 self._sock = None
+self._mainipc = None
+self._workeripc = None
 self._oldsigchldhandler = None
 self._workerpids = set()  # updated by signal handler; do not iterate
 self._socketunlinked = None
 
 def init(self):
 self._sock = socket.socket(socket.AF_UNIX)
+# IPC channel from many workers to one main process; this is actually
+# a uni-directional pipe, but is backed by a DGRAM socket so each
+# message can be easily separated.
+o = socket.socketpair(socket.AF_UNIX, socket.SOCK_DGRAM)
+self._mainipc, self._workeripc = o
 self._servicehandler.bindsocket(self._sock, self.address)
 if util.safehasattr(procutil, 'unblocksignal'):
 procutil.unblocksignal(signal.SIGCHLD)
@@ -527,6 +534,8 @@ class unixforkingservice(object):
 def _cleanup(self):
 signal.signal(signal.SIGCHLD, self._oldsigchldhandler)
 self._sock.close()
+self._mainipc.close()
+self._workeripc.close()
 self._unlinksocket()
 # don't kill child processes as they have active clients, just wait
 self._reapworkers(0)
@@ -543,6 +552,8 @@ class unixforkingservice(object):
 selector = selectors.DefaultSelector()
 selector.register(self._sock, selectors.EVENT_READ,
   self._acceptnewconnection)
+selector.register(self._mainipc, selectors.EVENT_READ,
+  self._handlemainipc)
 while True:
 if not exiting and h.shouldexit():
 # clients can no longer connect() to the domain socket, so
@@ -592,8 +603,10 @@ class unixforkingservice(object):
 try:
 selector.close()
 sock.close()
+self._mainipc.close()
 self._runworker(conn)
 conn.close()
+self._workeripc.close()
 os._exit(0)
 except:  # never return, hence no re-raises
 try:
@@ -601,6 +614,17 @@ class unixforkingservice(object):
 finally:
 os._exit(255)
 
+def _handlemainipc(self, sock, selector):
+"""Process messages sent from a worker"""
+try:
+path = sock.recv(32768)  # large enough to receive path
+except socket.error as inst:
+if inst.args[0] == errno.EINTR:
+return
+raise
+
+self.ui.log(b'cmdserver', b'repository: %s\n', path)
+
 def _sigchldhandler(self, signal, frame):
 self._reapworkers(os.WNOHANG)
 
@@ -628,6 +652,22 @@ class unixforkingservice(object):
 h = self._servicehandler
 try:
 _serverequest(self.ui, self.repo, conn, h.createcmdserver,
-  prereposetups=None)  # TODO: pass in hook functions
+  prereposetups=[self._reposetup])
 finally:
 gc.collect()  # trigger __del__ since worker process uses os._exit
+
+def _reposetup(self, ui, repo):
+if not repo.local():
+return
+
+class unixcmdserverrepo(repo.__class__):
+def close(self):
+super(unixcmdserverrepo, self).close()
+try:
+self._cmdserveripc.send(self.root)
+except socket.error:
+ 

Re: [PATCH 4 of 6] revlog: add public CPython function to get parent revisions

2018-12-11 Thread Yuya Nishihara
On Mon, 10 Dec 2018 18:54:56 +0100, Georges Racinet wrote:
> On 12/9/18 6:02 AM, Yuya Nishihara wrote:
> > On Wed, 05 Dec 2018 22:43:35 +0900, Yuya Nishihara wrote:
> >> # HG changeset patch
> >> # User Yuya Nishihara 
> >> # Date 1543756237 -32400
> >> #  Sun Dec 02 22:10:37 2018 +0900
> >> # Node ID 716a73bab79be30c20c75e13324c44205d5e2120
> >> # Parent  3842abba948cd7f4bb3fad6805265a35fb94a083
> >> revlog: add public CPython function to get parent revisions
> >> +/*
> >> + * Get parents of the given rev.
> >> + *
> >> + * If the specified rev is out of range, IndexError will be raised. If the
> >> + * revlog entry is corrupted, ValueError may be raised.
> >> + *
> >> + * Returns 0 on success or -1 on failure.
> >> + */
> >> +int HgRevlogIndex_GetParents(PyObject *op, int rev, int *ps)
> > This is based on the idea that the Rust module will be statically linked 
> > with
> > the cext objects. I thought that would be easier for our use case, 
> > package-local
> > visibility, but I'm not certain. If that makes things complicated, maybe we
> > should choose dynamic linking and wrap the function with PyCapsule, as you 
> > did
> > in the PoC code.
> 
> Yes, it's true in the direct-ffi code, I passed the function pointer
> around because I was wary of a loop in dependencies (that's a bit silly
> since we can't avoid linking the Rust extension within the parsers
> module anyway), but also I didn't want to touch the existing C code too
> much for my first patch set. This version you're proposing feels simpler
> to me.
> 
> Using a capsule in that context wouldn't be much complicated either, all
> we'd need in hg-direct-ffi would be to declare and call PyCapsule_Import
> (it's obviously designed to use very few CPython API concepts, only
> needs a char * for the name). The advantage it'd have then would be that
> the same capsule could be used for all types of FFI, and we could do the
> same for other functions we could need later on (maybe in other
> packages). Adding a new capsule seems less risky for people like me, who
> aren't as familiar with mercurial's C code as you are or, if you prefer
> to see it that way, will require less review.
> 
> To be more explicit for other mailing-list subscribers, here's the
> change in revlog.c I'm doing in my PoC CPython code (this is inside the
> module init function) :
> 
> @@ -2846,6 +2846,12 @@
>     if (nullentry)
>     PyObject_GC_UnTrack(nullentry);
>  
> +   void *caps = PyCapsule_New(
> +   index_get_parents,
> "mercurial.cext.parsers.index_get_parents_CAPI",
> +   NULL);
> +   if (caps != NULL)
> +   PyModule_AddObject(mod, "index_get_parents_CAPI", caps);
> +
>  #ifdef WITH_RUST
>     rustlazyancestorsType.tp_new = PyType_GenericNew;
>     if (PyType_Ready() < 0)
> 
> So, to summarize, I think we should maybe promote capsules as the
> preferred way to interface Rust code with inner C code. It wouldn't be
> hard to document either. What do you think ?

My only concern about using PyCapsule is, we would have to get around some
"static mut" variables in Rust if the cost of the name resolution matters.
That's what I noticed while reading your rust/hg-cpython code.

To be clear, I'm not against using PyCapsule. It's documented as the "right"
way to interface C-level APIs across modules. I wrote this patch before
reading your upcoming series. That's the only reason I made the GetParents()
function public.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 5 of 6] rust: look up HgRevlogIndex_GetParents() from symbol table

2018-12-11 Thread Yuya Nishihara
On Mon, 10 Dec 2018 19:00:43 +0100, Georges Racinet wrote:
> On 12/5/18 2:43 PM, Yuya Nishihara wrote:
> > # HG changeset patch
> > # User Yuya Nishihara 
> > # Date 1543756838 -32400
> > #  Sun Dec 02 22:20:38 2018 +0900
> > # Node ID f5cdfa49994e3943ba7c4ce2d66708142f0c7058
> > # Parent  716a73bab79be30c20c75e13324c44205d5e2120
> > rust: look up HgRevlogIndex_GetParents() from symbol table
> >
> > And removes the unused index_get_parents_checked() function.
> >
> > I expect the Index struct will be turned into a pyobject type, though I
> > haven't written any PoC-level patches yet.
> 
> I'm not sure what you mean exactly with turning Index into a pyobject
> type. Would you care to elaborate ?

I mean we'll probably want a Rust type wrapping a Python Index object,
something like:

  impl Index {
  pub fn parents(, py: Python, rev: Revision)
 -> PyResult<[Revision; 2]>
  ...
  }
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D5409: remotefilelog: accepting a None node to cmp

2018-12-11 Thread yuja (Yuya Nishihara)
yuja added a comment.


  >   In context.py, basefilectx.cmp explicitly calls it with None, so it has 
to be
  >   supported. Specifically, this breaks "hg absorb -i" currently.
  
  IIUC, `self._filenode` should never be `None` if the given `fctx._filenode`
  is `None`. If `None` were passed down to the filelog layer, exception would
  be raised.
  
  >   returns True if text is different than what is stored.
  >   """
  > 
  > 
  > - if node == nullid: +if not node or node == nullid: return True
  
  Are we sure that the working-directory data is different from the given text?

REPOSITORY
  rHG Mercurial

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

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


Re: D5409: remotefilelog: accepting a None node to cmp

2018-12-11 Thread Yuya Nishihara
>   In context.py, basefilectx.cmp explicitly calls it with None, so it has to 
> be
>   supported. Specifically, this breaks "hg absorb -i" currently.

IIUC, `self._filenode` should never be `None` if the given `fctx._filenode`
is `None`. If `None` were passed down to the filelog layer, exception would
be raised.

>  returns True if text is different than what is stored.
>  """
>  
> -if node == nullid:
> +if not node or node == nullid:
>  return True

Are we sure that the working-directory data is different from the given text?
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


mercurial@40921: 2 new changesets

2018-12-11 Thread Mercurial Commits
2 new changesets in mercurial:

https://www.mercurial-scm.org/repo/hg/rev/5014e93a5696
changeset:   40920:5014e93a5696
user:Gregory Szorc 
date:Mon Dec 10 19:41:43 2018 +
summary: tests: add sparserevlog requirement to test-sqlitestore.t

https://www.mercurial-scm.org/repo/hg/rev/afdbc9c6a333
changeset:   40921:afdbc9c6a333
bookmark:@
tag: tip
user:Gregory Szorc 
date:Mon Dec 10 16:53:09 2018 +
summary: tests: fix empty commit in test

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


D5410: merge: allow to merge non-conflicting changes outside narrowspec

2018-12-11 Thread pulkit (Pulkit Goyal)
pulkit added a subscriber: martinvonz.
pulkit added a comment.


  I am dubiuos that my fix is correct. I went through the history and didn't 
find any explanation why we don't allow merging non-conflicting changes outside 
narrowspec except TODO's. @martinvonz do you know why we don't allow merging of 
non-conflicting changes here?

REPOSITORY
  rHG Mercurial

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

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


D5410: merge: allow to merge non-conflicting changes outside narrowspec

2018-12-11 Thread pulkit (Pulkit Goyal)
pulkit created this revision.
Herald added a reviewer: durin42.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  This patch allows merging of non-conflicting changes outside narrowspec.

REPOSITORY
  rHG Mercurial

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

AFFECTED FILES
  mercurial/merge.py
  tests/test-narrow-merge.t

CHANGE DETAILS

diff --git a/tests/test-narrow-merge.t b/tests/test-narrow-merge.t
--- a/tests/test-narrow-merge.t
+++ b/tests/test-narrow-merge.t
@@ -80,16 +80,14 @@
   (no more unresolved files)
   $ hg commit -m 'merge inside/f1'
 
-TODO: Can merge non-conflicting changes outside narrow spec
+Can merge non-conflicting changes outside narrow spec
 
   $ hg update -q 'desc("modify inside/f1")'
   $ hg merge 'desc("modify outside/f1")'
-  abort: merge affects file 'outside/f1' outside narrow, which is not yet 
supported (flat !)
-  abort: merge affects file 'outside/' outside narrow, which is not yet 
supported (tree !)
-  (merging in the other direction may work)
-  [255]
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
 
-  $ hg update -q 'desc("modify outside/f1")'
+  $ hg update -q 'desc("modify outside/f1")' -C
   $ hg merge 'desc("modify inside/f1")'
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   (branch merge, don't forget to commit)
diff --git a/mercurial/merge.py b/mercurial/merge.py
--- a/mercurial/merge.py
+++ b/mercurial/merge.py
@@ -1109,10 +1109,7 @@
 elif action[0] in nooptypes:
 del actions[f] # merge does not affect file
 elif action[0] in nonconflicttypes:
-raise error.Abort(_('merge affects file \'%s\' outside narrow, '
-'which is not yet supported') % f,
-  hint=_('merging in the other direction '
- 'may work'))
+del actions[f]
 else:
 raise error.Abort(_('conflict in file \'%s\' is outside '
 'narrow clone') % f)



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


D5408: progress: [RFC] avoid ui.configbool() lookup when progress bar is active

2018-12-11 Thread pulkit (Pulkit Goyal)
pulkit added a comment.


  To add on what commit message says, we have also internally seen progress bar 
taking a lot of time. I am +1 on getting this change in core.

REPOSITORY
  rHG Mercurial

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

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