Mercurial > hg
comparison mercurial/localrepo.py @ 1981:736b6c96bbbc
make incoming work via ssh (issue139); move chunk code into separate module.
Incoming ssh needs to detect the end of the changegroup, otherwise it would
block trying to read from the ssh pipe. This is done by parsing the
changegroup chunks.
bundlerepo.getchunk() already is identical to
localrepo.addchangegroup.getchunk(), which is followed by getgroup which
looks much like what you can re-use in bundlerepository.__init__() and in
write_bundle(). bundlerevlog.__init__.genchunk() looks very similar, too,
as do some while loops in localrepo.py.
Applied patch from Benoit Boissinot to move duplicate/related code
to mercurial/changegroup.py and use this to fix incoming ssh.
author | Thomas Arendsen Hein <thomas@intevation.de> |
---|---|
date | Tue, 21 Mar 2006 11:47:21 +0100 |
parents | 72f7a335b955 |
children | ae12a81549a7 |
comparison
equal
deleted
inserted
replaced
1980:dfb796786337 | 1981:736b6c96bbbc |
---|---|
3 # Copyright 2005 Matt Mackall <mpm@selenic.com> | 3 # Copyright 2005 Matt Mackall <mpm@selenic.com> |
4 # | 4 # |
5 # This software may be used and distributed according to the terms | 5 # This software may be used and distributed according to the terms |
6 # of the GNU General Public License, incorporated herein by reference. | 6 # of the GNU General Public License, incorporated herein by reference. |
7 | 7 |
8 import struct, os, util | 8 import os, util |
9 import filelog, manifest, changelog, dirstate, repo | 9 import filelog, manifest, changelog, dirstate, repo |
10 from node import * | 10 from node import * |
11 from i18n import gettext as _ | 11 from i18n import gettext as _ |
12 from demandload import * | 12 from demandload import * |
13 demandload(globals(), "re lock transaction tempfile stat mdiff errno ui") | 13 demandload(globals(), "re lock transaction tempfile stat mdiff errno ui") |
14 demandload(globals(), "changegroup") | |
14 | 15 |
15 class localrepository(object): | 16 class localrepository(object): |
16 def __del__(self): | 17 def __del__(self): |
17 self.transhandle = None | 18 self.transhandle = None |
18 def __init__(self, parentui, path=None, create=0): | 19 def __init__(self, parentui, path=None, create=0): |
1242 else: | 1243 else: |
1243 msng_filenode_lst = [] | 1244 msng_filenode_lst = [] |
1244 # If any filenodes are left, generate the group for them, | 1245 # If any filenodes are left, generate the group for them, |
1245 # otherwise don't bother. | 1246 # otherwise don't bother. |
1246 if len(msng_filenode_lst) > 0: | 1247 if len(msng_filenode_lst) > 0: |
1247 yield struct.pack(">l", len(fname) + 4) + fname | 1248 yield changegroup.genchunk(fname) |
1248 # Sort the filenodes by their revision # | 1249 # Sort the filenodes by their revision # |
1249 msng_filenode_lst.sort(cmp_by_rev_func(filerevlog)) | 1250 msng_filenode_lst.sort(cmp_by_rev_func(filerevlog)) |
1250 # Create a group generator and only pass in a changenode | 1251 # Create a group generator and only pass in a changenode |
1251 # lookup function as we need to collect no information | 1252 # lookup function as we need to collect no information |
1252 # from filenodes. | 1253 # from filenodes. |
1256 yield chnk | 1257 yield chnk |
1257 if msng_filenode_set.has_key(fname): | 1258 if msng_filenode_set.has_key(fname): |
1258 # Don't need this anymore, toss it to free memory. | 1259 # Don't need this anymore, toss it to free memory. |
1259 del msng_filenode_set[fname] | 1260 del msng_filenode_set[fname] |
1260 # Signal that no more groups are left. | 1261 # Signal that no more groups are left. |
1261 yield struct.pack(">l", 0) | 1262 yield changegroup.closechunk() |
1262 | 1263 |
1263 self.hook('outgoing', node=hex(msng_cl_lst[0]), source=source) | 1264 self.hook('outgoing', node=hex(msng_cl_lst[0]), source=source) |
1264 | 1265 |
1265 return util.chunkbuffer(gengroup()) | 1266 return util.chunkbuffer(gengroup()) |
1266 | 1267 |
1316 for fname in changedfiles: | 1317 for fname in changedfiles: |
1317 filerevlog = self.file(fname) | 1318 filerevlog = self.file(fname) |
1318 nodeiter = gennodelst(filerevlog) | 1319 nodeiter = gennodelst(filerevlog) |
1319 nodeiter = list(nodeiter) | 1320 nodeiter = list(nodeiter) |
1320 if nodeiter: | 1321 if nodeiter: |
1321 yield struct.pack(">l", len(fname) + 4) + fname | 1322 yield changegroup.genchunk(fname) |
1322 lookup = lookuprevlink_func(filerevlog) | 1323 lookup = lookuprevlink_func(filerevlog) |
1323 for chnk in filerevlog.group(nodeiter, lookup): | 1324 for chnk in filerevlog.group(nodeiter, lookup): |
1324 yield chnk | 1325 yield chnk |
1325 | 1326 |
1326 yield struct.pack(">l", 0) | 1327 yield changegroup.closechunk() |
1327 self.hook('outgoing', node=hex(nodes[0]), source=source) | 1328 self.hook('outgoing', node=hex(nodes[0]), source=source) |
1328 | 1329 |
1329 return util.chunkbuffer(gengroup()) | 1330 return util.chunkbuffer(gengroup()) |
1330 | 1331 |
1331 def addchangegroup(self, source): | 1332 def addchangegroup(self, source): |
1332 | |
1333 def getchunk(): | |
1334 d = source.read(4) | |
1335 if not d: | |
1336 return "" | |
1337 l = struct.unpack(">l", d)[0] | |
1338 if l <= 4: | |
1339 return "" | |
1340 d = source.read(l - 4) | |
1341 if len(d) < l - 4: | |
1342 raise repo.RepoError(_("premature EOF reading chunk" | |
1343 " (got %d bytes, expected %d)") | |
1344 % (len(d), l - 4)) | |
1345 return d | |
1346 | |
1347 def getgroup(): | |
1348 while 1: | |
1349 c = getchunk() | |
1350 if not c: | |
1351 break | |
1352 yield c | |
1353 | 1333 |
1354 def csmap(x): | 1334 def csmap(x): |
1355 self.ui.debug(_("add changeset %s\n") % short(x)) | 1335 self.ui.debug(_("add changeset %s\n") % short(x)) |
1356 return self.changelog.count() | 1336 return self.changelog.count() |
1357 | 1337 |
1370 oldheads = len(self.changelog.heads()) | 1350 oldheads = len(self.changelog.heads()) |
1371 | 1351 |
1372 # pull off the changeset group | 1352 # pull off the changeset group |
1373 self.ui.status(_("adding changesets\n")) | 1353 self.ui.status(_("adding changesets\n")) |
1374 co = self.changelog.tip() | 1354 co = self.changelog.tip() |
1375 cn = self.changelog.addgroup(getgroup(), csmap, tr, 1) # unique | 1355 chunkiter = changegroup.chunkiter(source) |
1356 cn = self.changelog.addgroup(chunkiter, csmap, tr, 1) # unique | |
1376 cnr, cor = map(self.changelog.rev, (cn, co)) | 1357 cnr, cor = map(self.changelog.rev, (cn, co)) |
1377 if cn == nullid: | 1358 if cn == nullid: |
1378 cnr = cor | 1359 cnr = cor |
1379 changesets = cnr - cor | 1360 changesets = cnr - cor |
1380 | 1361 |
1381 # pull off the manifest group | 1362 # pull off the manifest group |
1382 self.ui.status(_("adding manifests\n")) | 1363 self.ui.status(_("adding manifests\n")) |
1383 mm = self.manifest.tip() | 1364 mm = self.manifest.tip() |
1384 mo = self.manifest.addgroup(getgroup(), revmap, tr) | 1365 chunkiter = changegroup.chunkiter(source) |
1366 mo = self.manifest.addgroup(chunkiter, revmap, tr) | |
1385 | 1367 |
1386 # process the files | 1368 # process the files |
1387 self.ui.status(_("adding file changes\n")) | 1369 self.ui.status(_("adding file changes\n")) |
1388 while 1: | 1370 while 1: |
1389 f = getchunk() | 1371 f = changegroup.getchunk(source) |
1390 if not f: | 1372 if not f: |
1391 break | 1373 break |
1392 self.ui.debug(_("adding %s revisions\n") % f) | 1374 self.ui.debug(_("adding %s revisions\n") % f) |
1393 fl = self.file(f) | 1375 fl = self.file(f) |
1394 o = fl.count() | 1376 o = fl.count() |
1395 n = fl.addgroup(getgroup(), revmap, tr) | 1377 chunkiter = changegroup.chunkiter(source) |
1378 n = fl.addgroup(chunkiter, revmap, tr) | |
1396 revisions += fl.count() - o | 1379 revisions += fl.count() - o |
1397 files += 1 | 1380 files += 1 |
1398 | 1381 |
1399 newheads = len(self.changelog.heads()) | 1382 newheads = len(self.changelog.heads()) |
1400 heads = "" | 1383 heads = "" |