Commit Graph

1709 Commits

Author SHA1 Message Date
Boris Feld
c9fe43d98b repovfs: add a ward to check if locks are properly taken
When the appropriate developer warnings are enabled, We wrap 'repo.vfs.audit' to
check for locks when accessing file in '.hg' for writing. Another changeset will
add a 'ward' for the store vfs (svfs).

This check system has caught a handful of locking issues that have been fixed
in previous series (mostly in 4.0). I expect another batch to be caught in third
party extensions.

We introduce two real exceptions from extensions 'blackbox.log' (because a lot of
read-only operations add entry to it), and 'last-email.txt' (because 'hg email'
is currently a read only operation and there is value to keep it this way).

In addition we are currently allowing bisect to operate outside of the lock
because the current code is a bit hard to get properly locked for now. Multiple
clean up have been made but there is still a couple of them to do and the freeze
is coming.
2017-07-11 12:38:17 +02:00
Martin von Zweigbergk
bf2a3c6ad8 py3: make localrepo filtered repo cache work on py3
I don't know if this is the right fix, but it makes
test-py3-commands.t pass again.

Differential Revision: https://phab.mercurial-scm.org/D56
2017-07-11 11:21:04 -07:00
Gregory Szorc
c0447df5a2 localrepo: cache types for filtered repos (issue5043)
Python introduces a reference cycle on dynamically created types
via __mro__, making them very easy to leak. See
https://bugs.python.org/issue17950.

Previously, repo.filtered() created a type on every invocation.
Long-running processes (like `hg convert`) could call this
function thousands of times, leading to a steady memory leak.

Since we're Unable to stop the leak because this is a bug in
Python, the next best thing is to contain it.

This patch adds a cache of of the dynamically generated repoview/filter
types on the localrepo object. Since we only generate each type
once, we cap the amount of memory that can leak to something
reasonable.

After this change, `hg convert` no longer leaks memory on every
revision. The process will likely grow memory usage over time due
to e.g. larger manifests. But there are no leaks.
2017-07-01 20:51:19 -07:00
FUJIWARA Katsunori
63fd3449f5 localrepo: add isfilecached to check filecache-ed property is already cached
isfilecached() encapsulates internal implementation of filecache-ed
property.

"name in repo.unfiltered().__dict__" or so can't be used for this
purpose, because corresponded entry in __dict__ might be discarded by
repo.invalidate(), repo.invalidatedirstate() or so (fsmonitor does so,
for example).

This patch makes isfilecached() return not only whether filecache-ed
property is already cached, but also already cached value (or None),
in order to avoid subsequent access to cached object via "repo.NAME",
which prevents main Mercurial procedure after reposetup() from
validating cache.
2017-07-10 23:09:51 +09:00
Gregory Szorc
a7c49e2ec2 dirstate: expose a sparse matcher on dirstate (API)
The sparse extension performs a lot of monkeypatching of dirstate
to make it sparse aware. Essentially, various operations need to
take the active sparse config into account. They do this by obtaining
a matcher representing the sparse config and filtering paths through
it.

