annotate upmana/mercurial/bundlerepo.py @ 248:1df5912db00c beta tip

Traipse Beta 'OpenRPG' {101205-00} Traipse is a distribution of OpenRPG that is designed to be easy to setup and go. Traipse also makes it easy for developers to work on code without fear of sacrifice. 'Ornery-Orc' continues the trend of 'Grumpy' and adds fixes to the code. 'Ornery-Orc's main goal is to offer more advanced features and enhance the productivity of the user. Update Summary (Closed) New Features: New to Map, can re-order Grid, Miniatures, and Whiteboard layer draw order New to Server GUI, can now clear log New Earthdawn Dieroller New IronClaw roller, sheet, and image New ShapeShifter PC Sheet Updates: Update to Warhammer PC Sheet. Rollers set as macros. Should work with little maintanence. Update to Browser Server window. Display rooms with ' " & cleaner Update to Server. Handles ' " & cleaner Update to Dieroller. Cleaner, more effecient expression system Update to Hidden Die plugin, allows for non standard dice rolls Update to location.py, allows for more portable references when starting Traipse Update to the Features node Fixes: Fix to InterParse that was causing an Infernal Loop with Namespace Internal Fix to XML data, removed old Minidom and switched to Element Tree Fix to Server that was causing eternal attempt to find a Server ID, in Register Rooms thread Fix to Server, removing wxPython dependencies where not needed Fix to metaservers.xml file not being created Fix to Single and Double quotes in Whiteboard text Fix to Background images not showing when using the Image Server Fix to Duplicate chat names appearing Fix to Server GUI's logging output Fix to FNB.COLORFUL_TABS bug Fix to Gametree for XSLT Sheets Fix to Gametree for locating gametree files Fix to Send to Chat from Gametree Fix to Gametree, renaming and remapping operates correctly Fix to aliaslib, prevents error caused when SafeHTML is sent None
author sirebral
date Sun, 05 Dec 2010 10:53:30 -0600
parents dcf4fbe09b70
children
rev   line source
135
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
1 # bundlerepo.py - repository class for viewing uncompressed bundles
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
2 #
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
3 # Copyright 2006, 2007 Benoit Boissinot <bboissin@gmail.com>
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
4 #
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
5 # This software may be used and distributed according to the terms of the
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
6 # GNU General Public License version 2, incorporated herein by reference.
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
7
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
8 """Repository class for viewing uncompressed bundles.
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
9
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
10 This provides a read-only repository interface to bundles as if they
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
11 were part of the actual repository.
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
12 """
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
13
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
14 from node import nullid
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
15 from i18n import _
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
16 import os, struct, bz2, zlib, tempfile, shutil
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
17 import changegroup, util, mdiff
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
18 import localrepo, changelog, manifest, filelog, revlog, error
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
19
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
20 class bundlerevlog(revlog.revlog):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
21 def __init__(self, opener, indexfile, bundlefile,
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
22 linkmapper=None):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
23 # How it works:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
24 # to retrieve a revision, we need to know the offset of
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
25 # the revision in the bundlefile (an opened file).
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
26 #
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
27 # We store this offset in the index (start), to differentiate a
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
28 # rev in the bundle and from a rev in the revlog, we check
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
29 # len(index[r]). If the tuple is bigger than 7, it is a bundle
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
30 # (it is bigger since we store the node to which the delta is)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
31 #
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
32 revlog.revlog.__init__(self, opener, indexfile)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
33 self.bundlefile = bundlefile
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
34 self.basemap = {}
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
35 def chunkpositer():
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
36 for chunk in changegroup.chunkiter(bundlefile):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
37 pos = bundlefile.tell()
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
38 yield chunk, pos - len(chunk)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
39 n = len(self)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
40 prev = None
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
41 for chunk, start in chunkpositer():
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
42 size = len(chunk)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
43 if size < 80:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
44 raise util.Abort(_("invalid changegroup"))
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
45 start += 80
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
46 size -= 80
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
47 node, p1, p2, cs = struct.unpack("20s20s20s20s", chunk[:80])
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
48 if node in self.nodemap:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
49 prev = node
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
50 continue
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
51 for p in (p1, p2):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
52 if not p in self.nodemap:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
53 raise error.LookupError(p1, self.indexfile,
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
54 _("unknown parent"))
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
55 if linkmapper is None:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
56 link = n
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
57 else:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
58 link = linkmapper(cs)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
59
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
60 if not prev:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
61 prev = p1
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
62 # start, size, full unc. size, base (unused), link, p1, p2, node
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
63 e = (revlog.offset_type(start, 0), size, -1, -1, link,
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
64 self.rev(p1), self.rev(p2), node)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
65 self.basemap[n] = prev
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
66 self.index.insert(-1, e)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
67 self.nodemap[node] = n
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
68 prev = node
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
69 n += 1
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
70
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
71 def bundle(self, rev):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
72 """is rev from the bundle"""
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
73 if rev < 0:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
74 return False
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
75 return rev in self.basemap
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
76 def bundlebase(self, rev): return self.basemap[rev]
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
77 def chunk(self, rev, df=None, cachelen=4096):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
78 # Warning: in case of bundle, the diff is against bundlebase,
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
79 # not against rev - 1
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
80 # XXX: could use some caching
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
81 if not self.bundle(rev):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
82 return revlog.revlog.chunk(self, rev, df)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
83 self.bundlefile.seek(self.start(rev))
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
84 return self.bundlefile.read(self.length(rev))
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
85
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
86 def revdiff(self, rev1, rev2):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
87 """return or calculate a delta between two revisions"""
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
88 if self.bundle(rev1) and self.bundle(rev2):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
89 # hot path for bundle
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
90 revb = self.rev(self.bundlebase(rev2))
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
91 if revb == rev1:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
92 return self.chunk(rev2)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
93 elif not self.bundle(rev1) and not self.bundle(rev2):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
94 return revlog.revlog.revdiff(self, rev1, rev2)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
95
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
96 return mdiff.textdiff(self.revision(self.node(rev1)),
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
97 self.revision(self.node(rev2)))
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
98
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
99 def revision(self, node):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
100 """return an uncompressed revision of a given"""
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
101 if node == nullid: return ""
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
102
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
103 text = None
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
104 chain = []
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
105 iter_node = node
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
106 rev = self.rev(iter_node)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
107 # reconstruct the revision if it is from a changegroup
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
108 while self.bundle(rev):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
109 if self._cache and self._cache[0] == iter_node:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
110 text = self._cache[2]
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
111 break
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
112 chain.append(rev)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
113 iter_node = self.bundlebase(rev)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
114 rev = self.rev(iter_node)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
115 if text is None:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
116 text = revlog.revlog.revision(self, iter_node)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
117
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
118 while chain:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
119 delta = self.chunk(chain.pop())
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
120 text = mdiff.patches(text, [delta])
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
121
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
122 p1, p2 = self.parents(node)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
123 if node != revlog.hash(text, p1, p2):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
124 raise error.RevlogError(_("integrity check failed on %s:%d")
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
125 % (self.datafile, self.rev(node)))
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
126
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
127 self._cache = (node, self.rev(node), text)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
128 return text
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
129
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
130 def addrevision(self, text, transaction, link, p1=None, p2=None, d=None):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
131 raise NotImplementedError
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
132 def addgroup(self, revs, linkmapper, transaction):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
133 raise NotImplementedError
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
134 def strip(self, rev, minlink):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
135 raise NotImplementedError
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
136 def checksize(self):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
137 raise NotImplementedError
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
138
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
139 class bundlechangelog(bundlerevlog, changelog.changelog):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
140 def __init__(self, opener, bundlefile):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
141 changelog.changelog.__init__(self, opener)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
142 bundlerevlog.__init__(self, opener, self.indexfile, bundlefile)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
143
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
144 class bundlemanifest(bundlerevlog, manifest.manifest):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
145 def __init__(self, opener, bundlefile, linkmapper):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
146 manifest.manifest.__init__(self, opener)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
147 bundlerevlog.__init__(self, opener, self.indexfile, bundlefile,
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
148 linkmapper)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
149
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
150 class bundlefilelog(bundlerevlog, filelog.filelog):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
151 def __init__(self, opener, path, bundlefile, linkmapper):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
152 filelog.filelog.__init__(self, opener, path)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
153 bundlerevlog.__init__(self, opener, self.indexfile, bundlefile,
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
154 linkmapper)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
155
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
156 class bundlerepository(localrepo.localrepository):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
157 def __init__(self, ui, path, bundlename):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
158 self._tempparent = None
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
159 try:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
160 localrepo.localrepository.__init__(self, ui, path)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
161 except error.RepoError:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
162 self._tempparent = tempfile.mkdtemp()
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
163 localrepo.instance(ui,self._tempparent,1)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
164 localrepo.localrepository.__init__(self, ui, self._tempparent)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
165
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
166 if path:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
167 self._url = 'bundle:' + path + '+' + bundlename
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
168 else:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
169 self._url = 'bundle:' + bundlename
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
170
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
171 self.tempfile = None
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
172 self.bundlefile = open(bundlename, "rb")
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
173 header = self.bundlefile.read(6)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
174 if not header.startswith("HG"):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
175 raise util.Abort(_("%s: not a Mercurial bundle file") % bundlename)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
176 elif not header.startswith("HG10"):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
177 raise util.Abort(_("%s: unknown bundle version") % bundlename)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
178 elif (header == "HG10BZ") or (header == "HG10GZ"):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
179 fdtemp, temp = tempfile.mkstemp(prefix="hg-bundle-",
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
180 suffix=".hg10un", dir=self.path)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
181 self.tempfile = temp
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
182 fptemp = os.fdopen(fdtemp, 'wb')
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
183 def generator(f):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
184 if header == "HG10BZ":
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
185 zd = bz2.BZ2Decompressor()
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
186 zd.decompress("BZ")
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
187 elif header == "HG10GZ":
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
188 zd = zlib.decompressobj()
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
189 for chunk in f:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
190 yield zd.decompress(chunk)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
191 gen = generator(util.filechunkiter(self.bundlefile, 4096))
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
192
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
193 try:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
194 fptemp.write("HG10UN")
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
195 for chunk in gen:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
196 fptemp.write(chunk)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
197 finally:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
198 fptemp.close()
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
199 self.bundlefile.close()
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
200
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
201 self.bundlefile = open(self.tempfile, "rb")
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
202 # seek right after the header
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
203 self.bundlefile.seek(6)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
204 elif header == "HG10UN":
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
205 # nothing to do
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
206 pass
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
207 else:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
208 raise util.Abort(_("%s: unknown bundle compression type")
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
209 % bundlename)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
210 # dict with the mapping 'filename' -> position in the bundle
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
211 self.bundlefilespos = {}
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
212
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
213 @util.propertycache
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
214 def changelog(self):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
215 c = bundlechangelog(self.sopener, self.bundlefile)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
216 self.manstart = self.bundlefile.tell()
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
217 return c
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
218
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
219 @util.propertycache
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
220 def manifest(self):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
221 self.bundlefile.seek(self.manstart)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
222 m = bundlemanifest(self.sopener, self.bundlefile, self.changelog.rev)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
223 self.filestart = self.bundlefile.tell()
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
224 return m
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
225
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
226 @util.propertycache
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
227 def manstart(self):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
228 self.changelog
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
229 return self.manstart
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
230
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
231 @util.propertycache
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
232 def filestart(self):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
233 self.manifest
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
234 return self.filestart
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
235
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
236 def url(self):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
237 return self._url
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
238
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
239 def file(self, f):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
240 if not self.bundlefilespos:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
241 self.bundlefile.seek(self.filestart)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
242 while 1:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
243 chunk = changegroup.getchunk(self.bundlefile)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
244 if not chunk:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
245 break
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
246 self.bundlefilespos[chunk] = self.bundlefile.tell()
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
247 for c in changegroup.chunkiter(self.bundlefile):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
248 pass
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
249
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
250 if f[0] == '/':
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
251 f = f[1:]
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
252 if f in self.bundlefilespos:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
253 self.bundlefile.seek(self.bundlefilespos[f])
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
254 return bundlefilelog(self.sopener, f, self.bundlefile,
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
255 self.changelog.rev)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
256 else:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
257 return filelog.filelog(self.sopener, f)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
258
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
259 def close(self):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
260 """Close assigned bundle file immediately."""
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
261 self.bundlefile.close()
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
262
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
263 def __del__(self):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
264 bundlefile = getattr(self, 'bundlefile', None)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
265 if bundlefile and not bundlefile.closed:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
266 bundlefile.close()
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
267 tempfile = getattr(self, 'tempfile', None)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
268 if tempfile is not None:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
269 os.unlink(tempfile)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
270 if self._tempparent:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
271 shutil.rmtree(self._tempparent, True)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
272
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
273 def cancopy(self):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
274 return False
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
275
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
276 def getcwd(self):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
277 return os.getcwd() # always outside the repo
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
278
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
279 def instance(ui, path, create):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
280 if create:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
281 raise util.Abort(_('cannot create new bundle repository'))
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
282 parentpath = ui.config("bundle", "mainreporoot", "")
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
283 if parentpath:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
284 # Try to make the full path relative so we get a nice, short URL.
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
285 # In particular, we don't want temp dir names in test outputs.
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
286 cwd = os.getcwd()
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
287 if parentpath == cwd:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
288 parentpath = ''
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
289 else:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
290 cwd = os.path.join(cwd,'')
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
291 if parentpath.startswith(cwd):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
292 parentpath = parentpath[len(cwd):]
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
293 path = util.drop_scheme('file', path)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
294 if path.startswith('bundle:'):
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
295 path = util.drop_scheme('bundle', path)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
296 s = path.split("+", 1)
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
297 if len(s) == 1:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
298 repopath, bundlename = parentpath, s[0]
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
299 else:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
300 repopath, bundlename = s
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
301 else:
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
302 repopath, bundlename = parentpath, path
dcf4fbe09b70 Traipse Beta 'OpenRPG' {091010-00}
sirebral
parents:
diff changeset
303 return bundlerepository(ui, repopath, bundlename)