11 """ |
11 """ |
12 |
12 |
13 from node import * |
13 from node import * |
14 from i18n import gettext as _ |
14 from i18n import gettext as _ |
15 from demandload import demandload |
15 from demandload import demandload |
16 demandload(globals(), "changegroup util os struct") |
16 demandload(globals(), "changegroup util os struct bz2 tempfile") |
17 |
17 |
18 import localrepo, changelog, manifest, filelog, revlog |
18 import localrepo, changelog, manifest, filelog, revlog |
19 |
19 |
20 class bundlerevlog(revlog.revlog): |
20 class bundlerevlog(revlog.revlog): |
21 def __init__(self, opener, indexfile, datafile, bundlefile, |
21 def __init__(self, opener, indexfile, datafile, bundlefile, |
157 bundlefile, linkmapper) |
157 bundlefile, linkmapper) |
158 |
158 |
159 class bundlerepository(localrepo.localrepository): |
159 class bundlerepository(localrepo.localrepository): |
160 def __init__(self, ui, path, bundlename): |
160 def __init__(self, ui, path, bundlename): |
161 localrepo.localrepository.__init__(self, ui, path) |
161 localrepo.localrepository.__init__(self, ui, path) |
162 f = open(bundlename, "rb") |
162 self.tempfile = None |
163 self.bundlefile = f |
163 self.bundlefile = open(bundlename, "rb") |
164 header = self.bundlefile.read(6) |
164 header = self.bundlefile.read(6) |
165 if not header.startswith("HG"): |
165 if not header.startswith("HG"): |
166 raise util.Abort(_("%s: not a Mercurial bundle file") % bundlename) |
166 raise util.Abort(_("%s: not a Mercurial bundle file") % bundlename) |
167 elif not header.startswith("HG10"): |
167 elif not header.startswith("HG10"): |
168 raise util.Abort(_("%s: unknown bundle version") % bundlename) |
168 raise util.Abort(_("%s: unknown bundle version") % bundlename) |
169 elif header == "HG10BZ": |
169 elif header == "HG10BZ": |
170 raise util.Abort(_("%s: compressed bundle not supported") |
170 fdtemp, temp = tempfile.mkstemp(prefix="hg-bundle-", |
171 % bundlename) |
171 suffix=".hg10un", dir=self.path) |
|
172 self.tempfile = temp |
|
173 fptemp = os.fdopen(fdtemp, 'wb') |
|
174 def generator(f): |
|
175 zd = bz2.BZ2Decompressor() |
|
176 zd.decompress("BZ") |
|
177 for chunk in f: |
|
178 yield zd.decompress(chunk) |
|
179 gen = generator(util.filechunkiter(self.bundlefile, 4096)) |
|
180 |
|
181 try: |
|
182 fptemp.write("HG10UN") |
|
183 for chunk in gen: |
|
184 fptemp.write(chunk) |
|
185 finally: |
|
186 fptemp.close() |
|
187 self.bundlefile.close() |
|
188 |
|
189 self.bundlefile = open(self.tempfile, "rb") |
|
190 # seek right after the header |
|
191 self.bundlefile.seek(6) |
172 elif header == "HG10UN": |
192 elif header == "HG10UN": |
173 # uncompressed bundle supported |
193 # nothing to do |
174 pass |
194 pass |
175 else: |
195 else: |
176 raise util.Abort(_("%s: unknown bundle compression type") |
196 raise util.Abort(_("%s: unknown bundle compression type") |
177 % bundlename) |
197 % bundlename) |
178 self.changelog = bundlechangelog(self.opener, self.bundlefile) |
198 self.changelog = bundlechangelog(self.opener, self.bundlefile) |
202 return filelog.filelog(self.opener, f) |
222 return filelog.filelog(self.opener, f) |
203 |
223 |
204 def close(self): |
224 def close(self): |
205 """Close assigned bundle file immediately.""" |
225 """Close assigned bundle file immediately.""" |
206 self.bundlefile.close() |
226 self.bundlefile.close() |
|
227 |
|
228 def __del__(self): |
|
229 if not self.bundlefile.closed: |
|
230 self.bundlefile.close() |
|
231 if self.tempfile is not None: |
|
232 os.unlink(self.tempfile) |