This replaces 'if y in subset' with '& subset'. first(null) and last(wdir())
are fixed thanks to fullreposet.__and__.
This also revealed that first() and last() don't follow the order of the
input set. 'ls & subset' is valid only if the ordering requirement is 'define'
or 'any'.
No performance regression observed:
revset #0: limit(0:9999, 100, 9000)
0) 0.001164
1) 0.001135
revset #2: 9000 & limit(0:9999, 100, 9000)
0) 0.001224
1) 0.001181
revset #3: last(0:9999, 100)
0) 0.000237
1) 0.000199
last() is implemented using a reversed iterator, so the result should be
reversed again.
I've marked this as BC since it's quite old bug seen in 3.0. The first bad
revision is 1ef0875a62f8 "revset: changed last implementation to use lazy
classes."
Instead of walking all ancestors to compute the full set we now check membership
lazily. This massively speed.
On a million-ish revision repository, this remove 14 seconds from the push logic,
making the checkheads function disappear from profile.
The obsolete post-processing needs to know the extend of the pushed set. The
way it is implemented is... suboptimal. It build a full set of all nodes in the
pushset and it does so using changectx. We have much better API for this now.
The simplest is to use the existing lazy ancestors computation. That logic uses
revnum and not node (for good reason) so we start with updating the
post-processing code to handle a "allfuturecommon" set containing revision
numbers.
We are about to call 'torev' on node that might be locally missing. In this
case, 'nodemap.revs' will return None (something valid in our usecase) while
'changelog.rev' would raise an exception.
We make this change in a distinct changeset to show it does not impact the
tests.
We are about to make "allfuturecommon" a set of revs instead of a set of nodes.
The function updated in this patch do not needs to know about these details so
we just pass it a 'ispushed(node)' function. This will simplify the next
changeset.
It seems sufficiently simple to use "profile(enabled=X)" to not justify having
a dedicated context manager just to read the config.
(I do not have a too strong opinion about this).
We now process the "--profile" a second time after alias has been processed and
the command argument fully parsed. If appropriate we enable profiling at that
time.
In these situation, the --profile will cover less than if the full --profile
flag was passed on the command line. This is better than the previous behavior
(flag ignored) and still fullfil multiple valid usecases.
This is a step toward allowing context where the profiling in enabled
withing the context range.
This also open the way to kill the dedicated "maybeprofile" context manager
and keep only one of 'profile' and 'maybeprofile'.
The start method is doing all profiler setup and activation. It is currently
unconditionally called by '__init__' but this will be made more flexible in
later changesets.
So far we have been able to use a simple decorator for this. However using the
current context manager makes the scope of the profiling in dispatch
constrainted and the time frame to decide to enable profiling quite limited
(using "maybeprofile")
This is the first step toward the ability to enable the profiling from within
the profiling scope. eg::
with maybeprofiling(ui) as profiler:
...
bar.foo():
...
if options['profile']:
profiler.start()
...
fooz()
...
My target usecase is adding support for "--profile" to alias definitions with
effect. These are to be used with "profiling.output=blackbox" to gather data
about operation that get slow from time to time (eg: pull being minutes instead
of seconds from time to time).
Of course, in such case, the scope of the profiling would be smaller since
profiler would be started after running extensions 'reposetup' (and other
potentially costly logic), but these are not relevant for my target usecase
(multiple second commits, multiple tens of seconds pull).
Currently adding '--profile' to a command through alias requires to re-spin a
Mercurial binary (using "!$HG" in alias), which as a significant performance
impact, especially in context where startup performance is being worked on...
An alternative approach would be to stop using the context manager in dispatch
and move back to a try/finally setup.
The 'srvheads' list contains all server heads including the common ones. We
adjust 'ui.log' message to provide more useful information about server heads
locally unknown. The performance impact of turning the list to set is
negligible (about 1e-4s) compared to the rest of the discovery cost, so I'm
taking the easy path.
gitweb was missing the hint hover box. So that was added.
Also, the positioning of the form was absolute and it didn't
vertically align on all pages. The element has been moved inline
with the navigation links (which now are contained in a div) and
flexbox is used to obtain sane alignment of the navigation links
and search form. For those new to flexbox,
"justify-content: space-between" basically says to maximize space
elements. You can use it to easily get left and right justified
containers without having to worry about width, floating, etc.
"align-items: center" centers all items in a cross-axis. I've
literally wasted hours trying to figure out both these problems
before flexbox. Flexbox is amazing.
Flexbox has been supported by Chrome and Firefox for a few years.
But it is only supported by IE 11. I'm willing to wager that
people using this either won't be using IE or will be using IE 11.
So I'm willing to be a bit aggressive in adopting flexbox because
it makes CSS alignment so much easier.
Paper has it on all pages. Not sure why gitweb doesn't. I think it
should be everywhere because it is a useful feature.
Also, we weren't consistently adding the HTML in the same place. This
was OK since the element is absolutely positioned. But this bothered
me a bit, so I went ahead and fixed it.
AFAICT this was mostly a bunch of copy pasta. The only variation is
some pages defined a "value" attribute. The "query" variable will
just be empty on pages that don't accept it. So let's consolidate
the template and remove the redundancy.
Before this patch, workingctx.status() may cause writing outdated
dirstate out, if:
- .hg/dirstate is changed simultaneously after last loading it,
- there is any file, which should be dirstate.normal()-ed
Typical issue case is:
- the working directory is updated by "hg update"
- .hg/dirstate is updated in background (e.g. fsmonitor)
This patch compares identities of dirstate before and after
acquisition of wlock, and avoids writing outdated dirstate out, if
change of .hg/dirstate is detected.
This identity is used to examine whether dirstate is simultaneously
changed in storage after previous caching (see issue5584 for detail).
util.cachestat can't be used for this purpose, because it has no
valuable information on Windows.
On the other hand, util.filestat can detect changing dirstate in
storage certainly, regardless of platforms.
https://www.mercurial-scm.org/wiki/ExactCacheValidationPlan
Strictly speaking, if underlying filesystem doesn't support
ctime/mtime, util.filestat can't detect simultaneous changing in
storage as expected. But simultaneous changing on such (very rare)
platform can't be detected regardless of this patch series.
Therefore, util.filestat should be reasonable identity for almost all
usecases.
In order to fix issue5418, 0d920bcb0fd1 made vfs.rename(checkambig=True)
omit advancing mtime of renamed file, if renamed file is owned by
another (EPERM is raised in this case).
But this omission causes rewinding mtime at restoration in such
situation, and makes avoiding file stat ambiguity difficult, because
ExactCacheValidationPlan assumes that mtime should be advanced, if a
file is changed in same ctime.
https://www.mercurial-scm.org/wiki/ExactCacheValidationPlan
Ambiguity of file stat also requires issue5584 to be fixed with other
than file stat, but "hash of file", "generation ID" and so on were
already rejected ideas (please see original RFC linked from "Outline
of issue" in ExactCacheValidationPlan page).
This omission occurs:
- only for non append-only files (dirstate, bookmarks, and phaseroots), and
- only if previous transaction is rollbacked by another user
The latter means "sharing a repository clone via group permission".
This is reasonable usecase, but not ordinary for many users, IMHO.
"hg rollback" itself has been deprecated since Mercurial 2.7, too.
Therefore, increasing the cost at rollbacking previous transaction
executed by another a little seems reasonable, for avoidance of file
stat ambiguity.
This patch does:
- create copy of (already renamed) source file, if advancing mtime
fails for EPERM
- rename from copied file to destination file, and
- advance mtime of renamed file, which is now owned by current user
This patch also factors "self.join(src)" out to reduce redundancy.
This seems like a prudent thing to do. As the inline comment says,
we may want to make this abort once the functionality is stabilized
as part of `hg bundle`. Let's save that debate for another day.
Previously, a repo containing secret changesets would be served via
stream clone, transferring those secret changesets. While secret
changesets aren't meant to imply strong security (if you really
want to keep them secret, others shouldn't have read access to the
repo), we should at least make an effort to protect secret changesets
when possible.
After this commit, we no longer serve stream clones for repos
containing secret changesets by default. This is backwards
incompatible behavior. In case anyone is relying on the behavior,
we provide a config option to opt into the old behavior.
Note that this defense is only beneficial for remote repos
accessed via the wire protocol: if a client has access to the
files backing a repo, they can get to the raw data and see secret
revisions.
Since we no longer set '_clean = False' during the initialization loop, we can
move the attribute assignment earlier in the function for clarity.
(no speed improvement expected or measured ;-) )
The bmstore '__setitem__' method is setting an extra flag that is not needed
during initialization. Skipping the method will allow further cleanup and yield
some speedup as a side effect.
Before:
! wall 0.009120 comb 0.010000 user 0.010000 sys 0.000000 (best of 312)
After:
! wall 0.007874 comb 0.010000 user 0.010000 sys 0.000000 (best of 360)
Since we already have an exception context open, for other thing, we can
simplify the code a bit and rely on exception handling for invalid lines.
Speed is not the main motivation for this changes. However as I'm in the middle
of benchmarking things we can see a small positive impact.
Before:
! wall 0.009358 comb 0.000000 user 0.000000 sys 0.000000 (best of 303)
After:
! wall 0.009173 comb 0.010000 user 0.010000 sys 0.000000 (best of 310)
We know the content of the file is supposed to be full hex. So we can do the
translation ourselves and directly check if the node is known.
As nice side effect we now have proper error handling for invalid node value.
Before:
! wall 0.021580 comb 0.020000 user 0.020000 sys 0.000000 (best of 134)
After:
! wall 0.009342 comb 0.010000 user 0.010000 sys 0.000000 (best of 302)
Skipping the attribute lookup up raise a significant speedup.
Example on a repository with about 4000 bookmarks.
Before:
! wall 0.026027 comb 0.020000 user 0.020000 sys 0.000000 (best of 112)
After:
! wall 0.021580 comb 0.020000 user 0.020000 sys 0.000000 (best of 134)
(This is also in its own changeset to clarify the perf win from another coming
changesets)
This is obviously an instance attribute, not a type attribute. The
modern Python style is to use __init__ for defining these.
This exposes statichttprepo as inheriting from localrepository
without calling its __init__. As a result, its __init__ defines
a lot of variables that methods on localrepository's methods need.
But factoring the common bits into a separate class is for another
day.