The monkeypatching is done by stuffing a reference to a repo on
dirstate and calling sparse.matcher() (which takes a repo instance)
during each function call. The reason this function takes a repo
instance is because resolving the sparse config may require resolving
file contents from filelogs, and that requires a repo. (If the
current sparse config references "profile" files, the contents of
those files from the dirstate's parent revisions is resolved.)

I seem to recall people having strong opinions that the dirstate
object not have a reference to a repo. So copying what the sparse
extension does probably won't fly in core. Plus, the dirstate
modifications shouldn't require a full repo: they only need a matcher.
So there's no good reason to stuff a reference to the repo in
dirstate.

This commit exposes a sparse matcher to dirstate via a property that
when looked up will call a function that eventually calls
sparse.matcher(). The repo instance is bound in a closure, so it
isn't exposed to dirstate.

This approach is functionally similar to what the sparse extension does
today, except it hides the repo instance from dirstate. The approach
is not optimal because we have to call a proxy function and
sparse.matcher() on every property lookup. There is room to cache
the matcher instance in dirstate. After all, the matcher only changes
if the dirstate's parents change or if the sparse config changes. It
feels like we should be able to detect both events and update the
matcher when this occurs. But for now we preserve the existing
semantics so we can move the dirstate sparseness bits into core. Once
in core, refactoring becomes a bit easier since it will be clearer how
all these components interact.

The sparse extension has been updated to use the new property.
Because all references to the repo on dirstate have been removed,
the code for setting it has been removed.
2017-07-08 16:18:04 -07:00
Jun Wu
f50841989e revset: make repo.anyrevs accept customized alias override (API)
Previously repo.anyrevs only expand aliases in [revsetalias] config. This
patch makes it more flexible to accept a customized dict defining aliases
without having to couple with ui.

revsetlang.expandaliases now has the signature (tree, aliases, warn=None)
which is more consistent with templater.expandaliases. revsetlang.py is now
free from "ui", which seems to be a good thing.
2017-06-24 15:29:42 -07:00
Gregory Szorc
0cd417305b localrepo: add sparse caches
The sparse extension maintains caches for the sparse files
to a signature and a signature to a matcher. This allows the
sparse matchers to be resolved quickly, which is apparently
something that can occur in loops.

This patch ports the sparse caches to the localrepo class
pretty much as-is. There is potentially room to improve the
caching mechanism. But that can be done as a follow-up.

The default invalidatecaches() now clears the relevant sparse
cache. invalidatesignaturecache() has been moved to sparse.py.
2017-07-06 12:20:53 -07:00
FUJIWARA Katsunori
ba85a5641c transaction: avoid file stat ambiguity only for files in blacklist
Advancing mtime by os.utime() fails for EPERM, if the target file is
owned by another. 0d920bcb0fd1 and related changes made some code
paths give advancing mtime up in such case, to fix issue5418.

This causes file stat ambiguity (again), if it is owned by another.

    https://www.mercurial-scm.org/wiki/ExactCacheValidationPlan

To avoid file stat ambiguity in such case, especially for
.hg/dirstate, c75c7b3e3284 made vfs.rename() copy the target file, and
advance mtime of renamed one again, if EPERM (see issue5584 for detail).

But straightforward "copy if EPERM" isn't reasonable for truncation of
append-only files at rollbacking, because rollbacking might cost much
for truncation of many filelogs, even though filelogs aren't
filecache-ed.

Therefore, this patch introduces blacklist "checkambigfiles", and
avoids file stat ambiguity only for files specified in this blacklist.

This patch consists of two parts below, which should be applied at
once in order to avoid regression.

  - specify 'checkambig=True' at vfs.open(mode='a') in _playback()
    according to checkambigfiles

  - invoke _playback() with checkambigfiles
    - add transaction.__init__() checkambigfiles argument, for _abort()
      - make localrepo instantiate transaction with _cachedfiles
    - add rollback() checkambigfiles argument, for "hg rollback/recover"
      - make localrepo invoke rollback() with _cachedfiles

After this patch, straightforward "copy if EPERM" will be reasonable
at closing the file opened with checkambig=True, because this policy
is applied only on files, which are listed in blacklist
"checkambigfiles".
2017-07-04 23:13:46 +09:00
FUJIWARA Katsunori
749a6e710f localrepo: store path and vfs location of cached properties
This information is used to make transaction handle these files
specially, in order to avoid file stat ambiguity of them.

Gathering information about cached files via annotation classes can
avoid overlooking properties newly introduced in the future.
2017-07-04 23:13:46 +09:00
Pierre-Yves David
c13c22104d auditor: add simple comment about repo.auditor and al
Every once in a while, I get confused by what these are. Let us add a comment.
2017-07-02 02:19:05 +02:00
Pierre-Yves David
8093995fed transaction: track new obsmarkers in the 'changes' mapping
The obsstore collaborate with transaction to make sure we track all the
obsmarkers added during a transaction. This will be useful for various usages:
hooks, caches, better output, etc.

This is the seconds kind of data added to tr.changes (first one was added revisions)
2017-06-27 02:45:09 +02:00
Pierre-Yves David
d708a01e9b configitems: register the 'format.usestore' config 2017-06-30 03:42:30 +02:00
Pierre-Yves David
ef58ebbe2d configitems: register the 'format.usefncache' config 2017-06-30 03:42:28 +02:00
Pierre-Yves David
66973f9ece configitems: register the 'format.dotencode' config 2017-06-30 03:42:22 +02:00
Pierre-Yves David
6f55ce8db4 configitems: register the 'format.aggressivemergedeltas' config 2017-06-30 03:42:20 +02:00
Pierre-Yves David
7c5463c25b revlog: add an experimental option to mitigated delta issues (issue5480)
The general delta heuristic to select a delta do not scale with the number of
branch. The delta base is frequently too far away to be able to reuse a chain
according to the "distance" criteria. This leads to insertion of larger delta (or
even full text) that themselves push the bases for the next delta further away
leading to more large deltas and full texts. This full text and frequent
recomputation throw Mercurial performance in disarray.

For example of a slightly large repository

  280 000 files (2 150 000 versions)
  430 000 changesets (10 000 topological heads)

Number below compares repository with and without the distance criteria:

manifest size:
    with:    21.4 GB
    without:  0.3 GB

store size:
    with:    28.7 GB
    without   7.4 GB

bundle last 15 00 revisions:
    with:    800 seconds
             971 MB
    without:  50 seconds
              73 MB

unbundle time (of the last 15K revisions):
    with:    1150 seconds (~19 minutes)
    without:   35 seconds

Similar issues has been observed in other repositories.


Adding a new option or "feature" on stable is uncommon. However, given that this
issues is making Mercurial practically unusable, I'm exceptionally targeting
this patch for stable.

What is actually needed is a full rework of the delta building and reading
logic. However, that will be a longer process and churn not suitable for stable.

In the meantime, we introduces a quick and dirty mitigation of this in the
'experimental' config space. The new option introduces a way to set the maximum
amount of memory usable to store a diff in memory. This extend the ability for
Mercurial to create chains without removing all safe guard regarding memory
access. The option should be phased out when core has a more proper solution
available.

Setting the limit to '0' remove all limits, setting it to '-1' use the default
limit (textsize x 4).
2017-06-23 13:49:34 +02:00
FUJIWARA Katsunori
0f2623ec07 localrepo: factor out base of filecache annotation class
It isn't needed that storecache is derived from repofilecache.

Changes in this patch allow repofilecache and storecache to do in own
__init__() differently from each other.
2017-06-30 01:47:49 +09:00
Pulkit Goyal
d1e9e38065 py3: use '%d' instead of '%s' for integers
Python 3 does not let you use '%s' for integers.
2017-06-17 14:53:25 +05:30
Martin von Zweigbergk
d75cb87451 localrepo: remove unused addchangegroup() (API)
This completes the cleanup started in f1b3c9ce0ce7 (localrepo: move
the addchangegroup method in changegroup module, 2014-04-01).
2017-06-15 15:13:18 -07:00
Siddharth Agarwal
f23bf55820 workingctx: add a way for extensions to run code at status fixup time
Some extensions like fsmonitor need to run code after dirstate.status is
called, but while the wlock is held. The extensions could grab the wlock again,
but that has its own peculiar race issues. For example, fsmonitor would not
like its state to be written out if the dirstate has changed underneath (see
issue5581 for what can go wrong in that sort of case).

To protect against these sorts of issues, allow extensions to declare that they
would like to run some code to run at fixup time.

fsmonitor will switch to using this in the next patch in the series.
2017-06-12 13:56:50 -07:00
Gregory Szorc
2c7b5a6b43 localrepo: move filtername to __init__
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.
2017-06-08 23:23:37 -07:00
Gregory Szorc
943d55015e obsolete: move obsstore creation logic from localrepo
This code has more to do with obsolete.py than localrepo.py. Let's
move it there.
2017-06-08 21:54:30 -07:00
Gregory Szorc
efbb740737 revlog: skeleton support for version 2 revlogs
There are a number of improvements we want to make to revlogs
that will require a new version - version 2. It is unclear what the
full set of improvements will be or when we'll be done with them.
What I do know is that the process will likely take longer than a
single release, will require input from various stakeholders to
evaluate changes, and will have many contentious debates and
bikeshedding.

It is unrealistic to develop revlog version 2 up front: there
are just too many uncertainties that we won't know until things
are implemented and experiments are run. Some changes will also
be invasive and prone to bit rot, so sitting on dozens of patches
is not practical.

This commit introduces skeleton support for version 2 revlogs in
a way that is flexible and not bound by backwards compatibility
concerns.

An experimental repo requirement for denoting revlog v2 has been
added. The requirement string has a sub-version component to it.
This will allow us to declare multiple requirements in the course
of developing revlog v2. Whenever we change the in-development
revlog v2 format, we can tweak the string, creating a new
requirement and locking out old clients. This will allow us to
make as many backwards incompatible changes and experiments to
revlog v2 as we want. In other words, we can land code and make
meaningful progress towards revlog v2 while still maintaining
extreme format flexibility up until the point we freeze the
format and remove the experimental labels.

To enable the new repo requirement, you must supply an experimental
and undocumented config option. But not just any boolean flag
will do: you need to explicitly use a value that no sane person
should ever type. This is an additional guard against enabling
revlog v2 on an installation it shouldn't be enabled on. The
specific scenario I'm trying to prevent is say a user with a
4.4 client with a frozen format enabling the option but then
downgrading to 4.3 and accidentally creating repos with an
outdated and unsupported repo format. Requiring a "challenge"
string should prevent this.

Because the format is not yet finalized and I don't want to take
any chances, revlog v2's version is currently 0xDEAD. I figure
squatting on a value we're likely never to use as an actual revlog
version to mean "internal testing only" is acceptable. And
"dead" is easily recognized as something meaningful.

There is a bunch of cleanup that is needed before work on revlog
v2 begins in earnest. I plan on doing that work once this patch
is accepted and we're comfortable with the idea of starting down
this path.
2017-05-19 20:29:11 -07:00
Yuya Nishihara
e6297851af localrepo: map integer and hex wdir identifiers to workingctx
changectx.__init__() is slightly modified to take str(wdirrev) as a valid
integer revision (and raise WdirUnsupported exception.)

Test will be added by the next patch.
2016-08-19 18:40:35 +09:00
Yuya Nishihara
75533e6603 localrepo: document that __contains__() may raise LookupError 2017-05-25 23:18:02 +09:00
Pierre-Yves David
c1ca9ad6ee transaction: run _writejournal unfiltered
The function use the length of the repository, something affected by filtering.
It seems better to use the unfiltered length here.

Credit for finding this goes to Durham Goode.
2017-05-25 01:45:52 +02:00
Augie Fackler
39eba5889f localrepo: extract bookmarkheads method to bookmarks.py
This method is only used internally by destutil, and it's obscure
enough I'm willing to just move it without a deprecation warning,
especially since the new method has more constrained functionality.

Design-wise I'd also like to get active bookmark handling folded into
the bookmark store, so that we don't squirrel away an extra attribute
for the active bookmark on the repository object.
2017-05-18 16:43:56 -04:00
Augie Fackler
33cedfa925 localrepo: mark walk convenience method as deprecated (API) 2017-05-18 18:01:48 -04:00
Augie Fackler
c46d888391 localrepo: migrate to context manager for changing dirstate parents 2017-05-18 17:11:14 -04:00
Pierre-Yves David
705173411e cache: make the cache updated callback easily accessible to extension
This will help extension to benefit from this new logic. As a side effect this
clarify the 'transaction' method a little bit.
2017-05-19 13:09:23 +02:00
Gregory Szorc
0d15165c74 localrepo: reformat set literals
Putting multiple elements on the same line makes diffs harder
to read. Switch to one line per element so future changes are
easier on the eyes.
2017-05-17 20:01:29 -07:00
Martin von Zweigbergk
3bc2187d25 match: remove ispartial()
The function was added in c2498bb6d298 (match: add match.ispartial(),
2015-05-15) for use by narrowhg, but narrowhg never ended up needing
it.
2017-05-17 09:43:50 -07:00
Gregory Szorc
ae8cb885e7 changelog: load pending file directly
When changelogs are written, a copy of the index (or inline revlog)
may be written to an 00changelog.i.a file to facilitate hooks and
other processes having access to the pending data before it is
finalized.

The way it works today, the localrepo class loads the changelog
like normal. Then, if it detects a pending transaction, it asks
the changelog class to load a pending changelog. The changelog
class looks for a 00changelog.i.a file. If it exists, it is
loaded and internal data structures on the new revlog class are
copied to the original instance.

The existing mechanism is inefficient because it loads 2 revlog
files. The index, node map, and chunk cache for 00changelog.i
are thrown away and replaced by those for 00changelog.i.a.

The existing mechanism is also brittle because it is a layering
violation to access the data structures being accessed. For example,
the code copies the "chunk cache" because for inline revlogs
this cache contains the raw revision chunks and allows the original
changelog/revlog instance to access revision data for these pending
revisions. This whole behavior of course relies on the revlog
constructor reading the entirety of an inline revlog into memory
and caching it. That's why it is brittle. (I discovered all this
as part of modifying behavior of the chunk cache.)

