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 = "" |