Mercurial > hg
annotate mercurial/repoview.py @ 26755:bb0b955d050d
streamclone: support for producing and consuming stream clone bundles
Up to this point, stream clones only existed as a dynamically generated
data format produced and consumed during streaming clones. In order to
support this efficient cloning format with the clone bundles feature, we
need a more formal, on disk representation of the streaming clone data.
This patch introduces a new "bundle" type for streaming clones. Unlike
existing bundles, it does not contain changegroup data. It does,
however, share the same concepts like the 4 byte header which identifies
the type of data that follows and the 2 byte abbreviation for
compression types (of which only "UN" is currently supported).
The new bundle format is essentially the existing stream clone version 1
data format with some headers at the beginning.
Content negotiation at stream clone request time checked for repository
format/requirements compatibility before initiating a stream clone. We
can't do active content negotiation when using clone bundles. So, we put
this set of requirements inside the payload so consumers have a built-in
mechanism for checking compatibility before reading and applying lots of
data. Of course, we will also advertise this requirements set in clone
bundles. But that's for another patch.
We currently don't have a mechanism to produce and consume this new
bundle format. This will be implemented in upcoming patches.
It's worth noting that if a legacy client attempts to `hg unbundle` a
stream clone bundle (with the "HGS1" header), it will abort with:
"unknown bundle version S1," which seems appropriate.
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Sat, 17 Oct 2015 11:14:52 -0700 |
parents | f279191124f3 |
children | 49a76d3d43b1 |
rev | line source |
---|---|
18100
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
1 # repoview.py - Filtered view of a localrepo object |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
2 # |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
3 # Copyright 2012 Pierre-Yves David <pierre-yves.david@ens-lyon.org> |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
4 # Logilab SA <contact@logilab.fr> |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
5 # |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
6 # This software may be used and distributed according to the terms of the |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
7 # GNU General Public License version 2 or any later version. |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
8 |
25972
f279191124f3
repoview: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25149
diff
changeset
|
9 from __future__ import absolute_import |
f279191124f3
repoview: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25149
diff
changeset
|
10 |
18100
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
11 import copy |
25972
f279191124f3
repoview: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25149
diff
changeset
|
12 import heapq |
22150
45b5cd948a4d
repoview: add caching bits
David Soria Parra <davidsp@fb.com>
parents:
22149
diff
changeset
|
13 import struct |
25972
f279191124f3
repoview: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25149
diff
changeset
|
14 |
f279191124f3
repoview: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25149
diff
changeset
|
15 from .node import nullrev |
f279191124f3
repoview: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25149
diff
changeset
|
16 from . import ( |
f279191124f3
repoview: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25149
diff
changeset
|
17 error, |
f279191124f3
repoview: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25149
diff
changeset
|
18 obsolete, |
f279191124f3
repoview: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25149
diff
changeset
|
19 phases, |
f279191124f3
repoview: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25149
diff
changeset
|
20 tags as tagsmod, |
f279191124f3
repoview: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25149
diff
changeset
|
21 util, |
f279191124f3
repoview: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25149
diff
changeset
|
22 ) |
18242
e4687edec014
clfilter: introduces a hidden filter
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18233
diff
changeset
|
23 |
18293
1f35d6737ed8
repoview: extract hideable revision computation in a dedicated function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18274
diff
changeset
|
24 def hideablerevs(repo): |
1f35d6737ed8
repoview: extract hideable revision computation in a dedicated function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18274
diff
changeset
|
25 """Revisions candidates to be hidden |
1f35d6737ed8
repoview: extract hideable revision computation in a dedicated function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18274
diff
changeset
|
26 |
1f35d6737ed8
repoview: extract hideable revision computation in a dedicated function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18274
diff
changeset
|
27 This is a standalone function to help extensions to wrap it.""" |
1f35d6737ed8
repoview: extract hideable revision computation in a dedicated function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18274
diff
changeset
|
28 return obsolete.getrevs(repo, 'obsolete') |
1f35d6737ed8
repoview: extract hideable revision computation in a dedicated function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18274
diff
changeset
|
29 |
24565
2f7cb6e6acdd
repoview: improve compute staticblockers perf
Durham Goode <durham@fb.com>
parents:
24154
diff
changeset
|
30 def _getstatichidden(repo): |
24615
9e558b788daa
repoview: update documentation of _getstatichidden
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
24565
diff
changeset
|
31 """Revision to be hidden (disregarding dynamic blocker) |
20940
b0822c23e80a
repoview: add _gethiddenblockers method
Sean Farley <sean.michael.farley@gmail.com>
parents:
20939
diff
changeset
|
32 |
24615
9e558b788daa
repoview: update documentation of _getstatichidden
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
24565
diff
changeset
|
33 To keep a consistent graph, we cannot hide any revisions with |
9e558b788daa
repoview: update documentation of _getstatichidden
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
24565
diff
changeset
|
34 non-hidden descendants. This function computes the set of |
9e558b788daa
repoview: update documentation of _getstatichidden
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
24565
diff
changeset
|
35 revisions that could be hidden while keeping the graph consistent. |
9e558b788daa
repoview: update documentation of _getstatichidden
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
24565
diff
changeset
|
36 |
9e558b788daa
repoview: update documentation of _getstatichidden
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
24565
diff
changeset
|
37 A second pass will be done to apply "dynamic blocker" like bookmarks or |
9e558b788daa
repoview: update documentation of _getstatichidden
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
24565
diff
changeset
|
38 working directory parents. |
9e558b788daa
repoview: update documentation of _getstatichidden
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
24565
diff
changeset
|
39 |
9e558b788daa
repoview: update documentation of _getstatichidden
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
24565
diff
changeset
|
40 """ |
20940
b0822c23e80a
repoview: add _gethiddenblockers method
Sean Farley <sean.michael.farley@gmail.com>
parents:
20939
diff
changeset
|
41 assert not repo.changelog.filteredrevs |
24617
f76595f6ed7c
repoview: simplify process in _getstatichidden
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
24616
diff
changeset
|
42 hidden = set(hideablerevs(repo)) |
f76595f6ed7c
repoview: simplify process in _getstatichidden
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
24616
diff
changeset
|
43 if hidden: |
24565
2f7cb6e6acdd
repoview: improve compute staticblockers perf
Durham Goode <durham@fb.com>
parents:
24154
diff
changeset
|
44 getphase = repo._phasecache.phase |
2f7cb6e6acdd
repoview: improve compute staticblockers perf
Durham Goode <durham@fb.com>
parents:
24154
diff
changeset
|
45 getparentrevs = repo.changelog.parentrevs |
24618
cde57a8d8fe7
repoview: directly skip public head in _getstatichidden
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
24617
diff
changeset
|
46 # Skip heads which are public (guaranteed to not be hidden) |
cde57a8d8fe7
repoview: directly skip public head in _getstatichidden
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
24617
diff
changeset
|
47 heap = [-r for r in repo.changelog.headrevs() if getphase(repo, r)] |
24616
72d34c5a6614
repoview: use a heap in _getstatichidden
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
24615
diff
changeset
|
48 heapq.heapify(heap) |
72d34c5a6614
repoview: use a heap in _getstatichidden
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
24615
diff
changeset
|
49 heappop = heapq.heappop |
72d34c5a6614
repoview: use a heap in _getstatichidden
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
24615
diff
changeset
|
50 heappush = heapq.heappush |
24620
7c6f9097e2e0
repoview: avoid processing the same rev twice in _getstatichidden
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
24619
diff
changeset
|
51 seen = set() # no need to init it with heads, they have no children |
24616
72d34c5a6614
repoview: use a heap in _getstatichidden
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
24615
diff
changeset
|
52 while heap: |
24617
f76595f6ed7c
repoview: simplify process in _getstatichidden
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
24616
diff
changeset
|
53 rev = -heappop(heap) |
f76595f6ed7c
repoview: simplify process in _getstatichidden
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
24616
diff
changeset
|
54 # All children have been processed so at that point, if no children |
f76595f6ed7c
repoview: simplify process in _getstatichidden
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
24616
diff
changeset
|
55 # removed 'rev' from the 'hidden' set, 'rev' is going to be hidden. |
f76595f6ed7c
repoview: simplify process in _getstatichidden
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
24616
diff
changeset
|
56 blocker = rev not in hidden |
f76595f6ed7c
repoview: simplify process in _getstatichidden
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
24616
diff
changeset
|
57 for parent in getparentrevs(rev): |
f76595f6ed7c
repoview: simplify process in _getstatichidden
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
24616
diff
changeset
|
58 if parent == nullrev: |
f76595f6ed7c
repoview: simplify process in _getstatichidden
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
24616
diff
changeset
|
59 continue |
f76595f6ed7c
repoview: simplify process in _getstatichidden
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
24616
diff
changeset
|
60 if blocker: |
f76595f6ed7c
repoview: simplify process in _getstatichidden
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
24616
diff
changeset
|
61 # If visible, ensure parent will be visible too |
f76595f6ed7c
repoview: simplify process in _getstatichidden
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
24616
diff
changeset
|
62 hidden.discard(parent) |
24620
7c6f9097e2e0
repoview: avoid processing the same rev twice in _getstatichidden
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
24619
diff
changeset
|
63 # - Avoid adding the same revision twice |
7c6f9097e2e0
repoview: avoid processing the same rev twice in _getstatichidden
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
24619
diff
changeset
|
64 # - Skip nodes which are public (guaranteed to not be hidden) |
7c6f9097e2e0
repoview: avoid processing the same rev twice in _getstatichidden
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
24619
diff
changeset
|
65 pre = len(seen) |
7c6f9097e2e0
repoview: avoid processing the same rev twice in _getstatichidden
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
24619
diff
changeset
|
66 seen.add(parent) |
7c6f9097e2e0
repoview: avoid processing the same rev twice in _getstatichidden
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
24619
diff
changeset
|
67 if pre < len(seen) and getphase(repo, rev): |
24619
ad6dea5d96f2
repoview: skip public parent earlier in _getstatichidden
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
24618
diff
changeset
|
68 heappush(heap, -parent) |
24617
f76595f6ed7c
repoview: simplify process in _getstatichidden
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
24616
diff
changeset
|
69 return hidden |
22149
16ef2c485f03
repoview: split _gethiddenblockers
David Soria Parra <davidsp@fb.com>
parents:
22148
diff
changeset
|
70 |
16ef2c485f03
repoview: split _gethiddenblockers
David Soria Parra <davidsp@fb.com>
parents:
22148
diff
changeset
|
71 def _getdynamicblockers(repo): |
16ef2c485f03
repoview: split _gethiddenblockers
David Soria Parra <davidsp@fb.com>
parents:
22148
diff
changeset
|
72 """Non-cacheable revisions blocking hidden changesets from being filtered. |
16ef2c485f03
repoview: split _gethiddenblockers
David Soria Parra <davidsp@fb.com>
parents:
22148
diff
changeset
|
73 |
16ef2c485f03
repoview: split _gethiddenblockers
David Soria Parra <davidsp@fb.com>
parents:
22148
diff
changeset
|
74 Get revisions that will block hidden changesets and are likely to change, |
16ef2c485f03
repoview: split _gethiddenblockers
David Soria Parra <davidsp@fb.com>
parents:
22148
diff
changeset
|
75 but unlikely to create hidden blockers. They won't be cached, so be careful |
16ef2c485f03
repoview: split _gethiddenblockers
David Soria Parra <davidsp@fb.com>
parents:
22148
diff
changeset
|
76 with adding additional computation.""" |
16ef2c485f03
repoview: split _gethiddenblockers
David Soria Parra <davidsp@fb.com>
parents:
22148
diff
changeset
|
77 |
16ef2c485f03
repoview: split _gethiddenblockers
David Soria Parra <davidsp@fb.com>
parents:
22148
diff
changeset
|
78 cl = repo.changelog |
16ef2c485f03
repoview: split _gethiddenblockers
David Soria Parra <davidsp@fb.com>
parents:
22148
diff
changeset
|
79 blockers = set() |
16ef2c485f03
repoview: split _gethiddenblockers
David Soria Parra <davidsp@fb.com>
parents:
22148
diff
changeset
|
80 blockers.update([par.rev() for par in repo[None].parents()]) |
16ef2c485f03
repoview: split _gethiddenblockers
David Soria Parra <davidsp@fb.com>
parents:
22148
diff
changeset
|
81 blockers.update([cl.rev(bm) for bm in repo._bookmarks.values()]) |
16ef2c485f03
repoview: split _gethiddenblockers
David Soria Parra <davidsp@fb.com>
parents:
22148
diff
changeset
|
82 |
16ef2c485f03
repoview: split _gethiddenblockers
David Soria Parra <davidsp@fb.com>
parents:
22148
diff
changeset
|
83 tags = {} |
16ef2c485f03
repoview: split _gethiddenblockers
David Soria Parra <davidsp@fb.com>
parents:
22148
diff
changeset
|
84 tagsmod.readlocaltags(repo.ui, repo, tags, {}) |
16ef2c485f03
repoview: split _gethiddenblockers
David Soria Parra <davidsp@fb.com>
parents:
22148
diff
changeset
|
85 if tags: |
16ef2c485f03
repoview: split _gethiddenblockers
David Soria Parra <davidsp@fb.com>
parents:
22148
diff
changeset
|
86 rev, nodemap = cl.rev, cl.nodemap |
16ef2c485f03
repoview: split _gethiddenblockers
David Soria Parra <davidsp@fb.com>
parents:
22148
diff
changeset
|
87 blockers.update(rev(t[0]) for t in tags.values() if t[0] in nodemap) |
20940
b0822c23e80a
repoview: add _gethiddenblockers method
Sean Farley <sean.michael.farley@gmail.com>
parents:
20939
diff
changeset
|
88 return blockers |
b0822c23e80a
repoview: add _gethiddenblockers method
Sean Farley <sean.michael.farley@gmail.com>
parents:
20939
diff
changeset
|
89 |
22150
45b5cd948a4d
repoview: add caching bits
David Soria Parra <davidsp@fb.com>
parents:
22149
diff
changeset
|
90 cacheversion = 1 |
45b5cd948a4d
repoview: add caching bits
David Soria Parra <davidsp@fb.com>
parents:
22149
diff
changeset
|
91 cachefile = 'cache/hidden' |
45b5cd948a4d
repoview: add caching bits
David Soria Parra <davidsp@fb.com>
parents:
22149
diff
changeset
|
92 |
45b5cd948a4d
repoview: add caching bits
David Soria Parra <davidsp@fb.com>
parents:
22149
diff
changeset
|
93 def cachehash(repo, hideable): |
45b5cd948a4d
repoview: add caching bits
David Soria Parra <davidsp@fb.com>
parents:
22149
diff
changeset
|
94 """return sha1 hash of repository data to identify a valid cache. |
45b5cd948a4d
repoview: add caching bits
David Soria Parra <davidsp@fb.com>
parents:
22149
diff
changeset
|
95 |
45b5cd948a4d
repoview: add caching bits
David Soria Parra <davidsp@fb.com>
parents:
22149
diff
changeset
|
96 We calculate a sha1 of repo heads and the content of the obsstore and write |
45b5cd948a4d
repoview: add caching bits
David Soria Parra <davidsp@fb.com>
parents:
22149
diff
changeset
|
97 it to the cache. Upon reading we can easily validate by checking the hash |
45b5cd948a4d
repoview: add caching bits
David Soria Parra <davidsp@fb.com>
parents:
22149
diff
changeset
|
98 against the stored one and discard the cache in case the hashes don't match. |
45b5cd948a4d
repoview: add caching bits
David Soria Parra <davidsp@fb.com>
parents:
22149
diff
changeset
|
99 """ |
22282
4092d12ba18a
repoview: fix 0L with pack/unpack for 2.4
Matt Mackall <mpm@selenic.com>
parents:
22261
diff
changeset
|
100 h = util.sha1() |
4092d12ba18a
repoview: fix 0L with pack/unpack for 2.4
Matt Mackall <mpm@selenic.com>
parents:
22261
diff
changeset
|
101 h.update(''.join(repo.heads())) |
22150
45b5cd948a4d
repoview: add caching bits
David Soria Parra <davidsp@fb.com>
parents:
22149
diff
changeset
|
102 h.update(str(hash(frozenset(hideable)))) |
45b5cd948a4d
repoview: add caching bits
David Soria Parra <davidsp@fb.com>
parents:
22149
diff
changeset
|
103 return h.digest() |
45b5cd948a4d
repoview: add caching bits
David Soria Parra <davidsp@fb.com>
parents:
22149
diff
changeset
|
104 |
23378
47091002ae62
repoview: extract actual hidden cache writing in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22773
diff
changeset
|
105 def _writehiddencache(cachefile, cachehash, hidden): |
47091002ae62
repoview: extract actual hidden cache writing in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22773
diff
changeset
|
106 """write hidden data to a cache file""" |
47091002ae62
repoview: extract actual hidden cache writing in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22773
diff
changeset
|
107 data = struct.pack('>%ii' % len(hidden), *sorted(hidden)) |
47091002ae62
repoview: extract actual hidden cache writing in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22773
diff
changeset
|
108 cachefile.write(struct.pack(">H", cacheversion)) |
47091002ae62
repoview: extract actual hidden cache writing in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22773
diff
changeset
|
109 cachefile.write(cachehash) |
47091002ae62
repoview: extract actual hidden cache writing in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22773
diff
changeset
|
110 cachefile.write(data) |
47091002ae62
repoview: extract actual hidden cache writing in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22773
diff
changeset
|
111 |
22150
45b5cd948a4d
repoview: add caching bits
David Soria Parra <davidsp@fb.com>
parents:
22149
diff
changeset
|
112 def trywritehiddencache(repo, hideable, hidden): |
45b5cd948a4d
repoview: add caching bits
David Soria Parra <davidsp@fb.com>
parents:
22149
diff
changeset
|
113 """write cache of hidden changesets to disk |
45b5cd948a4d
repoview: add caching bits
David Soria Parra <davidsp@fb.com>
parents:
22149
diff
changeset
|
114 |
45b5cd948a4d
repoview: add caching bits
David Soria Parra <davidsp@fb.com>
parents:
22149
diff
changeset
|
115 Will not write the cache if a wlock cannot be obtained lazily. |
45b5cd948a4d
repoview: add caching bits
David Soria Parra <davidsp@fb.com>
parents:
22149
diff
changeset
|
116 The cache consists of a head of 22byte: |
45b5cd948a4d
repoview: add caching bits
David Soria Parra <davidsp@fb.com>
parents:
22149
diff
changeset
|
117 2 byte version number of the cache |
45b5cd948a4d
repoview: add caching bits
David Soria Parra <davidsp@fb.com>
parents:
22149
diff
changeset
|
118 20 byte sha1 to validate the cache |
45b5cd948a4d
repoview: add caching bits
David Soria Parra <davidsp@fb.com>
parents:
22149
diff
changeset
|
119 n*4 byte hidden revs |
45b5cd948a4d
repoview: add caching bits
David Soria Parra <davidsp@fb.com>
parents:
22149
diff
changeset
|
120 """ |
45b5cd948a4d
repoview: add caching bits
David Soria Parra <davidsp@fb.com>
parents:
22149
diff
changeset
|
121 wlock = fh = None |
45b5cd948a4d
repoview: add caching bits
David Soria Parra <davidsp@fb.com>
parents:
22149
diff
changeset
|
122 try: |
25086
140c2d1e57e7
repoview: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents:
24620
diff
changeset
|
123 wlock = repo.wlock(wait=False) |
140c2d1e57e7
repoview: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents:
24620
diff
changeset
|
124 # write cache to file |
140c2d1e57e7
repoview: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents:
24620
diff
changeset
|
125 newhash = cachehash(repo, hideable) |
140c2d1e57e7
repoview: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents:
24620
diff
changeset
|
126 fh = repo.vfs.open(cachefile, 'w+b', atomictemp=True) |
140c2d1e57e7
repoview: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents:
24620
diff
changeset
|
127 _writehiddencache(fh, newhash, hidden) |
140c2d1e57e7
repoview: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents:
24620
diff
changeset
|
128 except (IOError, OSError): |
140c2d1e57e7
repoview: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents:
24620
diff
changeset
|
129 repo.ui.debug('error writing hidden changesets cache') |
140c2d1e57e7
repoview: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents:
24620
diff
changeset
|
130 except error.LockHeld: |
140c2d1e57e7
repoview: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents:
24620
diff
changeset
|
131 repo.ui.debug('cannot obtain lock to write hidden changesets cache') |
22150
45b5cd948a4d
repoview: add caching bits
David Soria Parra <davidsp@fb.com>
parents:
22149
diff
changeset
|
132 finally: |
45b5cd948a4d
repoview: add caching bits
David Soria Parra <davidsp@fb.com>
parents:
22149
diff
changeset
|
133 if fh: |
45b5cd948a4d
repoview: add caching bits
David Soria Parra <davidsp@fb.com>
parents:
22149
diff
changeset
|
134 fh.close() |
45b5cd948a4d
repoview: add caching bits
David Soria Parra <davidsp@fb.com>
parents:
22149
diff
changeset
|
135 if wlock: |
45b5cd948a4d
repoview: add caching bits
David Soria Parra <davidsp@fb.com>
parents:
22149
diff
changeset
|
136 wlock.release() |
45b5cd948a4d
repoview: add caching bits
David Soria Parra <davidsp@fb.com>
parents:
22149
diff
changeset
|
137 |
45b5cd948a4d
repoview: add caching bits
David Soria Parra <davidsp@fb.com>
parents:
22149
diff
changeset
|
138 def tryreadcache(repo, hideable): |
45b5cd948a4d
repoview: add caching bits
David Soria Parra <davidsp@fb.com>
parents:
22149
diff
changeset
|
139 """read a cache if the cache exists and is valid, otherwise returns None.""" |
45b5cd948a4d
repoview: add caching bits
David Soria Parra <davidsp@fb.com>
parents:
22149
diff
changeset
|
140 hidden = fh = None |
45b5cd948a4d
repoview: add caching bits
David Soria Parra <davidsp@fb.com>
parents:
22149
diff
changeset
|
141 try: |
45b5cd948a4d
repoview: add caching bits
David Soria Parra <davidsp@fb.com>
parents:
22149
diff
changeset
|
142 if repo.vfs.exists(cachefile): |
45b5cd948a4d
repoview: add caching bits
David Soria Parra <davidsp@fb.com>
parents:
22149
diff
changeset
|
143 fh = repo.vfs.open(cachefile, 'rb') |
45b5cd948a4d
repoview: add caching bits
David Soria Parra <davidsp@fb.com>
parents:
22149
diff
changeset
|
144 version, = struct.unpack(">H", fh.read(2)) |
45b5cd948a4d
repoview: add caching bits
David Soria Parra <davidsp@fb.com>
parents:
22149
diff
changeset
|
145 oldhash = fh.read(20) |
45b5cd948a4d
repoview: add caching bits
David Soria Parra <davidsp@fb.com>
parents:
22149
diff
changeset
|
146 newhash = cachehash(repo, hideable) |
45b5cd948a4d
repoview: add caching bits
David Soria Parra <davidsp@fb.com>
parents:
22149
diff
changeset
|
147 if (cacheversion, oldhash) == (version, newhash): |
45b5cd948a4d
repoview: add caching bits
David Soria Parra <davidsp@fb.com>
parents:
22149
diff
changeset
|
148 # cache is valid, so we can start reading the hidden revs |
45b5cd948a4d
repoview: add caching bits
David Soria Parra <davidsp@fb.com>
parents:
22149
diff
changeset
|
149 data = fh.read() |
45b5cd948a4d
repoview: add caching bits
David Soria Parra <davidsp@fb.com>
parents:
22149
diff
changeset
|
150 count = len(data) / 4 |
22282
4092d12ba18a
repoview: fix 0L with pack/unpack for 2.4
Matt Mackall <mpm@selenic.com>
parents:
22261
diff
changeset
|
151 hidden = frozenset(struct.unpack('>%ii' % count, data)) |
22150
45b5cd948a4d
repoview: add caching bits
David Soria Parra <davidsp@fb.com>
parents:
22149
diff
changeset
|
152 return hidden |
45b5cd948a4d
repoview: add caching bits
David Soria Parra <davidsp@fb.com>
parents:
22149
diff
changeset
|
153 finally: |
45b5cd948a4d
repoview: add caching bits
David Soria Parra <davidsp@fb.com>
parents:
22149
diff
changeset
|
154 if fh: |
45b5cd948a4d
repoview: add caching bits
David Soria Parra <davidsp@fb.com>
parents:
22149
diff
changeset
|
155 fh.close() |
45b5cd948a4d
repoview: add caching bits
David Soria Parra <davidsp@fb.com>
parents:
22149
diff
changeset
|
156 |
18242
e4687edec014
clfilter: introduces a hidden filter
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18233
diff
changeset
|
157 def computehidden(repo): |
e4687edec014
clfilter: introduces a hidden filter
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18233
diff
changeset
|
158 """compute the set of hidden revision to filter |
e4687edec014
clfilter: introduces a hidden filter
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18233
diff
changeset
|
159 |
e4687edec014
clfilter: introduces a hidden filter
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18233
diff
changeset
|
160 During most operation hidden should be filtered.""" |
e4687edec014
clfilter: introduces a hidden filter
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18233
diff
changeset
|
161 assert not repo.changelog.filteredrevs |
22151
c0c369aec643
repoview: cache hidden changesets
David Soria Parra <davidsp@fb.com>
parents:
22150
diff
changeset
|
162 |
22149
16ef2c485f03
repoview: split _gethiddenblockers
David Soria Parra <davidsp@fb.com>
parents:
22148
diff
changeset
|
163 hidden = frozenset() |
18293
1f35d6737ed8
repoview: extract hideable revision computation in a dedicated function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18274
diff
changeset
|
164 hideable = hideablerevs(repo) |
18272
95ef7a87c053
performance: speedup computation of hidden revisions
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18250
diff
changeset
|
165 if hideable: |
95ef7a87c053
performance: speedup computation of hidden revisions
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18250
diff
changeset
|
166 cl = repo.changelog |
22151
c0c369aec643
repoview: cache hidden changesets
David Soria Parra <davidsp@fb.com>
parents:
22150
diff
changeset
|
167 hidden = tryreadcache(repo, hideable) |
c0c369aec643
repoview: cache hidden changesets
David Soria Parra <davidsp@fb.com>
parents:
22150
diff
changeset
|
168 if hidden is None: |
24565
2f7cb6e6acdd
repoview: improve compute staticblockers perf
Durham Goode <durham@fb.com>
parents:
24154
diff
changeset
|
169 hidden = frozenset(_getstatichidden(repo)) |
22151
c0c369aec643
repoview: cache hidden changesets
David Soria Parra <davidsp@fb.com>
parents:
22150
diff
changeset
|
170 trywritehiddencache(repo, hideable, hidden) |
22149
16ef2c485f03
repoview: split _gethiddenblockers
David Soria Parra <davidsp@fb.com>
parents:
22148
diff
changeset
|
171 |
16ef2c485f03
repoview: split _gethiddenblockers
David Soria Parra <davidsp@fb.com>
parents:
22148
diff
changeset
|
172 # check if we have wd parents, bookmarks or tags pointing to hidden |
16ef2c485f03
repoview: split _gethiddenblockers
David Soria Parra <davidsp@fb.com>
parents:
22148
diff
changeset
|
173 # changesets and remove those. |
16ef2c485f03
repoview: split _gethiddenblockers
David Soria Parra <davidsp@fb.com>
parents:
22148
diff
changeset
|
174 dynamic = hidden & _getdynamicblockers(repo) |
16ef2c485f03
repoview: split _gethiddenblockers
David Soria Parra <davidsp@fb.com>
parents:
22148
diff
changeset
|
175 if dynamic: |
16ef2c485f03
repoview: split _gethiddenblockers
David Soria Parra <davidsp@fb.com>
parents:
22148
diff
changeset
|
176 blocked = cl.ancestors(dynamic, inclusive=True) |
16ef2c485f03
repoview: split _gethiddenblockers
David Soria Parra <davidsp@fb.com>
parents:
22148
diff
changeset
|
177 hidden = frozenset(r for r in hidden if r not in blocked) |
16ef2c485f03
repoview: split _gethiddenblockers
David Soria Parra <davidsp@fb.com>
parents:
22148
diff
changeset
|
178 return hidden |
18242
e4687edec014
clfilter: introduces a hidden filter
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18233
diff
changeset
|
179 |
18102
3c7b67b76190
clfilter: introduce a "unserver" filtering mode
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18101
diff
changeset
|
180 def computeunserved(repo): |
3c7b67b76190
clfilter: introduce a "unserver" filtering mode
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18101
diff
changeset
|
181 """compute the set of revision that should be filtered when used a server |
3c7b67b76190
clfilter: introduce a "unserver" filtering mode
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18101
diff
changeset
|
182 |
3c7b67b76190
clfilter: introduce a "unserver" filtering mode
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18101
diff
changeset
|
183 Secret and hidden changeset should not pretend to be here.""" |
3c7b67b76190
clfilter: introduce a "unserver" filtering mode
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18101
diff
changeset
|
184 assert not repo.changelog.filteredrevs |
3c7b67b76190
clfilter: introduce a "unserver" filtering mode
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18101
diff
changeset
|
185 # fast path in simple case to avoid impact of non optimised code |
18382
f3b21beb9802
filtering: rename filters to their antonyms
Kevin Bullock <kbullock@ringworld.org>
parents:
18293
diff
changeset
|
186 hiddens = filterrevs(repo, 'visible') |
18273
a2d54f68e13c
performance: speedup computation of unserved revisions
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18272
diff
changeset
|
187 if phases.hassecret(repo): |
a2d54f68e13c
performance: speedup computation of unserved revisions
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18272
diff
changeset
|
188 cl = repo.changelog |
a2d54f68e13c
performance: speedup computation of unserved revisions
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18272
diff
changeset
|
189 secret = phases.secret |
a2d54f68e13c
performance: speedup computation of unserved revisions
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18272
diff
changeset
|
190 getphase = repo._phasecache.phase |
a2d54f68e13c
performance: speedup computation of unserved revisions
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18272
diff
changeset
|
191 first = min(cl.rev(n) for n in repo._phasecache.phaseroots[secret]) |
a2d54f68e13c
performance: speedup computation of unserved revisions
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18272
diff
changeset
|
192 revs = cl.revs(start=first) |
a2d54f68e13c
performance: speedup computation of unserved revisions
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18272
diff
changeset
|
193 secrets = set(r for r in revs if getphase(repo, r) >= secret) |
a2d54f68e13c
performance: speedup computation of unserved revisions
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18272
diff
changeset
|
194 return frozenset(hiddens | secrets) |
a2d54f68e13c
performance: speedup computation of unserved revisions
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18272
diff
changeset
|
195 else: |
a2d54f68e13c
performance: speedup computation of unserved revisions
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18272
diff
changeset
|
196 return hiddens |
18100
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
197 |
18245
aff706b3a21c
clfilter: add mutable filtering
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18242
diff
changeset
|
198 def computemutable(repo): |
aff706b3a21c
clfilter: add mutable filtering
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18242
diff
changeset
|
199 """compute the set of revision that should be filtered when used a server |
aff706b3a21c
clfilter: add mutable filtering
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18242
diff
changeset
|
200 |
aff706b3a21c
clfilter: add mutable filtering
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18242
diff
changeset
|
201 Secret and hidden changeset should not pretend to be here.""" |
aff706b3a21c
clfilter: add mutable filtering
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18242
diff
changeset
|
202 assert not repo.changelog.filteredrevs |
aff706b3a21c
clfilter: add mutable filtering
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18242
diff
changeset
|
203 # fast check to avoid revset call on huge repo |
25149
3f0744eeaeaf
cleanup: use __builtins__.any instead of util.any
Augie Fackler <augie@google.com>
parents:
25086
diff
changeset
|
204 if any(repo._phasecache.phaseroots[1:]): |
18274
254b708fd37d
performance: speedup computation of mutable revisions
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18273
diff
changeset
|
205 getphase = repo._phasecache.phase |
18382
f3b21beb9802
filtering: rename filters to their antonyms
Kevin Bullock <kbullock@ringworld.org>
parents:
18293
diff
changeset
|
206 maymutable = filterrevs(repo, 'base') |
18274
254b708fd37d
performance: speedup computation of mutable revisions
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18273
diff
changeset
|
207 return frozenset(r for r in maymutable if getphase(repo, r)) |
18245
aff706b3a21c
clfilter: add mutable filtering
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18242
diff
changeset
|
208 return frozenset() |
aff706b3a21c
clfilter: add mutable filtering
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18242
diff
changeset
|
209 |
18246
58ca19edc043
clfilter: add impactable filter
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18245
diff
changeset
|
210 def computeimpactable(repo): |
58ca19edc043
clfilter: add impactable filter
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18245
diff
changeset
|
211 """Everything impactable by mutable revision |
58ca19edc043
clfilter: add impactable filter
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18245
diff
changeset
|
212 |
18462
593eb3786165
documentation: update to new filter names
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18445
diff
changeset
|
213 The immutable filter still have some chance to get invalidated. This will |
18246
58ca19edc043
clfilter: add impactable filter
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18245
diff
changeset
|
214 happen when: |
58ca19edc043
clfilter: add impactable filter
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18245
diff
changeset
|
215 |
58ca19edc043
clfilter: add impactable filter
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18245
diff
changeset
|
216 - you garbage collect hidden changeset, |
58ca19edc043
clfilter: add impactable filter
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18245
diff
changeset
|
217 - public phase is moved backward, |
58ca19edc043
clfilter: add impactable filter
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18245
diff
changeset
|
218 - something is changed in the filtering (this could be fixed) |
58ca19edc043
clfilter: add impactable filter
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18245
diff
changeset
|
219 |
58ca19edc043
clfilter: add impactable filter
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18245
diff
changeset
|
220 This filter out any mutable changeset and any public changeset that may be |
58ca19edc043
clfilter: add impactable filter
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18245
diff
changeset
|
221 impacted by something happening to a mutable revision. |
58ca19edc043
clfilter: add impactable filter
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18245
diff
changeset
|
222 |
58ca19edc043
clfilter: add impactable filter
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18245
diff
changeset
|
223 This is achieved by filtered everything with a revision number egal or |
58ca19edc043
clfilter: add impactable filter
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18245
diff
changeset
|
224 higher than the first mutable changeset is filtered.""" |
58ca19edc043
clfilter: add impactable filter
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18245
diff
changeset
|
225 assert not repo.changelog.filteredrevs |
58ca19edc043
clfilter: add impactable filter
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18245
diff
changeset
|
226 cl = repo.changelog |
58ca19edc043
clfilter: add impactable filter
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18245
diff
changeset
|
227 firstmutable = len(cl) |
58ca19edc043
clfilter: add impactable filter
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18245
diff
changeset
|
228 for roots in repo._phasecache.phaseroots[1:]: |
58ca19edc043
clfilter: add impactable filter
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18245
diff
changeset
|
229 if roots: |
58ca19edc043
clfilter: add impactable filter
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18245
diff
changeset
|
230 firstmutable = min(firstmutable, min(cl.rev(r) for r in roots)) |
18443
64848f7fb764
repoview: protect `base` computation from weird phase root
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18382
diff
changeset
|
231 # protect from nullrev root |
64848f7fb764
repoview: protect `base` computation from weird phase root
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18382
diff
changeset
|
232 firstmutable = max(0, firstmutable) |
18246
58ca19edc043
clfilter: add impactable filter
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18245
diff
changeset
|
233 return frozenset(xrange(firstmutable, len(cl))) |
58ca19edc043
clfilter: add impactable filter
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18245
diff
changeset
|
234 |
18100
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
235 # function to compute filtered set |
20196
59198508b0bd
filter: add a comment so that people do not forget to update subsettable
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
20032
diff
changeset
|
236 # |
20549
2025315cfb0c
comments: fix minor spelling issues found with spell checker
Mads Kiilerich <madski@unity3d.com>
parents:
20405
diff
changeset
|
237 # When adding a new filter you MUST update the table at: |
20196
59198508b0bd
filter: add a comment so that people do not forget to update subsettable
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
20032
diff
changeset
|
238 # mercurial.branchmap.subsettable |
59198508b0bd
filter: add a comment so that people do not forget to update subsettable
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
20032
diff
changeset
|
239 # Otherwise your filter will have to recompute all its branches cache |
59198508b0bd
filter: add a comment so that people do not forget to update subsettable
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
20032
diff
changeset
|
240 # from scratch (very slow). |
18382
f3b21beb9802
filtering: rename filters to their antonyms
Kevin Bullock <kbullock@ringworld.org>
parents:
18293
diff
changeset
|
241 filtertable = {'visible': computehidden, |
f3b21beb9802
filtering: rename filters to their antonyms
Kevin Bullock <kbullock@ringworld.org>
parents:
18293
diff
changeset
|
242 'served': computeunserved, |
f3b21beb9802
filtering: rename filters to their antonyms
Kevin Bullock <kbullock@ringworld.org>
parents:
18293
diff
changeset
|
243 'immutable': computemutable, |
f3b21beb9802
filtering: rename filters to their antonyms
Kevin Bullock <kbullock@ringworld.org>
parents:
18293
diff
changeset
|
244 'base': computeimpactable} |
18100
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
245 |
18382
f3b21beb9802
filtering: rename filters to their antonyms
Kevin Bullock <kbullock@ringworld.org>
parents:
18293
diff
changeset
|
246 def filterrevs(repo, filtername): |
18100
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
247 """returns set of filtered revision for this filter name""" |
18101
a464deecc9dd
clfilter: add a cache on repo for set of revision to filter for a given set.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18100
diff
changeset
|
248 if filtername not in repo.filteredrevcache: |
a464deecc9dd
clfilter: add a cache on repo for set of revision to filter for a given set.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18100
diff
changeset
|
249 func = filtertable[filtername] |
a464deecc9dd
clfilter: add a cache on repo for set of revision to filter for a given set.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18100
diff
changeset
|
250 repo.filteredrevcache[filtername] = func(repo.unfiltered()) |
a464deecc9dd
clfilter: add a cache on repo for set of revision to filter for a given set.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18100
diff
changeset
|
251 return repo.filteredrevcache[filtername] |
18100
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
252 |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
253 class repoview(object): |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
254 """Provide a read/write view of a repo through a filtered changelog |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
255 |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
256 This object is used to access a filtered version of a repository without |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
257 altering the original repository object itself. We can not alter the |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
258 original object for two main reasons: |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
259 - It prevents the use of a repo with multiple filters at the same time. In |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
260 particular when multiple threads are involved. |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
261 - It makes scope of the filtering harder to control. |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
262 |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
263 This object behaves very closely to the original repository. All attribute |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
264 operations are done on the original repository: |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
265 - An access to `repoview.someattr` actually returns `repo.someattr`, |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
266 - A write to `repoview.someattr` actually sets value of `repo.someattr`, |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
267 - A deletion of `repoview.someattr` actually drops `someattr` |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
268 from `repo.__dict__`. |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
269 |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
270 The only exception is the `changelog` property. It is overridden to return |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
271 a (surface) copy of `repo.changelog` with some revisions filtered. The |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
272 `filtername` attribute of the view control the revisions that need to be |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
273 filtered. (the fact the changelog is copied is an implementation detail). |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
274 |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
275 Unlike attributes, this object intercepts all method calls. This means that |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
276 all methods are run on the `repoview` object with the filtered `changelog` |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
277 property. For this purpose the simple `repoview` class must be mixed with |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
278 the actual class of the repository. This ensures that the resulting |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
279 `repoview` object have the very same methods than the repo object. This |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
280 leads to the property below. |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
281 |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
282 repoview.method() --> repo.__class__.method(repoview) |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
283 |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
284 The inheritance has to be done dynamically because `repo` can be of any |
18644
3e92772d5383
spelling: fix some minor issues found by spell checker
Mads Kiilerich <mads@kiilerich.com>
parents:
18495
diff
changeset
|
285 subclasses of `localrepo`. Eg: `bundlerepo` or `statichttprepo`. |
18100
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
286 """ |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
287 |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
288 def __init__(self, repo, filtername): |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
289 object.__setattr__(self, '_unfilteredrepo', repo) |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
290 object.__setattr__(self, 'filtername', filtername) |
18445
4d92e2d75cff
repoview: cache filtered changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18443
diff
changeset
|
291 object.__setattr__(self, '_clcachekey', None) |
4d92e2d75cff
repoview: cache filtered changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18443
diff
changeset
|
292 object.__setattr__(self, '_clcache', None) |
18100
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
293 |
18644
3e92772d5383
spelling: fix some minor issues found by spell checker
Mads Kiilerich <mads@kiilerich.com>
parents:
18495
diff
changeset
|
294 # not a propertycache on purpose we shall implement a proper cache later |
18100
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
295 @property |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
296 def changelog(self): |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
297 """return a filtered version of the changeset |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
298 |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
299 this changelog must not be used for writing""" |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
300 # some cache may be implemented later |
18445
4d92e2d75cff
repoview: cache filtered changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18443
diff
changeset
|
301 unfi = self._unfilteredrepo |
4d92e2d75cff
repoview: cache filtered changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18443
diff
changeset
|
302 unfichangelog = unfi.changelog |
4d92e2d75cff
repoview: cache filtered changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18443
diff
changeset
|
303 revs = filterrevs(unfi, self.filtername) |
4d92e2d75cff
repoview: cache filtered changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18443
diff
changeset
|
304 cl = self._clcache |
24154
a41902aac76d
repoview: invalidate cached changelog if _delayed changes (issue4549)
Matt Mackall <mpm@selenic.com>
parents:
23636
diff
changeset
|
305 newkey = (len(unfichangelog), unfichangelog.tip(), hash(revs), |
a41902aac76d
repoview: invalidate cached changelog if _delayed changes (issue4549)
Matt Mackall <mpm@selenic.com>
parents:
23636
diff
changeset
|
306 unfichangelog._delayed) |
18445
4d92e2d75cff
repoview: cache filtered changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18443
diff
changeset
|
307 if cl is not None: |
4d92e2d75cff
repoview: cache filtered changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18443
diff
changeset
|
308 # we need to check curkey too for some obscure reason. |
4d92e2d75cff
repoview: cache filtered changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18443
diff
changeset
|
309 # MQ test show a corruption of the underlying repo (in _clcache) |
4d92e2d75cff
repoview: cache filtered changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18443
diff
changeset
|
310 # without change in the cachekey. |
4d92e2d75cff
repoview: cache filtered changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18443
diff
changeset
|
311 oldfilter = cl.filteredrevs |
4d92e2d75cff
repoview: cache filtered changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18443
diff
changeset
|
312 try: |
22317
e1d5fcab58b6
repoview: fix typo in repoview.changelog
Mike Hommey <mh@glandium.org>
parents:
22106
diff
changeset
|
313 cl.filteredrevs = () # disable filtering for tip |
24154
a41902aac76d
repoview: invalidate cached changelog if _delayed changes (issue4549)
Matt Mackall <mpm@selenic.com>
parents:
23636
diff
changeset
|
314 curkey = (len(cl), cl.tip(), hash(oldfilter), cl._delayed) |
18445
4d92e2d75cff
repoview: cache filtered changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18443
diff
changeset
|
315 finally: |
4d92e2d75cff
repoview: cache filtered changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18443
diff
changeset
|
316 cl.filteredrevs = oldfilter |
4d92e2d75cff
repoview: cache filtered changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18443
diff
changeset
|
317 if newkey != self._clcachekey or newkey != curkey: |
4d92e2d75cff
repoview: cache filtered changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18443
diff
changeset
|
318 cl = None |
4d92e2d75cff
repoview: cache filtered changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18443
diff
changeset
|
319 # could have been made None by the previous if |
4d92e2d75cff
repoview: cache filtered changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18443
diff
changeset
|
320 if cl is None: |
4d92e2d75cff
repoview: cache filtered changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18443
diff
changeset
|
321 cl = copy.copy(unfichangelog) |
4d92e2d75cff
repoview: cache filtered changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18443
diff
changeset
|
322 cl.filteredrevs = revs |
4d92e2d75cff
repoview: cache filtered changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18443
diff
changeset
|
323 object.__setattr__(self, '_clcache', cl) |
4d92e2d75cff
repoview: cache filtered changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18443
diff
changeset
|
324 object.__setattr__(self, '_clcachekey', newkey) |
18100
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
325 return cl |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
326 |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
327 def unfiltered(self): |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
328 """Return an unfiltered version of a repo""" |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
329 return self._unfilteredrepo |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
330 |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
331 def filtered(self, name): |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
332 """Return a filtered version of a repository""" |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
333 if name == self.filtername: |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
334 return self |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
335 return self.unfiltered().filtered(name) |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
336 |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
337 # everything access are forwarded to the proxied repo |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
338 def __getattr__(self, attr): |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
339 return getattr(self._unfilteredrepo, attr) |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
340 |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
341 def __setattr__(self, attr, value): |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
342 return setattr(self._unfilteredrepo, attr, value) |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
343 |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
344 def __delattr__(self, attr): |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
345 return delattr(self._unfilteredrepo, attr) |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
346 |
18644
3e92772d5383
spelling: fix some minor issues found by spell checker
Mads Kiilerich <mads@kiilerich.com>
parents:
18495
diff
changeset
|
347 # The `requirements` attribute is initialized during __init__. But |
18100
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
348 # __getattr__ won't be called as it also exists on the class. We need |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
349 # explicit forwarding to main repo here |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
350 @property |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
351 def requirements(self): |
3a6ddacb7198
clfilter: add actual repo filtering mechanism
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
352 return self._unfilteredrepo.requirements |