This patch streamlines the loading of a pending 00changelog.i.a
revlog by doing it directly in the changelog constructor if told
to do so. When this code path is active, we no longer load the
00changelog.i file at all.

The only negative outcome I see from this change is if loading
00changelog.i was somehow facilitating a role. But I can't imagine
what that would be because we throw away its data (the index data
structures are replaced and inline revision data is replaced via
the chunk cache) and since 00changelog.i.a is a copy of
00changelog.i, file content should be identical, so there should
be no meaninful file integrity checking at play. I think this was
all just sub-optimal code.
2017-05-13 16:26:43 -07:00
Martin von Zweigbergk
c3406ac3db cleanup: use set literals
We no longer support Python 2.6, so we can now use set literals.
2017-02-10 16:56:29 -08:00
Pierre-Yves David
9c635f53f5 caches: move the 'updating the branch cache' message in 'updatecaches'
We are about to remove the branchmap cache update in changegroup application.
There is a debug message alongside this update that we do not want to loose. We
move the message beforehand to simplify the test update in the next changeset.
The message move is quite noisy and isolating that noise is useful.

Most tests update are just line reordering since the message is issued at a
later point during the transaction.

After this changes, the message is displayed in more case since local commit
creation also issue it.
2017-05-02 22:27:44 +02:00
Pierre-Yves David
781ab337a0 caches: stop warming the cache after 'localrepo.commitctx'
Now that we garantee that branchmap cache are updated at the end of the
transaction we can drop that one. This removes a problematic case with nested
transaction where the new cache could be written on disk before the transaction
is finished.

The test change is harmless, since we update the cache at a later point, the
dirstate have been updated in between.
2017-05-02 18:56:07 +02:00
Pierre-Yves David
6b3c96d7ef caches: call 'repo.updatecache()' in 'repo.destroyed()'
Regenerating the cache after a 'strip' or a 'rollback' is useful. So we call the
generic cache warming function as other caches than just branchmap will be
updated there in the future.

To do so, we have to make 'repo.updatecache()' able to take no arguments. In
such cases, we reload all caches.
2017-05-02 19:05:58 +02:00
Pierre-Yves David
87c7f6f271 caches: introduce a function to warm cache
We have multiple caches that gain from being kept up to date. For example in a
server setup, we want to make sure the branchcache cache is hot for other
read-only clients.

Right now each cache tries to update themself in place where new data have been
added. However the approach is error prone (we might miss some spot) and
fragile. When nested transaction are involved, such cache updates might happen
before a top level transaction is committed. Writing caches for uncommitted
data on disk.

Having a single entry point, run at the end of each successful transaction,
helps to ensure the cache is up to date and refreshed at the right time.

We start with updating the branchmap cache but other will come.
2017-05-02 21:39:43 +02:00
Pierre-Yves David
a1a70e3fbc transaction: track newly introduced revisions
Tracking revisions is not the data that will unlock the most new capability.
However, they are the simplest thing to track and still unlock some nice
improvements in regard with caching.

We plug ourself at the changelog level to make sure we do not miss any revision
additions.

The 'revs' set is configured at the repository level because the transaction
itself does not needs to know that much about the business logic.
2017-05-02 18:45:51 +02:00
Martin von Zweigbergk
dfa0866489 localrepo: reuse exchange.bundle2requested()
It seems like localrepo.getbundle() is trying to do the same thing, so
let's just call the method. That way we get the same condition as
there (matching any "HG2" prefix, not only "HG20").
2017-05-03 10:33:26 -07:00
Pierre-Yves David
95ea84f11b cleanup: drop the deprecated 'localrepo._link' method
This was deprecated in favor of 'localrepo.wvfs.islink'. We can now drop it for the
future 4.3.
2017-05-02 02:05:39 +02:00
Pierre-Yves David
258c50d8f2 cleanup: drop the deprecated 'localrepo.wfile' method
This was deprecated in favor of 'localrepo.wvfs.join'. We can now drop it for the
future 4.3.
2017-05-02 02:04:55 +02:00
Pierre-Yves David
511036e5cd cleanup: drop the deprecated 'localrepo.join' method
This was deprecated in favor of 'localrepo.vfs.join'. We can now drop it for the
future 4.3.
2017-05-02 02:03:56 +02:00
Pierre-Yves David
18be67b624 cleanup: drop the deprecated 'localrepo.tag' method
This was deprecated in favor of 'mercurial.tags.tag'. We can now drop it for the
future 4.3.
2017-05-02 02:03:04 +02:00
Pierre-Yves David
a1ea2991e5 cleanup: drop the deprecated 'localrepo.opener' method
This was deprecated in favor of 'localrepo.vfs'. We can now drop it for the
future 4.3.
2017-05-02 02:01:47 +02:00
Pierre-Yves David
aa3d41a9fe cleanup: drop the deprecated 'localrepo.wopener' method
This was deprecated in favor of 'localrepo.wvfs'. We can now drop it for the
future 4.3.
2017-05-02 02:01:15 +02:00
Pierre-Yves David
53505593ab track-tags: write all tag changes to a file
The tag changes information we compute is now written to disk. This gives
hooks full access to that data.

The format picked for that file uses a 2 characters prefix for the action:

    -R: tag removed
    +A: tag added
    -M: tag moved (old value)
    +M: tag moved (new value)

This format allows hooks to easily select the line that matters to them without
having to post process the file too much. Here is a couple of examples:

 * to select all newly tagged changeset, match "^+",
 * to detect tag move, match "^.M",
 * to detect tag deletion, match "-R".

Once again we rely on the fact the tag tests run through all possible
situations to test this change.
2017-03-28 10:15:02 +02:00
Pierre-Yves David
cd08df0c89 track-tags: compute the actual differences between tags pre/post transaction
We now compute the proper actuall differences between tags before and after the
transaction. This catch a couple of false positives in the tests.

The compute the full difference since we are about to make this data available
to hooks in the next changeset.
2017-03-28 10:14:55 +02:00
Pierre-Yves David
ac782d2423 track-tags: introduce first bits of tags tracking during transaction
This changeset introduces detection of tags changes during transaction. When
this happens a 'tag_moved=1' argument is set for hooks, similar to what we do
for bookmarks and phases.

This code is disabled by default as there are still various performance
concerns.  Some require a smarter use of our existing tag caches and some other
require rework around the transaction logic to skip execution when unneeded.
These performance improvements have been delayed, I would like to be able to
experiment and stabilize the feature behavior first.

Later changesets will push the concept further and provide a way for hooks to
know what are the actual changes introduced by the transaction. Similar work
is needed for the other families of changes (bookmark, phase, obsolescence,
etc). Upgrade of the transaction logic will likely be performed at the same
time.

The current code can report some false positive when .hgtags file changes but
resulting tags are unchanged. This will be fixed in the next changeset.

For testing, we simply globally enable a hook in the tag test as all the
possible tag update cases should exist there. A couple of them show the false
positive mentioned above.

See in code documentation for more details.
2017-03-28 06:38:09 +02:00
Pierre-Yves David
8d44f66739 localrepo: fix deprecation version for 'repo._link'
The patch lingered for a while and nobody noticed when it was resubmitted.
2017-04-04 16:49:12 +02:00
Pierre-Yves David
630da1c31c localrepo: fix deprecation version for 'repo.join'
The patch lingered for a while and nobody noticed when it was resubmitted.
2017-04-04 16:48:58 +02:00
Pierre-Yves David
ef96a2bca6 tags: only return 'alltags' in 'findglobaltags'
This is minor update along the way. We simplify the 'findglobaltags' function to
only return the tags. Since no existing data is reused, we know that all tags
returned are global and we can let the caller get that information if it cares
about it.
2017-03-28 07:41:23 +02:00
Pierre-Yves David
8da79dae5a tags: do not feed dictionaries to 'findglobaltags'
The code asserts that these dictionary are empty. So we can be more explicit
and have the function return the dictionaries directly.
2017-03-28 06:13:49 +02:00
Pierre-Yves David
368236438f tags: deprecated 'repo.tag'
All user are gone. We can now celebrate the removal of some extra line from the
'localrepo' class.
2017-03-27 16:00:47 +02:00
Pierre-Yves David
8141af4eed tags: move 'repo.tag' in the 'tags' module
Similar logic, pretty much nobody use this method (that creates a tag) so we
move it into the 'tags' module were it belong.
2017-03-27 15:58:31 +02:00
Pierre-Yves David
f1cbb59e75 tags: move '_tags' from 'repo' to 'tags' module
As far as I understand, that function do not needs to be on the local repository
class, so we extract it in the 'tags' module were it will be nice and
comfortable. We keep the '_' in the name since its only user will follow in the
next changeset.
2017-03-27 15:55:07 +02:00
Ryan McElroy
372012a68d localrepo: use tryunlink 2017-03-21 06:50:28 -07:00
Ryan McElroy
2c2aec06d7 localrepo: improve vfs documentation
At the beginning of March, I promised Yuya that I would follow up a comment I
made on a patch with improved documention for these vfs objects. Also hat tip
to Pierre-Yves for adding the documentation here in the first place.
2017-03-21 06:50:42 -07:00
Augie Fackler
8e92fda6f8 localrepo: use node.hex instead of awkward .encode('latin1')
Spotted as an option by Yuya. Thanks!
2017-03-20 22:06:57 -04:00
Augie Fackler
18340f960e localrepo: forcibly copy list of filecache keys
On Python 3, keys() is more like iterkeys(), so we got in trouble for
mutating the dict while we're iterating here. Since the list of caches
should be relatively small, work around this difference by just
forcing a copy of the key list.
2017-03-19 01:11:00 -04:00
Augie Fackler
00cba0f12b localrepo: turn hook kwargs back into strs before calling hook
It might be better to ensure that the hook kwargs dict only has str
keys on Python 3. I'm torn.
2017-03-19 01:10:02 -04:00
Augie Fackler
092cc849d4 localrepo: ensure transaction id is fully bytes on py3 2017-03-19 01:08:59 -04:00
Gregory Szorc
5ca0f908bf py3: add __bool__ to every class defining __nonzero__
__nonzero__ was renamed to __bool__ in Python 3. This patch simply
aliases __bool__ to __nonzero__ for every class implementing
__nonzero__.
2017-03-13 12:40:14 -07:00
Pierre-Yves David
3248bb0252 localrepo: fix deprecation warning version of wfile
The patch lingered a bit too long in my local clone and I messed up when I
updated the version number. Since nobody caught it, I'm fixing the version after
the fact.
2017-03-16 11:17:55 -07:00
Pierre-Yves David
09a5f07adf localrepo: deprecated '_link'
That method had a total on 1 internal user...


G: changed mercurial/localrepo.py
2016-08-05 14:15:45 +02:00
Pierre-Yves David
2634c22ce0 localrepo: use self.wvfs.islink directly
We are about to deprecate the helper function.
2016-08-05 14:19:31 +02:00
Pierre-Yves David
0923ede90f localrepo: deprecate 'wfile'
The method had very few users and the modern form is shorter. So let us
deprecates another method of the localrepo class.
2017-03-15 00:27:17 -07:00
Pierre-Yves David
5fc4dd0997 localrepo: use 'wvfs' instead of 'wfile'
Method is about to be deprecated and the modern form is shorter.
2017-03-15 00:29:09 -07:00
Pierre-Yves David
2a46795ed1 localrepo: don't use mutable default argument value
Caught by pylint.
2017-03-14 23:50:07 -07:00
Pierre-Yves David
c6f71ed49c localrepo: deprecate 'repo.join' in favor of 'repo.vfs.join'
localrepo have an insane amount of method. Accessing the feature through the
vfs is not really harder and allow us to schedule that method for removal.
2016-08-05 14:09:04 +02:00
Pierre-Yves David
b71c55108c localrepo: directly use repo.vfs.join
The 'repo.join' method is about to be deprecated.
2016-08-05 14:29:22 +02:00
Pierre-Yves David
6a42754a35 repofilecache: directly use 'repo.vfs.join'
The 'vfs' attribute already have all methods we need, the value of going
through the repository for this is low. so we removes it.
2016-08-05 14:25:21 +02:00
Pierre-Yves David
010d9af7e1 repofilecache: define a 'join' method
We are about to turn the 'join' method of the base class Abstract, so we need
on to be defined in the localrepo. The ultimate goal here is to be able to stop
relying for the 'localrepo' class to have a 'join' methods (there is above one
hundred methods on 'localrepo'. This change make te 'repo' file cache have its
own code so that we can prepare this change to the repostory class.


explicite join
2016-08-05 14:23:58 +02:00
Jun Wu
c389ff2eb2 localrepo: rename proxycls to filteredrepo
When debugging in a Python shell, the type of "repo" is "proxycls", which
could confuse new people.

    In [1]: repo
    Out[1]: <mercurial.localrepo.proxycls at 0x7f65d4b976d0>

Let's rename it to "filteredrepo" to make it clearer.
2017-03-09 15:10:27 -08:00
Pierre-Yves David
718c1a120c vfs: use 'vfs' module directly in 'mercurial.localrepo'
Now that the 'vfs' classes moved in their own module, lets use the new module
directly. We update code iteratively to help with possible bisect needs in the
future.
2017-03-02 13:28:17 +01:00
Jun Wu
a2a0eb3ac0 localrepo: handle rename with hardlinks properly
In "aftertrans", we rename "journal.*" to "undo.*". We expect "journal.*"
files to disappear after renaming.

However, if "journal.foo" and "undo.foo" refer to a same file (hardlink),
rename may be a no-op, leaving both files on disk, according to Linux
manpage [1]:

    If oldpath and newpath are existing hard links referring to the same
    file, then rename() does nothing, and returns  a  suc‐ cess status.

The POSIX specification [2] is not very clear about what to do.

To be safe, remove "undo.*" before the rename so "journal.*" cannot be left
on disk.

[1]: http://man7.org/linux/man-pages/man2/rename.2.html
[2]: http://pubs.opengroup.org/onlinepubs/9699919799/
2017-03-02 21:49:30 -08:00
Pierre-Yves David
ded2ad613e localrepo: deprecate 'repo.opener' (API)
The "new" 'repo.vfs' attribute have been around for almost 5 years. I think we
can deprecate the old form now ;-)
2016-08-05 13:56:10 +02:00
Pierre-Yves David
232150945e localrepo: deprecated 'repo.wopener' (API)
The "new" 'repo.wvfs' attribute have been around for almost 5 years. I think we
can deprecate the old form now ;-)
2016-08-05 13:53:45 +02:00
Pierre-Yves David
ec73028c00 localrepo: add some comment about role of various vfs object
This should make things clearer for most people.
2016-08-05 13:49:05 +02:00
Dan Villiom Podlaski Christiansen
66c3976319 share: add --relative flag to store a relative path to the source
Storing a relative path the source repository is useful when exporting
repositories over the network or when they're located on external
drives where the mountpoint isn't always fixed.

Currently, Mercurial interprets paths in `.hg/shared` relative to
$PWD. I suspect this is very much unintentional, and you have to
manually edit `.hg/shared` in order to trigger this behaviour.

However, on the off chance that someone might rely on it, I added a
new capability called 'relshared'. In addition, this makes earlier
versions of Mercurial fail with a graceful error.

I should note that I haven't tested this patch on Windows.
2017-02-13 14:05:24 +01:00
Pierre-Yves David
86873414c1 color: initialize color for the localrepo ui
The 'ui' object dedicated to a 'localrepo' is independent from the one available
in dispatch (and 'uisetup'). In addition, it is created from the 'baseui'
(apparently for good reason). As a result, we need to run the color setup on
it after the local repository config is read.

This was overlooked when the rest of the initialization changed but did not
had impact yet because all setup is still global. We fix it before it is too
late.
2017-02-25 18:34:01 +01:00
FUJIWARA Katsunori
397d5cb0d7 localrepo: check HG_PENDING strictly
Before this patch, checking HG_PENDING for changelog in localrepo.py
might cause unintentional reading unrelated '00changelog.i.a' in,
because HG_PENDING is checked by str.startswith().

An external hook spawned by inner repository in nested ones satisfies
this condition.

This patch uses txnutil.mayhavepending() to check HG_PENDING strictly.

BTW, this patch may cause failure of bisect in the repository of
Mercurial itself, if examination at bisecting assumes that an external
hook can see all pending changes while nested transactions across
repositories.

This invisibility issue will be fixed by subsequent patch, which
allows HG_PENDING to refer multiple repositories.
2017-02-21 01:21:00 +09:00
Yuya Nishihara
8e1d6228ac scmutil: proxy revrange() through repo to break import cycles
This was one of the hardest import cycles as scmutil is widely used and
revset functions are likely to depend on a variety of modules.

New repo.anyrevs() does not expand user aliases by default to copy the
behavior of the existing repo.revs(). I don't want to add new function to
localrepository, but this function is quite similar to repo.revs() so it
won't increase the complexity of the localrepository class so much.
2017-02-19 20:00:18 +09:00
Yuya Nishihara
b2229f5117 revset: split language services to revsetlang module (API)
New revsetlang module hosts parser, tokenizer, and miscellaneous functions
working on parsed tree. It does not include functions for evaluation such as
getset() and match().

  2288 mercurial/revset.py
   684 mercurial/revsetlang.py
  2972 total

get*() functions are aliased since they are common in revset.py.
2017-02-19 18:19:33 +09:00
Jun Wu
1911496ecd localrepo: move extension loading to a separate method
The stateful chg plan [1] requires a special repo object, where ideally all
side effects caused by loading the repo object could be reverted by just
dropping (gabbage collect) the loaded repo object.

Currently, that is impossible because repo.__init__ calls
"extensions.loadall", which may have unpredictable side-effects that cannot
be reverted by dropping the repo object.

This patch moves "extensions.loadall" to a separate method, so chg could
subclass localrepository and make extensions loading a no-op.

[1]: mercurial-scm.org/pipermail/mercurial-devel/2017-February/092547.html
2017-02-15 19:41:14 -08:00
Stanislau Hlebik
fda8c9c688 localrepo: avoid unnecessary sorting
headrevs output already sorted, no need to sort it again.
2017-02-13 02:31:56 -08:00
Stanislau Hlebik
8671ff39e1 localrepo: cache self.changelog in local variable
Repeated self.changelog lookups can incur overhead. Let's cache it in the
separate variable.
2017-02-13 02:26:18 -08:00
Stanislau Hlebik
1ea3a2dcdf localrepo: avoid unnecessary conversion from node to rev
changelog.heads() first calls headrevs then converts them to nodes.
localrepo.heads() then sorts them using self.changelog.rev function and makes
useless conversion back to revs. Instead let's call changelog.headrevs() from
localrepo.heads(), sort the output and then convert to nodes. Because headrevs
does not support start parameter this optimization only works if start is None.
2017-02-02 02:56:38 -08:00
Gregory Szorc
765aada92f localrepo: experimental support for non-zlib revlog compression
The final part of integrating the compression manager APIs into
revlog storage is the plumbing for repositories to advertise they
are using non-zlib storage and for revlogs to instantiate a non-zlib
compression engine.

The main intent of the compression manager work was to zstd all
of the things. Adding zstd to revlogs has proved to be more involved
than other places because revlogs are... special. Very small inputs
and the use of delta chains (which are themselves a form of
compression) are a completely different use case from streaming
compression, which bundles and the wire protocol employ. I've
conducted numerous experiments with zstd in revlogs and have yet
to formalize compression settings and a storage architecture that
I'm confident I won't regret later. In other words, I'm not yet
ready to commit to a new mechanism for using zstd - or any other
compression format - in revlogs.

That being said, having some support for zstd (and other compression
formats) in revlogs in core is beneficial. It can allow others to
conduct experiments.

This patch introduces *highly experimental* support for non-zlib
compression formats in revlogs. Introduced is a config option to
control which compression engine to use. Also introduced is a namespace
of "exp-compression-*" requirements to denote support for non-zlib
compression in revlogs. I've prefixed the namespace with "exp-"
(short for "experimental") because I'm not confident of the
requirements "schema" and in no way want to give the illusion of
supporting these requirements in the future. I fully intend to drop
support for these requirements once we figure out what we're doing
with zstd in revlogs.

A good portion of the patch is teaching the requirements system
about registered compression engines and passing the requested
compression engine as an opener option so revlogs can instantiate
the proper compression engine for new operations.

That's a verbose way of saying "we can now use zstd in revlogs!"

On an `hg pull` conversion of the mozilla-unified repo with no extra
redelta settings (like aggressivemergedeltas), we can see the impact
of zstd vs zlib in revlogs:

$ hg perfrevlogchunks -c
! chunk
! wall 2.032052 comb 2.040000 user 1.990000 sys 0.050000 (best of 5)
! wall 1.866360 comb 1.860000 user 1.820000 sys 0.040000 (best of 6)

! chunk batch
! wall 1.877261 comb 1.870000 user 1.860000 sys 0.010000 (best of 6)
! wall 1.705410 comb 1.710000 user 1.690000 sys 0.020000 (best of 6)

$ hg perfrevlogchunks -m
! chunk
! wall 2.721427 comb 2.720000 user 2.640000 sys 0.080000 (best of 4)
! wall 2.035076 comb 2.030000 user 1.950000 sys 0.080000 (best of 5)

! chunk batch
! wall 2.614561 comb 2.620000 user 2.580000 sys 0.040000 (best of 4)
! wall 1.910252 comb 1.910000 user 1.880000 sys 0.030000 (best of 6)

$ hg perfrevlog -c -d 1
! wall 4.812885 comb 4.820000 user 4.800000 sys 0.020000 (best of 3)
! wall 4.699621 comb 4.710000 user 4.700000 sys 0.010000 (best of 3)

$ hg perfrevlog -m -d 1000
! wall 34.252800 comb 34.250000 user 33.730000 sys 0.520000 (best of 3)
! wall 24.094999 comb 24.090000 user 23.320000 sys 0.770000 (best of 3)

Only modest wins for the changelog. But manifest reading is
significantly faster. What's going on?

One reason might be data volume. zstd decompresses faster. So given
more bytes, it will put more distance between it and zlib.

Another reason is size. In the current design, zstd revlogs are
*larger*:

debugcreatestreamclonebundle (size in bytes)
zlib: 1,638,852,492
zstd: 1,680,601,332

I haven't investigated this fully, but I reckon a significant cause of
larger revlogs is that the zstd frame/header has more bytes than
zlib's. For very small inputs or data that doesn't compress well, we'll
tend to store more uncompressed chunks than with zlib (because the
compressed size isn't smaller than original). This will make revlog
reading faster because it is doing less decompression.

Moving on to bundle performance:

$ hg bundle -a -t none-v2 (total CPU time)
zlib: 102.79s
zstd:  97.75s

So, marginal CPU decrease for reading all chunks in all revlogs
(this is somewhat disappointing).

$ hg bundle -a -t <engine>-v2 (total CPU time)
zlib: 191.59s
zstd: 115.36s

This last test effectively measures the difference between zlib->zlib
and zstd->zstd for revlogs to bundle. This is a rough approximation of
what a server does during `hg clone`.

There are some promising results for zstd. But not enough for me to
feel comfortable advertising it to users. We'll get there...
2017-01-13 20:16:56 -08:00
Pulkit Goyal
f1c1938039 py3: replace os.environ with encoding.environ (part 1 of 5)
os.environ is a dictionary which has string elements on Python 3. We have
encoding.environ which take care of all these things. This is the first patch
of 5 patch series which tend to replace the occurences of os.environ with
encoding.environ as using os.environ will result in unusual behaviour.
2016-12-18 01:34:41 +05:30
Jun Wu
f9c05a235e localrepo: use ProgrammingError
This is an example usage of ProgrammingError. Let's start migrating
RuntimeError to ProgrammingError.

The code only runs when devel.all-warnings or devel.check-locks is set, so
it does not affect the end-user experience.
2016-12-06 17:06:39 +00:00
Pulkit Goyal
6e996c4d4c localrepository: remove None as default value of path argument in __init__()
The path variable in localrepository.__init__() has a default value None. So
it gives us a option to create an object to localrespository class without
path variable. But things break if you try to do so. The second line in the
init which will be executed when we try to create a localrepository object
will call os.path.expandvars(path) which returns

TypeError: argument of type 'NoneType' is not iterable

I checked occurrences when it is called and can't find any piece of code
which calls it without path variable. Also if something is calling it, its
should break.
2016-12-04 23:22:34 +05:30
Mateusz Kwapich
529860b433 localrepo: make it possible to reuse manifest when commiting context
This makes the commit function understand the context that's reusing manifest.
2016-11-17 10:59:15 -08:00
Augie Fackler
93eca45354 localrepo: refer to checkunresolved by its new name 2016-11-21 21:32:55 -05:00
Augie Fackler
fab0872f32 localrepo: refer to dirstateguard by its new name 2016-11-21 21:06:34 -05:00
Durham Goode
d2df1b3944 manifest: delete manifest.manifest class
Now that nothing uses the primary manifest class, we can delete it.
2016-11-10 02:13:19 -08:00
Durham Goode
ae274e1c50 localrepo: delete localrepo.manifest
Now that nothing uses normal manifests, we can delete localrepo.manifest.
2016-11-10 02:13:19 -08:00
Durham Goode
6fb7c00e4d manifest: remove manifest.add and add memmfctx.write
This removes one more dependency on the manifest class by moving the write
functionality onto the memmanifestctx classes and changing the one consumer to
use the new API.

By moving the write path to a manifestctx, we now give the individual manifests
control over how they're read and serialized. This will be useful in developing
new manifest formats and storage systems.
2016-11-08 08:03:43 -08:00
Mads Kiilerich
38cb771268 spelling: fixes of non-dictionary words 2016-10-17 23:16:55 +02:00
timeless
05cf1812b9 cmdutil: refactor checkunresolved
localrepo.commit had code to check for unresolved merge conflicts,
it would be helpful for at least rebase to be able to use that
code without calling commit().
2016-11-02 18:45:53 +00:00