Commit Graph

1093 Commits

Author SHA1 Message Date
Pierre-Yves David
dd7869713e pushkey: splits obsolete marker exchange into multiple keys
Obsolete markers are now exchanged in smaller pieces that fit in a http header.

This changes is done to avoid 400 bad request error when exchanging obsolete
puskey over http.

The last key pushed is always hold by the "dump0" key to ensure an easy place to
hook for people who need it.
2012-07-27 18:32:56 +02:00
Pierre-Yves David
44bf164af6 obsolete: add debug output regarding obsolete marker exchange. 2012-07-26 16:41:42 +02:00
Pierre-Yves David
a4bba98ab8 pushkey: add more verbose debug output regarding pushkey
Very few data are displayed now, making it hard to debug phases and obsolete
related issues.
2012-07-28 12:28:35 +02:00
Patrick Mezard
f40d444448 push: do not try to push remote obsolete if local has none 2012-07-24 21:20:56 +02:00
Patrick Mezard
7221d12e58 discovery: add extinct changesets to outgoing.excluded
Before this change, push would incorrectly fast-path the bundle
generation when extinct changesets are involved, because they are not
added to outgoing.excluded. The reason to do so are related to
outgoing.excluded being assumed to contain only secret changesets by
scmutil.nochangesfound(), when displaying warnings like:

 changes found (ignored 9 secret changesets)

Still, outgoing.excluded seems like a good API to report the extinct
changesets instead of dedicated code and nothing in the docstring
indicates it to be bound to secret changesets. This patch adds extinct
changesets to outgoing.excluded and fixes scmutil.nochangesfound() to
filter the excluded node list.

Original version and test by Pierre-Yves.David@ens-lyon.org
2012-07-25 19:34:31 +02:00
Pierre-Yves David
dab9cf6c01 _updatebranchcache: prevent deleting dict key during iteration
We use dict.keys() to fetch all keys before starting to delete some. Otherwise
python complains that the dictionnary is altered during iteration.
2012-07-17 16:16:17 +02:00
Pierre-Yves.David@ens-lyon.org
a82f344ba4 obsolete: mark unreachable extinct changesets as hidden
The repo.hiddenrevs set is updated with all extinct() changesets which aren't
descendants of either:

- the current working copy,
- a bookmark,
- a tag.
2012-07-16 17:56:50 +02:00
Pierre-Yves David
edc2b520d9 hidden: move hiddenrevs set on the repository
This set is always accessed through the repo for now. Having this set
carried by the changelog make it complicated to:

- initialize it, computing hidden set may involve revset call
- lazy compute it, (1) only the changelog can detect someone access it,
                   (2) only the repo have enought knowledge to compute it.

In later version I expect he changelog to apply filtering itself and the set to
be carried by changelog again.
2012-07-16 17:44:46 +02:00
Pierre-Yves David
afa28ff113 repo: move visibleheads and visiblebranchmap logic in discovery
They were previously inside the mercurial.phases module, but obsolete
logic will need them to exclude `extinct` changesets from pull and
push.

The proper and planned way to implement such filtering is still to apply a
changelog level filtering. But we are far to late in the cycle to implement and
push such a critical piece of code (changelog filtering). With Matt Mackall
approval I'm extending this quick and dirty mechanism for obsolete purpose.

Changelog level filtering should come during the next release cycle.
2012-07-17 01:22:31 +02:00
Pierre-Yves David
ae5abd69f4 localpeer: return only visible heads and branchmap
Now that we have localpeer, we can apply filtering on heads and branchmap the
same way it's done for wireprotocol peer.
2012-07-17 01:04:45 +02:00
Sune Foldager
e82027e6f3 peer: remove cancopy from peer api; use directly on repo instead 2012-07-13 21:52:37 +02:00
Sune Foldager
7045c35403 peer: introduce canpush and improve error message 2012-07-13 21:52:28 +02:00
Peter Arrenbrecht
ef7b77046e peer: introduce real peer classes
This change separates peer implementations from the repository implementation.
localpeer currently is a simple pass-through to localrepository, except for
legacy calls, which have already been removed from localpeer. This ensures that
the local client code only uses the most modern peer API when talking to local
repos.

Peers have a .local() method which returns either None or the underlying
localrepository (or descendant thereof). Repos have a .peer() method to return
a freshly constructed localpeer. The latter is used by hg.peer(), and also to
allow folks to pass either a peer or a repo to some generic helper methods.
We might want to get rid of .peer() eventually.

The only user of locallegacypeer is debugdiscovery, which uses it to pose as a
pre-setdiscovery client. But we decided to leave the old API defined in
locallegacypeer for clarity and maybe for other uses in the future.

It might be nice to actually define the peer API directly in peer.py as stub
methods. One problem there is, however, that localpeer implements
lock/addchangegroup, whereas the true remote peers implement unbundle.
It might be desireable to get rid of this distinction eventually.
2012-07-13 21:47:06 +02:00
Pierre-Yves David
9cbee4c2aa push: fix bug in detection of remote obsolete support
Current code check obsolete availability in local repo.
2012-07-12 03:03:19 +02:00
Pierre-Yves David
3f157ec6fb push: refuse to push unstable changesets without force
User should resolve unstability locally before pushing the same way we encourage
user to merge locally instead of pushing a new remote head.

If we are to push obsolete changeset, at least one set of the pushed set will be
either obsolete or unstable. The check is narrowed to only heads.
2012-07-10 01:39:03 +02:00
Pierre-Yves David
34e21f9d79 push: refuse to push obsolete changesets
This is a first version. Simple but not very efficient.

Note that this changeset introduce the "obsolete" word in the UI.
2012-07-10 01:32:18 +02:00
FUJIWARA Katsunori
64cae05faf localrepo: use file API via vfs while ensuring repository directory
As a part of migration to vfs, this patch invokes some file API
indirectly via vfs, while ensuring repository directory in the
constructor of "localrepository" class.

New file API are added to "scmutil.abstractopener" class, because they
are also used via other derived classes than "scmutil.opener".

But "join()" is not yet defined other than "scmutil.opener" class,
because it should not be used via other opener classes yet.
2012-07-06 18:45:27 +09:00
FUJIWARA Katsunori
1c926cc201 localrepo: use "vfs" intead of "opener" while ensuring repository directory
As a part of migration to vfs, this patch uses "self.vfs" instead of
"self.opener", while ensuring repository directory in the constructor
of "localrepository" class.
2012-07-06 18:45:27 +09:00
FUJIWARA Katsunori
204c7d4046 localrepo: use the path relative to "self.vfs" instead of "path" argument
As a part of migration to vfs, this patch uses "self.root", which can
be recognized as the path relative to "self.vfs", instead of "path"
argument.

This fix allows to make invocations of "util.makedirs()" and
"os.path.exists()" while ensuring repository directory in
"localrepository.__init__()" ones indirectly via vfs.

But this fix also raises issue 2528: "hg clone" with empty destination.

"path" argument is empty in many cases, so this issue can't be fixed
in the view of "localrepository.__init__()".

Before this patch, it is fixed by empty-ness check ("not name") of
exception handler in "util.makedirs()".

    try:
        os.mkdir(name)
    except OSError, err:
        if err.errno == errno.EEXIST:
            return
        if err.errno != errno.ENOENT or not name:
            raise

This requires "localrepository.__init__()" to invoke "util.makedirs()"
with "path" instead of "self.root", because empty "path" is treated as
"current directory" and "self.root" becomes valid path.

But "hg clone" with empty destination can be detected also in
"hg.clone()" before "localrepository.__init__()" invocation, so this
patch re-fixes issue2528 by checking it in "hg.clone()".
2012-07-06 18:45:27 +09:00
FUJIWARA Katsunori
765d4328c8 localrepo: use "self.wvfs.join()" instead of "os.path.join()"
As a part of migration to vfs, this patch uses "self.wvfs.join()"
instead of "os.path.join()", while initialization of fields in the
constructor of "localrepository" class.
2012-07-06 18:45:27 +09:00
FUJIWARA Katsunori
d20072de6a localrepo: use path expansion API via vfs
As a part of migration to vfs, this patch moves path expansion API
invocations in the constructor of "localrepository" to the constructor
of "opener", because the root path to the repository is very important
to handle paths using non-ASCII characters correctly.

This patch also rearrange initialization order of "wvfs" field,
because it is required to initialize "self.root".
2012-07-06 18:45:27 +09:00
FUJIWARA Katsunori
dad1f854dd localrepo: add "vfs" fields to "localrepository" for migration from "opener"
As a part of migration to vfs, this patch adds "vfs" fields to
"localrepository" class.

This allows new codes to access current "opener" objects related to
repositories via "vfs" fields, so patches referring to "vfs" will
replace referring to "opener" in time.

This patch also adds initializations for "vfs" fields to
"statichttprepository" class derived from it, because its constructor
doesn't invoke the constructor of "localrepository", so "vfs" fields
should be initialized explicitly as same as "opener" fields: it has no
working directory, so "wvfs" field is not added.
2012-07-06 18:45:26 +09:00
Martin Geisler
c52341ae3f merge with main 2012-07-12 10:03:50 +02:00
Bryan O'Sullivan
f9d692c823 localrepo: make requirements and openerreqs mutable by subclasses
This is necessary for extensions that need to modify a repo's
requirements.
2012-07-11 15:36:00 -07:00
Pierre-Yves David
100b68ca2e obsolete: write obsolete marker inside a transaction
Marker are now written as soon as possible but within a transaction. Using a
transaction ensure a proper behavior on error and rollback compatibility.

Flush logic are not necessary anymore and are dropped from lock release.

With this changeset, the obsstore is open, written and closed for every single
added marker. This is expected to be highly inefficient and batched write should
be implemented "quickly".

Another issue is that every flush of the file will invalidate the obsstore
filecache and trigger a full re instantiation of the repo.obsstore attribute
(including, reading and parsing entry). This is also expected to be highly
inefficient and proper filecache operation should be implemented "quickly" too.

A side benefit of the filecache issue is that repo.obsstore  object is properly
invalidated on transaction abortion.
2012-07-04 02:21:04 +02:00
Pierre-Yves David
587d4505e1 obsolete: append new markers to obsstore file instead of rewriting everything
This is the second step toward incremental writing of marker inside a
transaction. The obsstore file is now handled append only.

Header writing have been extracted from _writemarkers.

Because the _writemarkers method have been dropped, the push code
directly reuse the serialised content of local repo `listkeys`. This
is not very pretty, but this part of the protocol still need major
improvement anyway.
2012-07-04 02:02:48 +02:00
Pierre-Yves David
3fa4ff72f7 obsolete: move obsolete markers read/write logic to obsstore object
This is the first step toward incremental writing of obsolete marker within a
transaction.

For this purpose, obsstore is now given its repo sopener. This make it able to
handles read and write to the obsstore file itself. Most IO logic is removed
from localrepo and handled by obsstore object directly.
2012-07-04 02:00:36 +02:00
Pierre-Yves.David@ens-lyon.org
d60eedc2d6 obsolete: exchange obsolete marker over pushkey
For a version of the exchange, all markers are exchange. This won't
scale and we will need a better protocol later.
2012-06-07 19:21:59 +02:00
Pierre-Yves.David@ens-lyon.org
f9dd15112c obsolete: introduction of obsolete markers
Markers are stored as binary records in a log structured file in
.hg/store/obsstore.
2012-06-07 19:07:39 +02:00
Joshua Redstone
fe77ca6b46 strip: incrementally update the branchheads cache after a strip
This function augments strip to incrementally update the branchheads cache
rather than recompute it from scratch.  This speeds up the performance of strip
and rebase on repos with long history.  The performance optimization only
happens if the revisions stripped are all on the same branch and the parents of
the stripped revisions are also on that same branch.

This adds a few test cases, particularly one that reproduces the extra heads
that mpm observed.
2012-05-18 12:45:47 -07:00
Joshua Redstone
8395f62c2f localrepo: convert _updatebranchcache from nodespace to revspace
_updatebranchcache used to use revlog.reachable.  After the switch to
revlog.ancestors, we can now clean it up a bit and switch the algorithm from
nodes to revs.
2012-06-01 08:56:17 -07:00
Joshua Redstone
09130c5cf2 revlog: remove reachable and switch call sites to ancestors
This change does a trivial conversion of callsites to ancestors.
Followon diffs will switch the callsites over to revs.
2012-06-08 08:39:44 -07:00
Martin Geisler
9b2274c69f localrepo: lowercase "unexpected response" message 2012-06-12 14:18:18 +02:00
Bryan O'Sullivan
6ba97b40c1 revlog: ancestors(*revs) becomes ancestors(revs) (API)
Accepting a variable number of arguments as the old API did is
deeply ugly, particularly as it means the API can't be extended
with new arguments.  Partly as a result, we have at least three
different implementations of the same ancestors algorithm (!?).

Most callers were forced to call ancestors(*somelist), adding to
both inefficiency and ugliness.
2012-06-01 12:37:18 -07:00
Matt Mackall
6c79e00693 localrepo: move filecache clearing into invalidate
Moving from self.destroy to _rollback fixed rollback fixed rollback
but broke mq. Move it lower rather than sideways.
2012-06-01 23:44:10 -05:00
Matt Mackall
da90115a02 merge with stable 2012-06-01 15:14:29 -05:00
Idan Kamara
6259990e39 localrepo: clear _filecache earlier to really force reloading (issue3462)
b67b333b0d8a attempted to force the filecaches in localrepo to reload
everything after a rollback. But simply clearing _filecache isn't enough,
invalidate() needs to be called before/after. localrepo._rollback calls
invalidate() already, so we clear the map right afterwards which ensures
everything will be reread.
2012-05-29 18:27:12 +03:00
Augie Fackler
e8eca68a89 clone: add progress calls to uncompressed code path 2012-05-21 14:25:46 -05:00
Matt Mackall
7e8d9b6e6f branchcache: backout 29529231e17d 2012-05-17 15:34:59 -05:00
Brodie Rao
ab32f1721d context: add changectx.closesbranch() method
This removes the duplicated code for inspecting the 'close' extra field in
a changeset.
2012-05-13 14:04:06 +02:00
Brodie Rao
d36ae7f264 localrepo: add branchtip() method for faster single-branch lookups
For the PyPy repo with 744 branches and 843 branch heads, this brings
hg log -r default over NFS from:

   CallCount    Recursive    Total(ms)   Inline(ms) module:lineno(function)
        3249            0      1.3222      1.3222   <open>
        3244            0      0.6211      0.6211   <method 'close' of 'file' objects>
        3243            0      0.0800      0.0800   <method 'read' of 'file' objects>
        3241            0      0.0660      0.0660   <method 'seek' of 'file' objects>
        3905            0      0.0476      0.0476   <zlib.decompress>
        3281            0      2.6756      0.0472   mercurial.changelog:182(read)
       +3281            0      2.5256      0.0453   +mercurial.revlog:881(revision)
       +3276            0      0.0389      0.0196   +mercurial.changelog:28(decodeextra)
       +6562            0      0.0123      0.0123   +<method 'split' of 'str' objects>
       +6562            0      0.0408      0.0073   +mercurial.encoding:61(tolocal)
       +3281            0      0.0054      0.0054   +<method 'index' of 'str' objects>
        3241            0      2.2464      0.0456   mercurial.revlog:818(_loadchunk)
       +3241            0      0.6205      0.6205   +<method 'close' of 'file' objects>
       +3241            0      0.0765      0.0765   +<method 'read' of 'file' objects>
       +3241            0      0.0660      0.0660   +<method 'seek' of 'file' objects>
       +3241            0      1.4209      0.0135   +mercurial.store:374(__call__)
       +3241            0      0.0122      0.0107   +mercurial.revlog:810(_addchunk)
        3281            0      2.5256      0.0453   mercurial.revlog:881(revision)
       +3280            0      0.0175      0.0175   +mercurial.revlog:305(rev)
       +3281            0      2.2819      0.0119   +mercurial.revlog:847(_chunkraw)
       +3281            0      0.0603      0.0083   +mercurial.revlog:945(_checkhash)
       +3281            0      0.0051      0.0051   +mercurial.revlog:349(flags)
       +3281            0      0.0040      0.0040   +<mercurial.mpatch.patches>
       13682            0      0.0479      0.0248   <method 'decode' of 'str' objects>
       +7418            0      0.0228      0.0076   +encodings.utf_8:15(decode)
          +1            0      0.0003      0.0000   +encodings:71(search_function)
        3248            0      1.3995      0.0246   mercurial.scmutil:218(__call__)
       +3248            0      1.3222      1.3222   +<open>
       +3248            0      0.0235      0.0184   +os.path:80(split)
       +3248            0      0.0084      0.0068   +mercurial.scmutil:92(__call__)
Time: real 2.750 secs (user 0.680+0.000 sys 0.360+0.000)

down to:

   CallCount    Recursive    Total(ms)   Inline(ms) module:lineno(function)
          55           31      0.0197      0.0163   <__import__>
          +1            0      0.0006      0.0002   +mercurial.context:8(<module>)
          +1            0      0.0042      0.0001   +mercurial.revlog:12(<module>)
          +1            0      0.0002      0.0001   +mercurial.match:8(<module>)
          +1            0      0.0003      0.0001   +mercurial.dirstate:7(<module>)
          +1            0      0.0057      0.0001   +mercurial.changelog:8(<module>)
           1            0      0.0117      0.0032   mercurial.localrepo:525(_readbranchcache)
        +844            0      0.0015      0.0015   +<binascii.unhexlify>
        +845            0      0.0010      0.0010   +<method 'split' of 'str' objects>
        +843            0      0.0045      0.0009   +mercurial.encoding:61(tolocal)
        +843            0      0.0004      0.0004   +<method 'setdefault' of 'dict' objects>
          +1            0      0.0003      0.0003   +<method 'close' of 'file' objects>
           3            0      0.0029      0.0029   <method 'read' of 'file' objects>
           9            0      0.0018      0.0018   <open>
         990            0      0.0017      0.0017   <binascii.unhexlify>
          53            0      0.0016      0.0016   mercurial.demandimport:43(__init__)
         862            0      0.0015      0.0015   <_codecs.utf_8_decode>
         862            0      0.0037      0.0014   <method 'decode' of 'str' objects>
        +862            0      0.0023      0.0008   +encodings.utf_8:15(decode)
         981            0      0.0011      0.0011   <method 'split' of 'str' objects>
         861            0      0.0046      0.0009   mercurial.encoding:61(tolocal)
        +861            0      0.0037      0.0014   +<method 'decode' of 'str' objects>
         862            0      0.0023      0.0008   encodings.utf_8:15(decode)
        +862            0      0.0015      0.0015   +<_codecs.utf_8_decode>
           4            0      0.0008      0.0008   <method 'close' of 'file' objects>
         179          154      0.0202      0.0004   mercurial.demandimport:83(__getattribute__)
         +36           11      0.0199      0.0003   +mercurial.demandimport:55(_load)
         +72            0      0.0001      0.0001   +mercurial.demandimport:83(__getattribute__)
         +36            0      0.0000      0.0000   +<getattr>
           1            0      0.0015      0.0004   mercurial.tags:148(_readtagcache)
Time: real 0.060 secs (user 0.030+0.000 sys 0.010+0.000)
2012-05-13 14:04:04 +02:00
Joshua Redstone
d70249edef localrepo: strip now incrementally updates the branchheads cache
Destroying history via strip used to invalidate the branchheads cache,
causing it to be regenerated the next time it is read. This is
expensive in large repos. This change converts strip to pass info to
localrepo.destroyed() to enable to it to incrementally update the
cache, improving the performance of strip and other operations that
depend on it (e.g., rebase).

This change also strengthens a bit the integrity checking of the
branchheads cache when it is read, by rejecting the cache if it has
nodes in it that no longer exist.
2012-05-11 10:35:54 -07:00
David Soria Parra
2ce902d434 localrepo: introduce bookmarkheads
Similar to branch heads we introduce the notion of bookmarkheads.
Bookmarkheads are changests that are bookmarked with the given bookmark
or a diverged version
2012-05-13 11:54:58 +02:00
David Soria Parra
7ffe2b2eb4 bookmarks: delete divergent bookmarks on merge 2012-05-12 21:28:10 +02:00
Brodie Rao
7f47d4e347 check-code: ignore naked excepts with a "re-raise" comment
This also promotes the naked except check from a warning to an error.
2012-05-13 13:18:06 +02:00
Matt Mackall
05e48d4041 merge with stable 2012-05-13 12:52:24 +02:00
Brodie Rao
d6a6abf2b0 cleanup: eradicate long lines 2012-05-12 15:54:54 +02:00
Patrick Mezard
641ee7d3ba phases: introduce phasecache
The original motivation was changectx.phase() had special logic to
correctly lookup in repo._phaserev, including invalidating it when
necessary. And at other places, repo._phaserev was accessed directly.

This led to the discovery that phases state including _phaseroots,
_phaserev and _dirtyphase was manipulated in localrepository.py,
phases.py, repair.py, etc. phasecache helps encapsulating that.

This patch replaces all phase state in localrepo with phasecache and
adjust related code except for advance/retractboundary() in phases.
These still access to phasecache internals directly. This will be
addressed in a followup.
2012-05-12 00:24:07 +02:00
Jesse Glick
a1ec63bdbc localrepo: optimize internode status calls using withflags
Introduce manifestdict.withflags() to get a set of all files which have any
flags set, since these are likely to be a minority. Otherwise checking .flags()
for every file is a lot of dictionary lookups and is quite slow.
2012-05-04 15:56:45 -04:00
Jesse Glick
17675847fa localrepo: optimize internode status calls using match.always
Introduce match.always() to check if a match object always says yes, i.e.
None was passed in. If so, mfmatches should not bother iterating every file in
the repository.
2012-05-04 15:54:55 -04:00