mercurial@30041: 11 new changesets
11 new changesets in mercurial: http://selenic.com/repo/hg//rev/0f6d6fdd3c2a changeset: 30031:0f6d6fdd3c2a parent: 30028:3741a8f86e88 user:Yuya Nishiharadate:Wed Sep 28 20:01:23 2016 +0900 summary: pycompat: provide 'ispy3' constant http://selenic.com/repo/hg//rev/2219f4f82ede changeset: 30032:2219f4f82ede user:Yuya Nishihara date:Wed Sep 28 22:32:09 2016 +0900 summary: pycompat: extract function that converts attribute or encoding name to str http://selenic.com/repo/hg//rev/02dbfaa6df0b changeset: 30033:02dbfaa6df0b user:Yuya Nishihara date:Wed Sep 28 20:39:06 2016 +0900 summary: py3: convert encoding name and mode to str http://selenic.com/repo/hg//rev/e4a6b439acc5 changeset: 30034:e4a6b439acc5 user:Yuya Nishihara date:Wed Sep 28 20:05:34 2016 +0900 summary: py3: provide encoding.environ which is a dict of bytes http://selenic.com/repo/hg//rev/02328b5d775d changeset: 30035:02328b5d775d user:Yuya Nishihara date:Wed Sep 28 20:07:32 2016 +0900 summary: py3: make i18n use encoding.environ http://selenic.com/repo/hg//rev/3f4e1c033f40 changeset: 30036:3f4e1c033f40 user:Yuya Nishihara date:Fri Sep 30 21:38:47 2016 +0900 summary: url: fix crash by empty path with #fragments http://selenic.com/repo/hg//rev/cd7276f7ea83 changeset: 30037:cd7276f7ea83 parent: 30036:3f4e1c033f40 parent: 30030:8d74027bd4e7 user:Augie Fackler date:Sat Oct 01 15:10:38 2016 -0400 summary: merge with stable http://selenic.com/repo/hg//rev/42ead5b3aa7b changeset: 30038:42ead5b3aa7b user:Pulkit Goyal <7895pul...@gmail.com> date:Sun Oct 02 03:38:14 2016 +0530 summary: py3: use unicodes in __slots__ http://selenic.com/repo/hg//rev/ff7697b436ab changeset: 30039:ff7697b436ab user:Pulkit Goyal <7895pul...@gmail.com> date:Sun Oct 02 05:29:17 2016 +0530 summary: py3: use unicode in is_frozen() http://selenic.com/repo/hg//rev/3e3f2201bbdf changeset: 30040:3e3f2201bbdf user:Jun Wu date:Sat Oct 01 14:18:58 2016 +0100 summary: annotate: calculate line count correctly http://selenic.com/repo/hg//rev/1779dde4c9ef changeset: 30041:1779dde4c9ef bookmark:@ tag: tip user:Gregory Szorc date:Sun Oct 02 22:34:40 2016 -0700 summary: hg: set default path correctly when doing a clone+share (issue5378) -- Repository URL: http://selenic.com/repo/hg/ ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH remotenames-ext] tests: adjust tests to respect negation in cmd flags
Kostia Balytskyiwrites: > # HG changeset patch > # User Kostia Balytskyi > # Date 1475505045 25200 > # Mon Oct 03 07:30:45 2016 -0700 > # Node ID e4c0713ea86204b900a2e1cce238f61e4bef2062 > # Parent 3aa5c4dbf5086615dbbe42b0d2d9fd5ca0488cf1 > tests: adjust tests to respect negation in cmd flags Thanks, queued. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [Bug 5388] New: have hg show similar like git show to show the commit in great detail.
Also "hg export" should do the trick. Le lun. 3 oct. 2016 23:43,a écrit : > https://bz.mercurial-scm.org/show_bug.cgi?id=5388 > > Bug ID: 5388 >Summary: have hg show similar like git show to show the commit > in great detail. >Product: Mercurial >Version: 3.9.1 > Hardware: PC > OS: Linux > Status: UNCONFIRMED > Severity: feature > Priority: wish > Component: Mercurial > Assignee: bugzi...@selenic.com > Reporter: shirisha...@gmail.com > CC: mercurial-de...@selenic.com > > It would be a nice feature to have. Currently this is done by > https://slaptijack.com/software/git-show-in-hg.html but it would be nicer > if > the user didn't need to do things that way and would be command compatible > to > git. > > -- > You are receiving this mail because: > You are on the CC list for the bug. > ___ > Mercurial-devel mailing list > Mercurial-devel@mercurial-scm.org > https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel > ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[Bug 5388] New: have hg show similar like git show to show the commit in great detail.
https://bz.mercurial-scm.org/show_bug.cgi?id=5388 Bug ID: 5388 Summary: have hg show similar like git show to show the commit in great detail. Product: Mercurial Version: 3.9.1 Hardware: PC OS: Linux Status: UNCONFIRMED Severity: feature Priority: wish Component: Mercurial Assignee: bugzi...@selenic.com Reporter: shirisha...@gmail.com CC: mercurial-de...@selenic.com It would be a nice feature to have. Currently this is done by https://slaptijack.com/software/git-show-in-hg.html but it would be nicer if the user didn't need to do things that way and would be command compatible to git. -- You are receiving this mail because: You are on the CC list for the bug. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 2 of 5] extdata: add revset support for extdata
On Tue, 2016-09-27 at 14:41 +0200, Pierre-Yves David wrote: > > On 09/25/2016 12:43 AM, Matt Mackall wrote: > > > > On Sat, 2016-09-24 at 00:22 +0200, Pierre-Yves David wrote: > > > > > > > > > On 09/23/2016 07:34 PM, Matt Mackall wrote: > > > > > > > > > > > > On Fri, 2016-09-23 at 19:49 +0900, FUJIWARA Katsunori wrote: > > > > > > > > > > > > > > > At Thu, 22 Sep 2016 13:21:36 -0500, > > > > > Matt Mackall wrote: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > # HG changeset patch > > > > > > # User Matt Mackall> > > > > > # Date 1474293900 18000 > > > > > > # Mon Sep 19 09:05:00 2016 -0500 > > > > > > # Node ID 9c8847df32a0c5045e60aded2e03a9c97507f909 > > > > > > # Parent 19bf2776dfe39befdc479253e1e7d030b41c08f9 > > > > > > extdata: add revset support for extdata > > > > > > > > > > > > This inserts extdata into the revset function support. Planned > > > > > > extensions of extdata support arguments, so this is the most > > > > > > appropriate place for it. > > > > > > > > > > > > Unfortunately, the registrar framework is not a good fit here. > > > > > > First, > > > > > > setting an appropriate load point is still an unsolved problem (we > > > > > > want the code to live in revset.py, but that module may never be > > > > > > loaded). > > > > > > Second, registered methods become global and the data sources are > > > > > > likely > > > > > > to > > > > > > be > > > > > > repo-specific. This won't work well in a context like hgwebdir. > > > > > Is there any reason not to define extdata() revset predicate (or > > > > > template function), which requires external data source name like as > > > > > extdata('filedata') ? (for convenience ?) > > > > It's mostly convenience. But I also plan to add support for arguments. > > > I think I really like foozy idea about using a generic 'extdata("key")' > > > predicate. That will probably be okay for many case and prevent > > > unexpected collision with other revsets. If needed, the user can easily > > > define a revset alias for the sources in needs easy access to. As > > > configuration of the source is needed anyway, this does seems like a > > > bearable burden. > > > > > > If I remember correctly, it does not seems to have limitation in the > > > current implementation of revset that would prevent use to do > > > 'extdata("key", arg1, arg2)' > > You get to implement this version, because I think it's an awful idea.'ll > hu? I'm not sure of when the Mercurial review process switched to from > "reviewers give feedback to submitter" to "reviewer can update submitter > patch them-self if they don't like it". That seems quite the opposite of > what you have been teaching us in the past 10 years. I've always been aware that there's a risk that contributors will walk away if I'm too nitpicky with their patches or ask them to make a change that they find distasteful. And I've often taken imperfect or incomplete patches because of it. Just so long as forward progress is made and no regressions are introduced. In rare cases, where I find a feature desirable, but can't get a contributor to do it to my satisfaction, I've written it myself (merge-tools comes to mind). The downside of this approach is that there's no reason for the original contributor to feel vested in it further, and I am thus on the hook for maintaining it. This extdata() proposal is a rather silly suggestion because every other namespace in Mercurial already collides. And they collide intentionally because it's convenient for users. We already have revset aliases creating the exact same collision risk so the idea that a) extdata() is somehow protecting me from something but b) I can still get the effect I want by also adding a revset alias is a bit of a self-contradiction. Never mind that I put out an RFC on this topic months ago and that the prototype has been in use for six. But the real issue is that I am still completely exhausted with arguing with you personally, so when you decided to latch on to this proposal, I was immediately reminded of how much I was looking forward to doing other things with my time. So I'm not going to write the extdata() version. You can either shrug and say "I guess we won't have that feature" or you can do it. -- Mathematics is the supreme nostalgia of our time. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 3 of 3 RFC] chgserve: preimport enabled extensions
Excerpts from Yuya Nishihara's message of 2016-10-04 00:29:09 +0900: > On Mon, 3 Oct 2016 15:39:24 +0100, Jun Wu wrote: > > Excerpts from Yuya Nishihara's message of 2016-10-03 21:59:02 +0900: > > > Regarding this, I was thinking about 'extensions.:enabled' syntax so > > > users (or sysadmins) can define a set of conditionally-enabled extensions > > > globally. > > > > > > [extensions] > > > rebase = > > > topic = /path/to/topic.py > > > topic:enabled = False > > > > > > chg daemon will import all extensions listed in ~/.hgrc. And if :enabled > > > = True > > > is flagged by repo/.hg/hgrc, ui/reposetup() will be run. > > > > This may make the implementation more complex and fragile. One area that chg > > currently cannot handle 100% correct is things like "-r bundles", shared > > repo, or inferrepo - confighash may mismatch forever because of differences > > between chg's config loading logic and the non-chg one. If that happens, chg > > may redirect forever. > > Isn't the goal of this series to get rid of the confighash? Yes. "confighash" will only contain sensitive environment variables like PYTHONPATH, LD_PRELOAD etc. ui.config won't affect confighash. > > Because of the above two reasons, I prefer no uisetup for all extensions. It > > leads to a simpler and safer implementation. > > Yep. No ui/reposetup() in the main server process. My idea is how to tell > chg server to pre-import extensions which can't be enabled globally. That has been taken care of in patch 4, which I haven't sent yet. [1] [1]: https://bitbucket.org/quark-zju/hg-draft/commits/51278775 > > Regarding on reposetup, I'm aware that some repo state like the radix tree > > index needs to be persistent in memory. In my opinion, it would be better > > solved by other IPC means, like shared memory or a background daemon > > speaking some protocol. > > Like memcached in some ways. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH remotenames-ext] bookmarks: adopt the formatter isplain method
On 10/3/16, 5:29 PM, "Mercurial-devel on behalf of Kevin Bullock"wrote: > On Oct 3, 2016, at 10:48, Kostia Balytskyi wrote: > > # HG changeset patch > # User Kostia Balytskyi > # Date 1475508913 25200 > # Mon Oct 03 08:35:13 2016 -0700 > # Node ID bc204ce8544ee98aed0119cbf5eec6a3618bf0db > # Parent e4c0713ea86204b900a2e1cce238f61e4bef2062 > bookmarks: adopt the formatter isplain method > > Main hg repo changed the way formatter is supposed to be checked for > plainness: previously people would run `if not fm`, thus relying on > `__nonzero__` method, but now there is `isplain` method of formatter. > Remotenames needs to adopt it. > > diff --git a/remotenames.py b/remotenames.py > --- a/remotenames.py > +++ b/remotenames.py > @@ -1047,7 +1047,7 @@ def displaylocalbookmarks(ui, repo, opts > fm = ui.formatter('bookmarks', opts) > hexfn = fm.hexfunc > marks = repo._bookmarks > -if len(marks) == 0 and not fm: > +if len(marks) == 0 and (not fm or fm.isplain()): Nit: extra space here --^ Yeah, sorry for that. I expect that this can be fixed in-flight, but can resend. pacem in terris / мир / शान्ति / سَلاَم / 平和 Kevin R. Bullock ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH remotenames-ext] bookmarks: adopt the formatter isplain method
> On Oct 3, 2016, at 10:48, Kostia Balytskyiwrote: > > # HG changeset patch > # User Kostia Balytskyi > # Date 1475508913 25200 > # Mon Oct 03 08:35:13 2016 -0700 > # Node ID bc204ce8544ee98aed0119cbf5eec6a3618bf0db > # Parent e4c0713ea86204b900a2e1cce238f61e4bef2062 > bookmarks: adopt the formatter isplain method > > Main hg repo changed the way formatter is supposed to be checked for > plainness: previously people would run `if not fm`, thus relying on > `__nonzero__` method, but now there is `isplain` method of formatter. > Remotenames needs to adopt it. > > diff --git a/remotenames.py b/remotenames.py > --- a/remotenames.py > +++ b/remotenames.py > @@ -1047,7 +1047,7 @@ def displaylocalbookmarks(ui, repo, opts > fm = ui.formatter('bookmarks', opts) > hexfn = fm.hexfunc > marks = repo._bookmarks > -if len(marks) == 0 and not fm: > +if len(marks) == 0 and (not fm or fm.isplain()): Nit: extra space here --^ pacem in terris / мир / शान्ति / سَلاَم / 平和 Kevin R. Bullock ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 3 of 3] mq: release lock after transaction in qrefresh
# HG changeset patch # User Pierre-Yves David# Date 1470920717 -7200 # Thu Aug 11 15:05:17 2016 +0200 # Node ID 870b39c306bef0889f738d292006a1a322757e22 # Parent 901855444329e0a4ad7ad0e41cf0a1b6fd3ed5bc # EXP-Topic vfs.ward mq: release lock after transaction in qrefresh The transaction should be closed within the lock. diff --git a/hgext/mq.py b/hgext/mq.py --- a/hgext/mq.py +++ b/hgext/mq.py @@ -1840,7 +1840,7 @@ class queue(object): self.applied.append(statusentry(n, patchfn)) finally: -lockmod.release(lock, tr) +lockmod.release(tr, lock) except: # re-raises ctx = repo[cparents[0]] repo.dirstate.rebuild(ctx.node(), ctx.manifest()) ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 1 of 3] pull: grab wlock during pull
# HG changeset patch # User Pierre-Yves David# Date 1471988879 -7200 # Tue Aug 23 23:47:59 2016 +0200 # Node ID fbd46d349985f6baa9ea5439697920726757ad38 # Parent 3741a8f86e88702595c29f8ed824a28da0cfa961 # EXP-Topic vfs.ward pull: grab wlock during pull because pull might move bookmarks and bookmark are protected by wlock, we have to grab wlock for pull :-( This required a small upgrade of the 'lockdelay' extension used by 'test-clone.t' because the delay must apply to a single lock only. diff --git a/mercurial/exchange.py b/mercurial/exchange.py --- a/mercurial/exchange.py +++ b/mercurial/exchange.py @@ -1201,8 +1201,10 @@ def pull(repo, remote, heads=None, force " %s") % (', '.join(sorted(missing))) raise error.Abort(msg) -lock = pullop.repo.lock() +wlock = lock = None try: +wlock = pullop.repo.wlock() +lock = pullop.repo.lock() pullop.trmanager = transactionmanager(repo, 'pull', remote.url()) streamclone.maybeperformlegacystreamclone(pullop) # This should ideally be in _pullbundle2(). However, it needs to run @@ -1217,8 +1219,7 @@ def pull(repo, remote, heads=None, force _pullobsolete(pullop) pullop.trmanager.close() finally: -pullop.trmanager.release() -lock.release() +lockmod.release(pullop.trmanager, lock, wlock) return pullop diff --git a/tests/lockdelay.py b/tests/lockdelay.py --- a/tests/lockdelay.py +++ b/tests/lockdelay.py @@ -7,20 +7,16 @@ from __future__ import absolute_import import os import time -from mercurial import ( -lock as lockmod, -) +def reposetup(ui, repo): -class delaylock(lockmod.lock): -def lock(self): -delay = float(os.environ.get('HGPRELOCKDELAY', '0.0')) -if delay: -time.sleep(delay) -res = super(delaylock, self).lock() -delay = float(os.environ.get('HGPOSTLOCKDELAY', '0.0')) -if delay: -time.sleep(delay) -return res - -def extsetup(ui): -lockmod.lock = delaylock +class delayedlockrepo(repo.__class__): +def lock(self): +delay = float(os.environ.get('HGPRELOCKDELAY', '0.0')) +if delay: +time.sleep(delay) +res = super(delayedlockrepo, self).lock() +delay = float(os.environ.get('HGPOSTLOCKDELAY', '0.0')) +if delay: +time.sleep(delay) +return res +repo.__class__ = delayedlockrepo ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 2 of 3] perf: release lock after transaction in perffncachewrite
# HG changeset patch # User Pierre-Yves David# Date 1470919879 -7200 # Thu Aug 11 14:51:19 2016 +0200 # Node ID 901855444329e0a4ad7ad0e41cf0a1b6fd3ed5bc # Parent fbd46d349985f6baa9ea5439697920726757ad38 # EXP-Topic vfs.ward perf: release lock after transaction in perffncachewrite The transaction should be closed within the lock. diff --git a/contrib/perf.py b/contrib/perf.py --- a/contrib/perf.py +++ b/contrib/perf.py @@ -575,8 +575,8 @@ def perffncachewrite(ui, repo, **opts): s.fncache._dirty = True s.fncache.write(tr) timer(d) +tr.close() lock.release() -tr.close() fm.end() @command('perffncacheencode', formatteropts) ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH remotenames-ext] tests: adjust tests to respect negation in cmd flags
# HG changeset patch # User Kostia Balytskyi# Date 1475505045 25200 # Mon Oct 03 07:30:45 2016 -0700 # Node ID e4c0713ea86204b900a2e1cce238f61e4bef2062 # Parent 3aa5c4dbf5086615dbbe42b0d2d9fd5ca0488cf1 tests: adjust tests to respect negation in cmd flags diff --git a/tests/test-remotenames.t b/tests/test-remotenames.t --- a/tests/test-remotenames.t +++ b/tests/test-remotenames.t @@ -289,9 +289,9 @@ Test loading with hggit $ echo "hggit=" >> $HGRCPATH $ hg help bookmarks | grep -A 3 -- '--track' -t --track BOOKMARK track this bookmark or remote name - -u --untrackremove tracking for this bookmark - -a --allshow both remote and local bookmarks - --remote show only remote bookmarks + -u --[no-]untrack remove tracking for this bookmark + -a --[no-]all show both remote and local bookmarks + --[no-]remoteshow only remote bookmarks Test branches marked as closed are not loaded $ cd ../alpha ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH remotenames-ext] bookmarks: adopt the formatter isplain method
# HG changeset patch # User Kostia Balytskyi# Date 1475508913 25200 # Mon Oct 03 08:35:13 2016 -0700 # Node ID bc204ce8544ee98aed0119cbf5eec6a3618bf0db # Parent e4c0713ea86204b900a2e1cce238f61e4bef2062 bookmarks: adopt the formatter isplain method Main hg repo changed the way formatter is supposed to be checked for plainness: previously people would run `if not fm`, thus relying on `__nonzero__` method, but now there is `isplain` method of formatter. Remotenames needs to adopt it. diff --git a/remotenames.py b/remotenames.py --- a/remotenames.py +++ b/remotenames.py @@ -1047,7 +1047,7 @@ def displaylocalbookmarks(ui, repo, opts fm = ui.formatter('bookmarks', opts) hexfn = fm.hexfunc marks = repo._bookmarks -if len(marks) == 0 and not fm: +if len(marks) == 0 and (not fm or fm.isplain()): ui.status(_("no bookmarks set\n")) tracking = _readtracking(repo) ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 3 of 3 RFC] chgserve: preimport enabled extensions
On Mon, 3 Oct 2016 15:39:24 +0100, Jun Wu wrote: > Excerpts from Yuya Nishihara's message of 2016-10-03 21:59:02 +0900: > > Regarding this, I was thinking about 'extensions.:enabled' syntax so > > users (or sysadmins) can define a set of conditionally-enabled extensions > > globally. > > > > [extensions] > > rebase = > > topic = /path/to/topic.py > > topic:enabled = False > > > > chg daemon will import all extensions listed in ~/.hgrc. And if :enabled = > > True > > is flagged by repo/.hg/hgrc, ui/reposetup() will be run. > > This may make the implementation more complex and fragile. One area that chg > currently cannot handle 100% correct is things like "-r bundles", shared > repo, or inferrepo - confighash may mismatch forever because of differences > between chg's config loading logic and the non-chg one. If that happens, chg > may redirect forever. Isn't the goal of this series to get rid of the confighash? > Because of the above two reasons, I prefer no uisetup for all extensions. It > leads to a simpler and safer implementation. Yep. No ui/reposetup() in the main server process. My idea is how to tell chg server to pre-import extensions which can't be enabled globally. > Regarding on reposetup, I'm aware that some repo state like the radix tree > index needs to be persistent in memory. In my opinion, it would be better > solved by other IPC means, like shared memory or a background daemon > speaking some protocol. Like memcached in some ways. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH] merge: update doc of manifestmerge() per 18c2184c27dc
# HG changeset patch # User Yuya Nishihara# Date 1475397092 -32400 # Sun Oct 02 17:31:32 2016 +0900 # Node ID 1fcc4a460a7e86aea018e06e776048e149b36f78 # Parent cd7276f7ea8308df2c5d8874d335d73247d0f357 merge: update doc of manifestmerge() per 18c2184c27dc p1 was renamed to wctx by 18c2184c27dc. diff --git a/mercurial/merge.py b/mercurial/merge.py --- a/mercurial/merge.py +++ b/mercurial/merge.py @@ -781,7 +781,7 @@ def driverconclude(repo, ms, wctx, label def manifestmerge(repo, wctx, p2, pa, branchmerge, force, matcher, acceptremote, followcopies): """ -Merge p1 and p2 with ancestor pa and generate merge action list +Merge wctx and p2 with ancestor pa and generate merge action list branchmerge and force are as passed in to update matcher = matcher to filter file lists ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 1 of 2 v9] graft: support grafting across move/copy (issue4028)
On Mon, 3 Oct 2016 10:28:37 +, Gábor STEFANIK wrote: > > > +_c1 = c1.p1() if c1.rev() is None else c1 > > > +_c2 = c2.p1() if c2.rev() is None else c2 > > > +dirty_c1 = not (ca == _c1 or ca.descendant(_c1)) > > > +dirty_c2 = not (ca == _c2 or ca.descendant(_c2)) > > > +graft = dirty_c1 or dirty_c2 > > > +if graft: > > > +cta = _c1.ancestor(_c2) > > > > Can you fix ctx.descendant() to handle wctx? or maybe this could be > > > > dirtyc = ca != ca.ancestor(c) # for n = 1, 2 > > > > and one of ca.ancestor(c) would be cta. (I don't carefully investigate > > criss- > > cross merge case, so I might be wrong.) > > ctx.ancestor() always returns just one common ancestor, not all possible > candidates. Yes. My guess was ca.ancestor(c1) (not c1.ancestor(c2)) would have only one common ancestor if it is ca, but I didn't think that deeply. > So unfortunately there is no way to eliminate the use of descendant() here, > nor do I feel > that there is a need to do so. descendant() is still faster than ancestor() > or especially > commonancestorsheads(). Anyway, if descendant() is faster than ancestor(), no need to take a slow path. > > > -u1, u2 = _computenonoverlap(repo, c1, c2, addedinm1, addedinm2) > > > +_u1, _u2 = _computenonoverlap(repo, c1, c2, addedinm1, addedinm2) > > > > Can you give them better names? '_' prefix in local variables generally > > means > > they are placeholder (unused output) variables. (Perhaps we can start with a > > trivial patch that separates u1/2 and _u1/2, which will describe why we need > > them.) > > u1r, u2r, u1u, u2u (for rotated/unrotated)? I'm wary of using longer names, > as many lines > in copies.py are already borderline for the 80-character rule, and will > require reformatting > with the introduction of longer variable names. Shorter names seem good so long as they are consistent. > > And it would be nice if there's a brief comment when to use ca/ma over > > cta/mta. > > > > > -seen = set([f]) > > > -for oc in getfctx(f, m1[f]).ancestors(): > > > +seen = {f: [getfctx(f, m1[f])]} > > > +for oc in seen[f][0].ancestors(): > > > ocr = oc.linkrev() > > > of = oc.path() > > > if of in seen: > > > +seen[of].append(oc) > > > # check limit late - grab last rename before > > > if ocr < limit: > > > break > > > continue > > > -seen.add(of) > > > +seen[of] = [oc] > > > > nit: maybe we only need a dict of file nodes, not a dict of file contexts? > > how do I get a file node id from a file context? ancestors() gives us > contexts. fctx.filenode() See also basefilectx.__eq__() to make sure if using .filenode() is appropriate compared to the current code. > > > -fullcopy[f] = of # remember for dir rename detection > > > +# remember for dir rename detection > > > +if backwards: > > > +fullcopy[of] = f # grafting backwards through renames > > > +else: > > > +fullcopy[f] = of > > > if of not in m2: > > > continue # no match, keep looking > > > if m2[of] == ma.get(of): > > > -break # no merge needed, quit early > > > +return # no merge needed, quit early > > > > So we no longer set diverge[of] = [f] this case. I don't know if it was > > necessary to populate 'renamedelete', but this change seems good for a > > separate patch to make sure it never break anything. > > This isn't just some optimization, it's necessary for correct behavior of the > new checkcopies. And it would break the old checkcopies if applied separately > before the main patch. Can you add a test that should fail if we only do s/break/return/ ? Unfortunately, all tests passed if I tried that. > Is that really necessary? It's a lot of additional work for me, to find > intermediate states that may work, > and fix each of them so they don't break anything in the testsuite, only for > those fixes to be reverted > by the next patch in the series. It would be the digital equipment of digging > and filling pits in the ground. > > Splitting isn't the hard part; ensuring no breakage in the intermediate > states is. If that requires lots of unwanted intermediate states, that wouldn't be what we should take. I guess this patch could be split to a) a few trivial changes plus b) one (or two) core change. Hopefully (a) will reduce noises in (b). (I'm not skilled around this code, so please feel free to ignore my comments if they seem wrong.) ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 3 of 3 RFC] chgserve: preimport enabled extensions
Excerpts from Yuya Nishihara's message of 2016-10-03 21:59:02 +0900: > Regarding this, I was thinking about 'extensions.:enabled' syntax so > users (or sysadmins) can define a set of conditionally-enabled extensions > globally. > > [extensions] > rebase = > topic = /path/to/topic.py > topic:enabled = False > > chg daemon will import all extensions listed in ~/.hgrc. And if :enabled = > True > is flagged by repo/.hg/hgrc, ui/reposetup() will be run. This may make the implementation more complex and fragile. One area that chg currently cannot handle 100% correct is things like "-r bundles", shared repo, or inferrepo - confighash may mismatch forever because of differences between chg's config loading logic and the non-chg one. If that happens, chg may redirect forever. I have seen this but haven't got enough time to find out what's going on exactly. In comparison, the new code can load a random hgrc and do not worry about if the extensions listed will be enabled or disabled because of the nice side-effect-free assumption. Running "uisetup" is not safe for extensions reading configs from "ui". I think controlling them via configs is not very friendly for average users. They may mess up and get surprised. Because of the above two reasons, I prefer no uisetup for all extensions. It leads to a simpler and safer implementation. That said, I understand "uisetup" can be fat and expensive. I think if that happens, the extension author can do the slow logic at import-time. So instead of: def uisetup(ui): x = expensive() ... They can write: x = expensive() def uisetup(ui): global x ... So uisetup would remain cheap. If "expensive()" relies on "ui", it cannot be pre-calculated, since chg cannot provide a "correct" "ui" because of possible future config changes. Regarding on reposetup, I'm aware that some repo state like the radix tree index needs to be persistent in memory. In my opinion, it would be better solved by other IPC means, like shared memory or a background daemon speaking some protocol. > > > +def _importext(orig, name, path=None, reportfunc=None): > > +mod = _preimported.get((name, path)) > > +if mod: > > +return mod > > +else: > > +return orig(name, path, reportfunc) > > + > > +def _preimportextensions(ui): > > +for name, path in ui.configitems("extensions"): > > +# only enabled extensions are pre-imported - assuming importing an > > +# extension is side-effect free. > > +if path.startswith('!'): > > +continue > > +try: > > +mod = extensions._importext(name, path) > > +except ImportError: > > +pass > > +else: > > +_preimported[(name, path)] = mod > > Perhaps path needs to be normalized. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
history at diff blocks level
Hi all, I've been recently thinking about adding some support in Mercurial to query repository history based on changes within a given line range in a file. I think that would be useful in at least two commands: * log, to restrict history to revisions that modify specified part(s) of file(s) and only display the diff around specified line range and, * annotate, to window the annotate result and maybe consider walking file revision from tip to base to reduce computation costs. (The "log" part is more interesting, I think.) From UI point of view, the basic idea is to specify a (file name, line range) pair and the simplest solution I could find is something like: hg log/annotate --line-range fromline,toline FILE but this does not work well with several files. (Perhaps something like hg log FILE:fromline:toline would be better.) I also thought about a "changes(filename, fromline, toline)" revset (or an extension of the existing "modifies()" revset), but it seems to me that this would not fit well for both log and annotate. Suggestions welcome. From the technical point of view, my idea is to rely on mdiff.allblocks(, ) (used in both annotate and log, when --patch option is given) to: 1. filter blocks depending on whether they are relevant to specified line range (e.g., for the log command there's some "!" block), and, 2. track the evolution of the line range across revisions (namely, given the line range at rev2, find the line range at rev1 in the example above). I have something working concerning this "low level" aspect, but I'm somehow getting stuck when it comes to plug things into the log command call. Namely, I need to pass the "line range" information from one revision to another during iterations of the loop on revisions in commands.log() [1] and pass this information down to the mdiff.unidiff() call [2] which would then give me back another line range to push up to the outer loop on revisions. Given the complexity of the call chain, I actually think this is not a very good idea... So the best idea I could come up with is to filter revisions beforehand (as would a revset do) but this would imply keeping track of files' line ranges per revision (to avoid processing diff blocks twice when --patch option is specified in particular). All in all, it's not clear to me which "tool" I may use to achieve this (I thought about using the "filematcher" built along with "revs" in commands.log(), but not really sure it's a good idea). Maybe I just need a data structure that does not exist yet? I'd appreciate any pointer to move forward. (I'll be at the sprint, so this can also be a working topic if some people are interested.) -- Denis Laxalde Logilab http://www.logilab.fr [1] https://selenic.com/repo/hg/file/tip/mercurial/commands.py#l5295 [2] https://selenic.com/repo/hg/file/tip/mercurial/patch.py#l2506 ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 1 of 4] bisect: access the filesystem through vfs when reseting
# HG changeset patch # User Pierre-Yves David# Date 1472005909 -7200 # Wed Aug 24 04:31:49 2016 +0200 # Node ID ec6cb977f8e62bf13f86c3a7ebbee182ae50422e # Parent ff7697b436aba70b752a6277eaf4e9ef298e3640 # EXP-Topic bisect bisect: access the filesystem through vfs when reseting We have nice and shiny abstractions now. diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -902,9 +902,8 @@ def bisect(ui, repo, rev=None, extra=Non cmdutil.checkunfinished(repo) if reset: -p = repo.join("bisect.state") -if os.path.exists(p): -os.unlink(p) +if repo.vfs.exists("bisect.state"): +repo.vfs.unlink("bisect.state") return state = hbisect.load_state(repo) ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 3 of 4] bisect: move the 'extendrange' to the 'hbisect' module
# HG changeset patch # User Pierre-Yves David# Date 1472004967 -7200 # Wed Aug 24 04:16:07 2016 +0200 # Node ID 2c643f89b68448619f6cf4326c58ef8cc686e51a # Parent efd8013b1521399d07ca956c1cba7bd9f7dfc6e0 # EXP-Topic bisect bisect: move the 'extendrange' to the 'hbisect' module We have a module ready to host any bisect logic. That logic was already isolated in a function so we just migrate it as is. diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -835,20 +835,6 @@ def bisect(ui, repo, rev=None, extra=Non Returns 0 on success. """ -def extendbisectrange(nodes, good): -# bisect is incomplete when it ends on a merge node and -# one of the parent was not checked. -parents = repo[nodes[0]].parents() -if len(parents) > 1: -if good: -side = state['bad'] -else: -side = state['good'] -num = len(set(i.node() for i in parents) & set(side)) -if num == 1: -return parents[0].ancestor(parents[1]) -return None - def print_result(nodes, good): displayer = cmdutil.show_changeset(ui, repo, {}) if len(nodes) == 1: @@ -858,7 +844,7 @@ def bisect(ui, repo, rev=None, extra=Non else: ui.write(_("The first bad revision is:\n")) displayer.show(repo[nodes[0]]) -extendnode = extendbisectrange(nodes, good) +extendnode = hbisect.extendrange(repo, state, nodes, good) if extendnode is not None: ui.write(_('Not all ancestors of this changeset have been' ' checked.\nUse bisect --extend to continue the ' @@ -977,7 +963,7 @@ def bisect(ui, repo, rev=None, extra=Non nodes, changesets, good = hbisect.bisect(repo.changelog, state) if extend: if not changesets: -extendnode = extendbisectrange(nodes, good) +extendnode = hbisect.extendrange(repo, state, nodes, good) if extendnode is not None: ui.write(_("Extending search to changeset %d:%s\n") % (extendnode.rev(), extendnode)) diff --git a/mercurial/hbisect.py b/mercurial/hbisect.py --- a/mercurial/hbisect.py +++ b/mercurial/hbisect.py @@ -139,6 +139,19 @@ def bisect(changelog, state): return ([best_node], tot, good) +def extendrange(repo, state, nodes, good): +# bisect is incomplete when it ends on a merge node and +# one of the parent was not checked. +parents = repo[nodes[0]].parents() +if len(parents) > 1: +if good: +side = state['bad'] +else: +side = state['good'] +num = len(set(i.node() for i in parents) & set(side)) +if num == 1: +return parents[0].ancestor(parents[1]) +return None def load_state(repo): state = {'current': [], 'good': [], 'bad': [], 'skip': []} ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH] hg: set default path correctly when doing a clone+share (issue5378)
On Sun, 02 Oct 2016 22:39:02 -0700, Gregory Szorc wrote: > # HG changeset patch > # User Gregory Szorc> # Date 1475472880 25200 > # Sun Oct 02 22:34:40 2016 -0700 > # Node ID 5333771304e905cecc8b35c4c137d407fc49eb92 > # Parent cd7276f7ea8308df2c5d8874d335d73247d0f357 > hg: set default path correctly when doing a clone+share (issue5378) Nice, queued, thanks. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 3 of 3 RFC] chgserve: preimport enabled extensions
On Mon, 3 Oct 2016 07:11:20 +0100, Jun Wu wrote: > # HG changeset patch > # User Jun Wu> # Date 1475463449 -3600 > # Mon Oct 03 03:57:29 2016 +0100 > # Node ID 6f38a7d259add12c44040535681c4b3ceef0a791 > # Parent 7d106c3386e17746c9b49ab9c788535634b3e8f6 > # Available At https://bitbucket.org/quark-zju/hg-draft > # hg pull https://bitbucket.org/quark-zju/hg-draft -r > 6f38a7d259ad > chgserve: preimport enabled extensions > > This patch pre-imports enabled extensions, so performance improvement is > visible. It's about 0.01 seconds slower than the old chg, which seems to be > acceptable. (I haven't read the patch 1 and 2 yet.) Regarding this, I was thinking about 'extensions.:enabled' syntax so users (or sysadmins) can define a set of conditionally-enabled extensions globally. [extensions] rebase = topic = /path/to/topic.py topic:enabled = False chg daemon will import all extensions listed in ~/.hgrc. And if :enabled = True is flagged by repo/.hg/hgrc, ui/reposetup() will be run. > +def _importext(orig, name, path=None, reportfunc=None): > +mod = _preimported.get((name, path)) > +if mod: > +return mod > +else: > +return orig(name, path, reportfunc) > + > +def _preimportextensions(ui): > +for name, path in ui.configitems("extensions"): > +# only enabled extensions are pre-imported - assuming importing an > +# extension is side-effect free. > +if path.startswith('!'): > +continue > +try: > +mod = extensions._importext(name, path) > +except ImportError: > +pass > +else: > +_preimported[(name, path)] = mod Perhaps path needs to be normalized. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
RE: [PATCH 1 of 2 v9] graft: support grafting across move/copy (issue4028)
> -- This message, including its attachments, is confidential. For more information please read NNG's email policy here: http://www.nng.com/emailpolicy/ By responding to this email you accept the email policy. -Original Message- > From: Yuya Nishihara [mailto:you...@gmail.com] On Behalf Of Yuya > Nishihara > Sent: Sunday, October 2, 2016 6:02 PM > To: Gábor STEFANIK> Cc: mercurial-devel@mercurial-scm.org > Subject: Re: [PATCH 1 of 2 v9] graft: support grafting across move/copy > (issue4028) > > On Fri, 16 Sep 2016 15:45:18 -0500, Gábor Stefanik wrote: > > # HG changeset patch > > # User Gábor Stefanik # Date 1474058125 -7200 > > # Fri Sep 16 22:35:25 2016 +0200 > > # Node ID 63a2ea1bc3aa51caaf22bdfe31e7ae685ac3894f > > # Parent 285a8c3e53f2183438f0cdbc238e4ab851d0d110 > > graft: support grafting across move/copy (issue4028) > > > diff --git a/mercurial/copies.py b/mercurial/copies.py > > --- a/mercurial/copies.py > > +++ b/mercurial/copies.py > > @@ -321,6 +321,23 @@ > > if repo.ui.configbool('experimental', 'disablecopytrace'): > > return {}, {}, {}, {} > > > > +# In certain scenarios (e.g. graft, update or rebase), ca can be > overridden > > +# We still need to know a real common ancestor in this case > > +# We can't just compute _c1.ancestor(_c2) and compare it to ca, > because > > +# there can be multiple common ancestors, e.g. in case of bidmerge. > > +# Because our caller may not know if the revision passed in lieu of the > CA > > +# is a genuine common ancestor or not without explicitly checking it, > > it's > > +# better to determine that here. > > +cta = ca > > +# ca.descendant(wc) and ca.descendant(ca) are False, work around that > > +_c1 = c1.p1() if c1.rev() is None else c1 > > +_c2 = c2.p1() if c2.rev() is None else c2 > > +dirty_c1 = not (ca == _c1 or ca.descendant(_c1)) > > +dirty_c2 = not (ca == _c2 or ca.descendant(_c2)) > > +graft = dirty_c1 or dirty_c2 > > +if graft: > > +cta = _c1.ancestor(_c2) > > Can you fix ctx.descendant() to handle wctx? or maybe this could be > > dirtyc = ca != ca.ancestor(c) # for n = 1, 2 > > and one of ca.ancestor(c) would be cta. (I don't carefully investigate > criss- > cross merge case, so I might be wrong.) ctx.ancestor() always returns just one common ancestor, not all possible candidates. bidmerge uses a function called commonancestorsheads() instead (not sure where that can be found), but a non-head common ancestor also shouldn't trigger graft logic. So unfortunately there is no way to eliminate the use of descendant() here, nor do I feel that there is a need to do so. descendant() is still faster than ancestor() or especially commonancestorsheads(). > > > # find interesting file sets from manifests > > +if graft: > > +repo.ui.debug(" computing unmatched files in rotated DAG\n") > > addedinm1 = m1.filesnotin(ma) > > addedinm2 = m2.filesnotin(ma) > > -u1, u2 = _computenonoverlap(repo, c1, c2, addedinm1, addedinm2) > > +_u1, _u2 = _computenonoverlap(repo, c1, c2, addedinm1, addedinm2) > > Can you give them better names? '_' prefix in local variables generally means > they are placeholder (unused output) variables. (Perhaps we can start with a > trivial patch that separates u1/2 and _u1/2, which will describe why we need > them.) u1r, u2r, u1u, u2u (for rotated/unrotated)? I'm wary of using longer names, as many lines in copies.py are already borderline for the 80-character rule, and will require reformatting with the introduction of longer variable names. > > > +# combine partial copy paths discovered in the previous step > > +copyfrom, copyto = incomplete1, incomplete2 > > +if dirty_c1: > > +copyfrom, copyto = incomplete2, incomplete1 > > +for f in copyfrom: > > +if f in copyto: > > +copy[copyto[f]] = copyfrom[f] > > +del copyto[f] > > +for f in incompletediverge: > > +assert f not in diverge > > +ic = incompletediverge[f] > > +if ic[0] in copyto: > > +diverge[f] = [copyto[ic[0]], ic[1]] > > Perhaps this can be a separate function, which would avoid spilling out > temporary variables, copyfrom/to. Sounds doable. > > > +_incomplete = _incomplete2 > > +if dirty_c1: > > +_incomplete = _incomplete1 > > +assert _incomplete2 == {} > > +else: > > +assert _incomplete1 == {} > > +for f in _diverge: > > +assert f not in bothdiverge > > +ic = _diverge[f] > > +if ic[0] in _incomplete: > > +bothdiverge[f] = [_incomplete[ic[0]], ic[1]] > > +elif ic[0] in (m1 if dirty_c1 else m2): > > +# backed-out rename on one side, but watch out for deleted > > files > > +bothdiverge[f] = ic > > This looks
[PATCH 1 of 3 RFC] chg: add a standalone entry point
# HG changeset patch # User Jun Wu# Date 1475458616 -3600 # Mon Oct 03 02:36:56 2016 +0100 # Node ID 7b19924c9fd57fbb7fa39c103902d51d7ea9beb4 # Parent cd7276f7ea8308df2c5d8874d335d73247d0f357 # Available At https://bitbucket.org/quark-zju/hg-draft # hg pull https://bitbucket.org/quark-zju/hg-draft -r 7b19924c9fd5 chg: add a standalone entry point This is the beginning of a series that does a re-architect to chg mentioned in [1], to achieve better compatibility. The compatibility issues are mainly around "uisetup"s and "reposetup"s: - Developers are usually unaware that uisetup runs only once per chg process. We cannot reliably devel-warn them. The result is, potential broken code are written. For example, it's really hard for chg to deal with "experimental.evolution" changed from unset to manually set in config files because setconfig is used if that config option is not set. - An unnecessary "reposetup" caused by "hg serve" may have unwanted side effects. This can become troublesome if the repo requires things like remotefilelog or lz4revlog, and the user sets HGRCPATH to run tests. The current chg implementation assumes that "loading" an extension is not side effect free - if extension related config has changed, a restart is needed. The new idea is, "loading" = "importing" + "run ui/extsetup", the "importing" part can be side-effect free for some extensions. And benchmark shows "import" takes most of the time consumed, while "uisetup" is usually very fast. We can afford running "uisetup"s per request. To be able to (pre-)"import" extensions without running any "uisetup"s, a different entry point is needed. Otherwise as long as we go through the normal dispatch / runcommand ("hg serve") flow, "uisetup"s cannot be avoided. Aside from better compatibility, we can also remove some hacks: - chg client: no longer needs to extract sensitive argv - chg server: confighash can be changed to only hash environment variables (reduce the number of server processes) - chg server: srcui.walkconfig hack is no longer necessary This patch adds a new script "chgserve" as the new entry point. Currently, it is just a minimal implementation that makes "CHGHG=chgserve chg ..." work, without doing any pre-importing. The change could also be done in the "hg" script. But since chg is still experimental, let's keep "hg" untouched for now. [1]: www.mercurial-scm.org/pipermail/mercurial-devel/2016-July/085965.html diff --git a/contrib/chg/chgserve b/contrib/chg/chgserve new file mode 100755 --- /dev/null +++ b/contrib/chg/chgserve @@ -0,0 +1,46 @@ +#!/usr/bin/env python + +from __future__ import absolute_import + +import os +import sys + +from mercurial import ( +cmdutil, +commands, +commandserver, +dispatch, +fancyopts, +ui as uimod, +util, +) + +from hgext import chgserver + +def _confighash(ui): +envitems = [(k, v) for k, v in os.environ.iteritems() +if chgserver._envre.match(k)] +envhash = chgserver._hashlist(sorted(envitems)) +return envhash[:12] + +def _startchgservice(): +# patch chgserver's confighash to only hash environment variables +chgserver._confighash = _confighash + +ui = uimod.ui() +repo = None +args = sys.argv[2:] +dispatch._earlygetopt(['--config'], args) +opts = {} +fancyopts.fancyopts(args, commands.table['^serve'][1], opts) + +service = chgserver.chgunixservice(ui, repo, opts) +cmdutil.service(opts, initfn=service.init, runfn=service.run) + +def _setbinary(): +for fp in (sys.stdin, sys.stdout, sys.stderr): +util.setbinary(fp) + +if __name__ == '__main__': +_setbinary() +sys.exit(_startchgservice()) ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 3 of 3 RFC] chgserve: preimport enabled extensions
# HG changeset patch # User Jun Wu# Date 1475463449 -3600 # Mon Oct 03 03:57:29 2016 +0100 # Node ID 6f38a7d259add12c44040535681c4b3ceef0a791 # Parent 7d106c3386e17746c9b49ab9c788535634b3e8f6 # Available At https://bitbucket.org/quark-zju/hg-draft # hg pull https://bitbucket.org/quark-zju/hg-draft -r 6f38a7d259ad chgserve: preimport enabled extensions This patch pre-imports enabled extensions, so performance improvement is visible. It's about 0.01 seconds slower than the old chg, which seems to be acceptable. diff --git a/contrib/chg/chgserve b/contrib/chg/chgserve --- a/contrib/chg/chgserve +++ b/contrib/chg/chgserve @@ -11,4 +11,5 @@ from mercurial import ( commandserver, dispatch, +extensions, fancyopts, ui as uimod, @@ -24,4 +25,27 @@ def _confighash(ui): return envhash[:12] +_preimported = {} # {(name, path): mod} + +def _importext(orig, name, path=None, reportfunc=None): +mod = _preimported.get((name, path)) +if mod: +return mod +else: +return orig(name, path, reportfunc) + +def _preimportextensions(ui): +for name, path in ui.configitems("extensions"): +# only enabled extensions are pre-imported - assuming importing an +# extension is side-effect free. +if path.startswith('!'): +continue +try: +mod = extensions._importext(name, path) +except ImportError: +pass +else: +_preimported[(name, path)] = mod +ui.debug('chg: preimported %s\n' % name) + def _startchgservice(): # patch chgserver's confighash to only hash environment variables @@ -35,4 +59,7 @@ def _startchgservice(): fancyopts.fancyopts(args, commands.table['^serve'][1], opts) +_preimportextensions(ui) +extensions.wrapfunction(extensions, '_importext', _importext) + service = chgserver.chgunixservice(ui, repo, opts) cmdutil.service(opts, initfn=service.init, runfn=service.run) ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel