Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/localrepo.py @ 7803:6d99ff7b79b5
Merge with stable
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Fri, 27 Feb 2009 08:13:42 -0600 |
parents | dd970a311ea8 b8d750daadde |
children | 4421abf8c85d |
comparison
equal
deleted
inserted
replaced
7802:dd970a311ea8 | 7803:6d99ff7b79b5 |
---|---|
8 from node import bin, hex, nullid, nullrev, short | 8 from node import bin, hex, nullid, nullrev, short |
9 from i18n import _ | 9 from i18n import _ |
10 import repo, changegroup | 10 import repo, changegroup |
11 import changelog, dirstate, filelog, manifest, context, weakref | 11 import changelog, dirstate, filelog, manifest, context, weakref |
12 import lock, transaction, stat, errno, ui, store | 12 import lock, transaction, stat, errno, ui, store |
13 import os, revlog, time, util, extensions, hook, inspect | 13 import os, time, util, extensions, hook, inspect, error |
14 import match as match_ | 14 import match as match_ |
15 import merge as merge_ | 15 import merge as merge_ |
16 | 16 |
17 class localrepository(repo.repository): | 17 class localrepository(repo.repository): |
18 capabilities = util.set(('lookup', 'changegroupsubset')) | 18 capabilities = util.set(('lookup', 'changegroupsubset')) |
45 reqfile = self.opener("requires", "w") | 45 reqfile = self.opener("requires", "w") |
46 for r in requirements: | 46 for r in requirements: |
47 reqfile.write("%s\n" % r) | 47 reqfile.write("%s\n" % r) |
48 reqfile.close() | 48 reqfile.close() |
49 else: | 49 else: |
50 raise repo.RepoError(_("repository %s not found") % path) | 50 raise error.RepoError(_("repository %s not found") % path) |
51 elif create: | 51 elif create: |
52 raise repo.RepoError(_("repository %s already exists") % path) | 52 raise error.RepoError(_("repository %s already exists") % path) |
53 else: | 53 else: |
54 # find requirements | 54 # find requirements |
55 requirements = [] | 55 requirements = [] |
56 try: | 56 try: |
57 requirements = self.opener("requires").read().splitlines() | 57 requirements = self.opener("requires").read().splitlines() |
58 for r in requirements: | 58 for r in requirements: |
59 if r not in self.supported: | 59 if r not in self.supported: |
60 raise repo.RepoError(_("requirement '%s' not supported") % r) | 60 raise error.RepoError(_("requirement '%s' not supported") % r) |
61 except IOError, inst: | 61 except IOError, inst: |
62 if inst.errno != errno.ENOENT: | 62 if inst.errno != errno.ENOENT: |
63 raise | 63 raise |
64 | 64 |
65 self.store = store.store(requirements, self.path, util.opener) | 65 self.store = store.store(requirements, self.path, util.opener) |
86 self._transref = self._lockref = self._wlockref = None | 86 self._transref = self._lockref = self._wlockref = None |
87 | 87 |
88 def __getattr__(self, name): | 88 def __getattr__(self, name): |
89 if name == 'changelog': | 89 if name == 'changelog': |
90 self.changelog = changelog.changelog(self.sopener) | 90 self.changelog = changelog.changelog(self.sopener) |
91 if 'HG_PENDING' in os.environ: | |
92 p = os.environ['HG_PENDING'] | |
93 if p.startswith(self.root): | |
94 self.changelog.readpending('00changelog.i.a') | |
91 self.sopener.defversion = self.changelog.version | 95 self.sopener.defversion = self.changelog.version |
92 return self.changelog | 96 return self.changelog |
93 if name == 'manifest': | 97 if name == 'manifest': |
94 self.changelog | 98 self.changelog |
95 self.manifest = manifest.manifest(self.sopener) | 99 self.manifest = manifest.manifest(self.sopener) |
175 else: | 179 else: |
176 prevtags = fp.read() | 180 prevtags = fp.read() |
177 else: | 181 else: |
178 try: | 182 try: |
179 prevtags = self.filectx('.hgtags', parent).data() | 183 prevtags = self.filectx('.hgtags', parent).data() |
180 except revlog.LookupError: | 184 except error.LookupError: |
181 pass | 185 pass |
182 fp = self.wfile('.hgtags', 'wb') | 186 fp = self.wfile('.hgtags', 'wb') |
183 if prevtags: | 187 if prevtags: |
184 fp.write(prevtags) | 188 fp.write(prevtags) |
185 | 189 |
263 if key in filetags: | 267 if key in filetags: |
264 n, h = filetags[key] | 268 n, h = filetags[key] |
265 h.append(n) | 269 h.append(n) |
266 filetags[key] = (bin_n, h) | 270 filetags[key] = (bin_n, h) |
267 | 271 |
268 for k, nh in filetags.items(): | 272 for k, nh in filetags.iteritems(): |
269 if k not in globaltags: | 273 if k not in globaltags: |
270 globaltags[k] = nh | 274 globaltags[k] = nh |
271 tagtypes[k] = tagtype | 275 tagtypes[k] = tagtype |
272 continue | 276 continue |
273 | 277 |
299 except IOError: | 303 except IOError: |
300 pass | 304 pass |
301 | 305 |
302 self.tagscache = {} | 306 self.tagscache = {} |
303 self._tagstypecache = {} | 307 self._tagstypecache = {} |
304 for k,nh in globaltags.items(): | 308 for k, nh in globaltags.iteritems(): |
305 n = nh[0] | 309 n = nh[0] |
306 if n != nullid: | 310 if n != nullid: |
307 self.tagscache[k] = n | 311 self.tagscache[k] = n |
308 self._tagstypecache[k] = tagtypes[k] | 312 self._tagstypecache[k] = tagtypes[k] |
309 self.tagscache['tip'] = self.changelog.tip() | 313 self.tagscache['tip'] = self.changelog.tip() |
330 for node in heads: | 334 for node in heads: |
331 c = self[node] | 335 c = self[node] |
332 rev = c.rev() | 336 rev = c.rev() |
333 try: | 337 try: |
334 fnode = c.filenode('.hgtags') | 338 fnode = c.filenode('.hgtags') |
335 except revlog.LookupError: | 339 except error.LookupError: |
336 continue | 340 continue |
337 ret.append((rev, node, fnode)) | 341 ret.append((rev, node, fnode)) |
338 if fnode in last: | 342 if fnode in last: |
339 ret[last[fnode]] = None | 343 ret[last[fnode]] = None |
340 last[fnode] = len(ret) - 1 | 344 last[fnode] = len(ret) - 1 |
341 return [item for item in ret if item] | 345 return [item for item in ret if item] |
342 | 346 |
343 def tagslist(self): | 347 def tagslist(self): |
344 '''return a list of tags ordered by revision''' | 348 '''return a list of tags ordered by revision''' |
345 l = [] | 349 l = [] |
346 for t, n in self.tags().items(): | 350 for t, n in self.tags().iteritems(): |
347 try: | 351 try: |
348 r = self.changelog.rev(n) | 352 r = self.changelog.rev(n) |
349 except: | 353 except: |
350 r = -2 # sort to the beginning of the list if unknown | 354 r = -2 # sort to the beginning of the list if unknown |
351 l.append((r, t, n)) | 355 l.append((r, t, n)) |
353 | 357 |
354 def nodetags(self, node): | 358 def nodetags(self, node): |
355 '''return the tags associated with a node''' | 359 '''return the tags associated with a node''' |
356 if not self.nodetagscache: | 360 if not self.nodetagscache: |
357 self.nodetagscache = {} | 361 self.nodetagscache = {} |
358 for t, n in self.tags().items(): | 362 for t, n in self.tags().iteritems(): |
359 self.nodetagscache.setdefault(n, []).append(t) | 363 self.nodetagscache.setdefault(n, []).append(t) |
360 return self.nodetagscache.get(node, []) | 364 return self.nodetagscache.get(node, []) |
361 | 365 |
362 def _branchtags(self, partial, lrev): | 366 def _branchtags(self, partial, lrev): |
367 # TODO: rename this function? | |
363 tiprev = len(self) - 1 | 368 tiprev = len(self) - 1 |
364 if lrev != tiprev: | 369 if lrev != tiprev: |
365 self._updatebranchcache(partial, lrev+1, tiprev+1) | 370 self._updatebranchcache(partial, lrev+1, tiprev+1) |
366 self._writebranchcache(partial, self.changelog.tip(), tiprev) | 371 self._writebranchcache(partial, self.changelog.tip(), tiprev) |
367 | 372 |
368 return partial | 373 return partial |
369 | 374 |
370 def branchtags(self): | 375 def _branchheads(self): |
371 tip = self.changelog.tip() | 376 tip = self.changelog.tip() |
372 if self.branchcache is not None and self._branchcachetip == tip: | 377 if self.branchcache is not None and self._branchcachetip == tip: |
373 return self.branchcache | 378 return self.branchcache |
374 | 379 |
375 oldtip = self._branchcachetip | 380 oldtip = self._branchcachetip |
383 else: | 388 else: |
384 lrev = self.changelog.rev(oldtip) | 389 lrev = self.changelog.rev(oldtip) |
385 partial = self._ubranchcache | 390 partial = self._ubranchcache |
386 | 391 |
387 self._branchtags(partial, lrev) | 392 self._branchtags(partial, lrev) |
393 # this private cache holds all heads (not just tips) | |
394 self._ubranchcache = partial | |
388 | 395 |
389 # the branch cache is stored on disk as UTF-8, but in the local | 396 # the branch cache is stored on disk as UTF-8, but in the local |
390 # charset internally | 397 # charset internally |
391 for k, v in partial.items(): | 398 for k, v in partial.iteritems(): |
392 self.branchcache[util.tolocal(k)] = v | 399 self.branchcache[util.tolocal(k)] = v |
393 self._ubranchcache = partial | |
394 return self.branchcache | 400 return self.branchcache |
401 | |
402 | |
403 def branchtags(self): | |
404 '''return a dict where branch names map to the tipmost head of | |
405 the branch, open heads come before closed''' | |
406 bt = {} | |
407 for bn, heads in self._branchheads().iteritems(): | |
408 head = None | |
409 for i in range(len(heads)-1, -1, -1): | |
410 h = heads[i] | |
411 if 'close' not in self.changelog.read(h)[5]: | |
412 head = h | |
413 break | |
414 # no open heads were found | |
415 if head is None: | |
416 head = heads[-1] | |
417 bt[bn] = head | |
418 return bt | |
419 | |
395 | 420 |
396 def _readbranchcache(self): | 421 def _readbranchcache(self): |
397 partial = {} | 422 partial = {} |
398 try: | 423 try: |
399 f = self.opener("branch.cache") | 424 f = self.opener("branchheads.cache") |
400 lines = f.read().split('\n') | 425 lines = f.read().split('\n') |
401 f.close() | 426 f.close() |
402 except (IOError, OSError): | 427 except (IOError, OSError): |
403 return {}, nullid, nullrev | 428 return {}, nullid, nullrev |
404 | 429 |
409 # invalidate the cache | 434 # invalidate the cache |
410 raise ValueError('invalidating branch cache (tip differs)') | 435 raise ValueError('invalidating branch cache (tip differs)') |
411 for l in lines: | 436 for l in lines: |
412 if not l: continue | 437 if not l: continue |
413 node, label = l.split(" ", 1) | 438 node, label = l.split(" ", 1) |
414 partial[label.strip()] = bin(node) | 439 partial.setdefault(label.strip(), []).append(bin(node)) |
415 except (KeyboardInterrupt, util.SignalInterrupt): | 440 except KeyboardInterrupt: |
416 raise | 441 raise |
417 except Exception, inst: | 442 except Exception, inst: |
418 if self.ui.debugflag: | 443 if self.ui.debugflag: |
419 self.ui.warn(str(inst), '\n') | 444 self.ui.warn(str(inst), '\n') |
420 partial, last, lrev = {}, nullid, nullrev | 445 partial, last, lrev = {}, nullid, nullrev |
421 return partial, last, lrev | 446 return partial, last, lrev |
422 | 447 |
423 def _writebranchcache(self, branches, tip, tiprev): | 448 def _writebranchcache(self, branches, tip, tiprev): |
424 try: | 449 try: |
425 f = self.opener("branch.cache", "w", atomictemp=True) | 450 f = self.opener("branchheads.cache", "w", atomictemp=True) |
426 f.write("%s %s\n" % (hex(tip), tiprev)) | 451 f.write("%s %s\n" % (hex(tip), tiprev)) |
427 for label, node in branches.iteritems(): | 452 for label, nodes in branches.iteritems(): |
428 f.write("%s %s\n" % (hex(node), label)) | 453 for node in nodes: |
454 f.write("%s %s\n" % (hex(node), label)) | |
429 f.rename() | 455 f.rename() |
430 except (IOError, OSError): | 456 except (IOError, OSError): |
431 pass | 457 pass |
432 | 458 |
433 def _updatebranchcache(self, partial, start, end): | 459 def _updatebranchcache(self, partial, start, end): |
434 for r in xrange(start, end): | 460 for r in xrange(start, end): |
435 c = self[r] | 461 c = self[r] |
436 b = c.branch() | 462 b = c.branch() |
437 partial[b] = c.node() | 463 bheads = partial.setdefault(b, []) |
464 bheads.append(c.node()) | |
465 for p in c.parents(): | |
466 pn = p.node() | |
467 if pn in bheads: | |
468 bheads.remove(pn) | |
438 | 469 |
439 def lookup(self, key): | 470 def lookup(self, key): |
440 if isinstance(key, int): | 471 if isinstance(key, int): |
441 return self.changelog.node(key) | 472 return self.changelog.node(key) |
442 elif key == '.': | 473 elif key == '.': |
458 try: | 489 try: |
459 if len(key) == 20: | 490 if len(key) == 20: |
460 key = hex(key) | 491 key = hex(key) |
461 except: | 492 except: |
462 pass | 493 pass |
463 raise repo.RepoError(_("unknown revision '%s'") % key) | 494 raise error.RepoError(_("unknown revision '%s'") % key) |
464 | 495 |
465 def local(self): | 496 def local(self): |
466 return True | 497 return True |
467 | 498 |
468 def join(self, f): | 499 def join(self, f): |
564 if self._transref and self._transref(): | 595 if self._transref and self._transref(): |
565 return self._transref().nest() | 596 return self._transref().nest() |
566 | 597 |
567 # abort here if the journal already exists | 598 # abort here if the journal already exists |
568 if os.path.exists(self.sjoin("journal")): | 599 if os.path.exists(self.sjoin("journal")): |
569 raise repo.RepoError(_("journal already exists - run hg recover")) | 600 raise error.RepoError(_("journal already exists - run hg recover")) |
570 | 601 |
571 # save dirstate for rollback | 602 # save dirstate for rollback |
572 try: | 603 try: |
573 ds = self.opener("dirstate").read() | 604 ds = self.opener("dirstate").read() |
574 except IOError: | 605 except IOError: |
635 self._branchcachetip = None | 666 self._branchcachetip = None |
636 | 667 |
637 def _lock(self, lockname, wait, releasefn, acquirefn, desc): | 668 def _lock(self, lockname, wait, releasefn, acquirefn, desc): |
638 try: | 669 try: |
639 l = lock.lock(lockname, 0, releasefn, desc=desc) | 670 l = lock.lock(lockname, 0, releasefn, desc=desc) |
640 except lock.LockHeld, inst: | 671 except error.LockHeld, inst: |
641 if not wait: | 672 if not wait: |
642 raise | 673 raise |
643 self.ui.warn(_("waiting for lock on %s held by %r\n") % | 674 self.ui.warn(_("waiting for lock on %s held by %r\n") % |
644 (desc, inst.locker)) | 675 (desc, inst.locker)) |
645 # default to 600 seconds timeout | 676 # default to 600 seconds timeout |
747 | 778 |
748 def commit(self, files=None, text="", user=None, date=None, | 779 def commit(self, files=None, text="", user=None, date=None, |
749 match=None, force=False, force_editor=False, | 780 match=None, force=False, force_editor=False, |
750 p1=None, p2=None, extra={}, empty_ok=False): | 781 p1=None, p2=None, extra={}, empty_ok=False): |
751 wlock = lock = None | 782 wlock = lock = None |
783 if extra.get("close"): | |
784 force = True | |
752 if files: | 785 if files: |
753 files = util.unique(files) | 786 files = util.unique(files) |
754 try: | 787 try: |
755 wlock = self.wlock() | 788 wlock = self.wlock() |
756 lock = self.lock() | 789 lock = self.lock() |
924 del lines[0] | 957 del lines[0] |
925 if not lines and use_dirstate: | 958 if not lines and use_dirstate: |
926 raise util.Abort(_("empty commit message")) | 959 raise util.Abort(_("empty commit message")) |
927 text = '\n'.join(lines) | 960 text = '\n'.join(lines) |
928 | 961 |
962 self.changelog.delayupdate() | |
929 n = self.changelog.add(mn, changed + removed, text, trp, p1, p2, | 963 n = self.changelog.add(mn, changed + removed, text, trp, p1, p2, |
930 user, wctx.date(), extra) | 964 user, wctx.date(), extra) |
965 p = lambda: self.changelog.writepending() and self.root or "" | |
931 self.hook('pretxncommit', throw=True, node=hex(n), parent1=xp1, | 966 self.hook('pretxncommit', throw=True, node=hex(n), parent1=xp1, |
932 parent2=xp2) | 967 parent2=xp2, pending=p) |
968 self.changelog.finalize(trp) | |
933 tr.close() | 969 tr.close() |
934 | 970 |
935 if self.branchcache: | 971 if self.branchcache: |
936 self.branchtags() | 972 self.branchtags() |
937 | 973 |
1021 try: | 1057 try: |
1022 try: | 1058 try: |
1023 wlock = self.wlock(False) | 1059 wlock = self.wlock(False) |
1024 for f in fixup: | 1060 for f in fixup: |
1025 self.dirstate.normal(f) | 1061 self.dirstate.normal(f) |
1026 except lock.LockException: | 1062 except lock.LockError: |
1027 pass | 1063 pass |
1028 finally: | 1064 finally: |
1029 del wlock | 1065 del wlock |
1030 | 1066 |
1031 if not parentworking: | 1067 if not parentworking: |
1160 self.dirstate.add(dest) | 1196 self.dirstate.add(dest) |
1161 self.dirstate.copy(source, dest) | 1197 self.dirstate.copy(source, dest) |
1162 finally: | 1198 finally: |
1163 del wlock | 1199 del wlock |
1164 | 1200 |
1165 def heads(self, start=None): | 1201 def heads(self, start=None, closed=True): |
1166 heads = self.changelog.heads(start) | 1202 heads = self.changelog.heads(start) |
1203 def display(head): | |
1204 if closed: | |
1205 return True | |
1206 extras = self.changelog.read(head)[5] | |
1207 return ('close' not in extras) | |
1167 # sort the output in rev descending order | 1208 # sort the output in rev descending order |
1168 heads = [(-self.changelog.rev(h), h) for h in heads] | 1209 heads = [(-self.changelog.rev(h), h) for h in heads if display(h)] |
1169 return [n for (r, n) in util.sort(heads)] | 1210 return [n for (r, n) in util.sort(heads)] |
1170 | 1211 |
1171 def branchheads(self, branch=None, start=None): | 1212 def branchheads(self, branch=None, start=None, closed=True): |
1172 if branch is None: | 1213 if branch is None: |
1173 branch = self[None].branch() | 1214 branch = self[None].branch() |
1174 branches = self.branchtags() | 1215 branches = self._branchheads() |
1175 if branch not in branches: | 1216 if branch not in branches: |
1176 return [] | 1217 return [] |
1177 # The basic algorithm is this: | 1218 bheads = branches[branch] |
1178 # | 1219 # the cache returns heads ordered lowest to highest |
1179 # Start from the branch tip since there are no later revisions that can | 1220 bheads.reverse() |
1180 # possibly be in this branch, and the tip is a guaranteed head. | |
1181 # | |
1182 # Remember the tip's parents as the first ancestors, since these by | |
1183 # definition are not heads. | |
1184 # | |
1185 # Step backwards from the brach tip through all the revisions. We are | |
1186 # guaranteed by the rules of Mercurial that we will now be visiting the | |
1187 # nodes in reverse topological order (children before parents). | |
1188 # | |
1189 # If a revision is one of the ancestors of a head then we can toss it | |
1190 # out of the ancestors set (we've already found it and won't be | |
1191 # visiting it again) and put its parents in the ancestors set. | |
1192 # | |
1193 # Otherwise, if a revision is in the branch it's another head, since it | |
1194 # wasn't in the ancestor list of an existing head. So add it to the | |
1195 # head list, and add its parents to the ancestor list. | |
1196 # | |
1197 # If it is not in the branch ignore it. | |
1198 # | |
1199 # Once we have a list of heads, use nodesbetween to filter out all the | |
1200 # heads that cannot be reached from startrev. There may be a more | |
1201 # efficient way to do this as part of the previous algorithm. | |
1202 | |
1203 set = util.set | |
1204 heads = [self.changelog.rev(branches[branch])] | |
1205 # Don't care if ancestors contains nullrev or not. | |
1206 ancestors = set(self.changelog.parentrevs(heads[0])) | |
1207 for rev in xrange(heads[0] - 1, nullrev, -1): | |
1208 if rev in ancestors: | |
1209 ancestors.update(self.changelog.parentrevs(rev)) | |
1210 ancestors.remove(rev) | |
1211 elif self[rev].branch() == branch: | |
1212 heads.append(rev) | |
1213 ancestors.update(self.changelog.parentrevs(rev)) | |
1214 heads = [self.changelog.node(rev) for rev in heads] | |
1215 if start is not None: | 1221 if start is not None: |
1216 heads = self.changelog.nodesbetween([start], heads)[2] | 1222 # filter out the heads that cannot be reached from startrev |
1217 return heads | 1223 bheads = self.changelog.nodesbetween([start], bheads)[2] |
1224 if not closed: | |
1225 bheads = [h for h in bheads if | |
1226 ('close' not in self.changelog.read(h)[5])] | |
1227 return bheads | |
1218 | 1228 |
1219 def branches(self, nodes): | 1229 def branches(self, nodes): |
1220 if not nodes: | 1230 if not nodes: |
1221 nodes = [self.changelog.tip()] | 1231 nodes = [self.changelog.tip()] |
1222 b = [] | 1232 b = [] |
1391 search = newsearch | 1401 search = newsearch |
1392 | 1402 |
1393 # sanity check our fetch list | 1403 # sanity check our fetch list |
1394 for f in fetch.keys(): | 1404 for f in fetch.keys(): |
1395 if f in m: | 1405 if f in m: |
1396 raise repo.RepoError(_("already have changeset ") + short(f[:4])) | 1406 raise error.RepoError(_("already have changeset ") |
1407 + short(f[:4])) | |
1397 | 1408 |
1398 if base.keys() == [nullid]: | 1409 if base.keys() == [nullid]: |
1399 if force: | 1410 if force: |
1400 self.ui.warn(_("warning: repository is unrelated\n")) | 1411 self.ui.warn(_("warning: repository is unrelated\n")) |
1401 else: | 1412 else: |
1577 | 1588 |
1578 def changegroupinfo(self, nodes, source): | 1589 def changegroupinfo(self, nodes, source): |
1579 if self.ui.verbose or source == 'bundle': | 1590 if self.ui.verbose or source == 'bundle': |
1580 self.ui.status(_("%d changesets found\n") % len(nodes)) | 1591 self.ui.status(_("%d changesets found\n") % len(nodes)) |
1581 if self.ui.debugflag: | 1592 if self.ui.debugflag: |
1582 self.ui.debug(_("List of changesets:\n")) | 1593 self.ui.debug(_("list of changesets:\n")) |
1583 for node in nodes: | 1594 for node in nodes: |
1584 self.ui.debug("%s\n" % hex(node)) | 1595 self.ui.debug("%s\n" % hex(node)) |
1585 | 1596 |
1586 def changegroupsubset(self, bases, heads, source, extranodes=None): | 1597 def changegroupsubset(self, bases, heads, source, extranodes=None): |
1587 """This function generates a changegroup consisting of all the nodes | 1598 """This function generates a changegroup consisting of all the nodes |
1754 if r == next_rev[0]: | 1765 if r == next_rev[0]: |
1755 # If the last rev we looked at was the one just previous, | 1766 # If the last rev we looked at was the one just previous, |
1756 # we only need to see a diff. | 1767 # we only need to see a diff. |
1757 deltamf = mnfst.readdelta(mnfstnode) | 1768 deltamf = mnfst.readdelta(mnfstnode) |
1758 # For each line in the delta | 1769 # For each line in the delta |
1759 for f, fnode in deltamf.items(): | 1770 for f, fnode in deltamf.iteritems(): |
1760 f = changedfiles.get(f, None) | 1771 f = changedfiles.get(f, None) |
1761 # And if the file is in the list of files we care | 1772 # And if the file is in the list of files we care |
1762 # about. | 1773 # about. |
1763 if f is not None: | 1774 if f is not None: |
1764 # Get the changenode this manifest belongs to | 1775 # Get the changenode this manifest belongs to |
2028 if fl.addgroup(chunkiter, revmap, trp) is None: | 2039 if fl.addgroup(chunkiter, revmap, trp) is None: |
2029 raise util.Abort(_("received file revlog group is empty")) | 2040 raise util.Abort(_("received file revlog group is empty")) |
2030 revisions += len(fl) - o | 2041 revisions += len(fl) - o |
2031 files += 1 | 2042 files += 1 |
2032 | 2043 |
2033 # make changelog see real files again | |
2034 cl.finalize(trp) | |
2035 | |
2036 newheads = len(self.changelog.heads()) | 2044 newheads = len(self.changelog.heads()) |
2037 heads = "" | 2045 heads = "" |
2038 if oldheads and newheads != oldheads: | 2046 if oldheads and newheads != oldheads: |
2039 heads = _(" (%+d heads)") % (newheads - oldheads) | 2047 heads = _(" (%+d heads)") % (newheads - oldheads) |
2040 | 2048 |
2041 self.ui.status(_("added %d changesets" | 2049 self.ui.status(_("added %d changesets" |
2042 " with %d changes to %d files%s\n") | 2050 " with %d changes to %d files%s\n") |
2043 % (changesets, revisions, files, heads)) | 2051 % (changesets, revisions, files, heads)) |
2044 | 2052 |
2045 if changesets > 0: | 2053 if changesets > 0: |
2054 p = lambda: self.changelog.writepending() and self.root or "" | |
2046 self.hook('pretxnchangegroup', throw=True, | 2055 self.hook('pretxnchangegroup', throw=True, |
2047 node=hex(self.changelog.node(cor+1)), source=srctype, | 2056 node=hex(self.changelog.node(cor+1)), source=srctype, |
2048 url=url) | 2057 url=url, pending=p) |
2058 | |
2059 # make changelog see real files again | |
2060 cl.finalize(trp) | |
2049 | 2061 |
2050 tr.close() | 2062 tr.close() |
2051 finally: | 2063 finally: |
2052 del tr | 2064 del tr |
2053 | 2065 |
2073 fp = remote.stream_out() | 2085 fp = remote.stream_out() |
2074 l = fp.readline() | 2086 l = fp.readline() |
2075 try: | 2087 try: |
2076 resp = int(l) | 2088 resp = int(l) |
2077 except ValueError: | 2089 except ValueError: |
2078 raise util.UnexpectedOutput( | 2090 raise error.ResponseError( |
2079 _('Unexpected response from remote server:'), l) | 2091 _('Unexpected response from remote server:'), l) |
2080 if resp == 1: | 2092 if resp == 1: |
2081 raise util.Abort(_('operation forbidden by server')) | 2093 raise util.Abort(_('operation forbidden by server')) |
2082 elif resp == 2: | 2094 elif resp == 2: |
2083 raise util.Abort(_('locking the remote repository failed')) | 2095 raise util.Abort(_('locking the remote repository failed')) |
2086 self.ui.status(_('streaming all changes\n')) | 2098 self.ui.status(_('streaming all changes\n')) |
2087 l = fp.readline() | 2099 l = fp.readline() |
2088 try: | 2100 try: |
2089 total_files, total_bytes = map(int, l.split(' ', 1)) | 2101 total_files, total_bytes = map(int, l.split(' ', 1)) |
2090 except (ValueError, TypeError): | 2102 except (ValueError, TypeError): |
2091 raise util.UnexpectedOutput( | 2103 raise error.ResponseError( |
2092 _('Unexpected response from remote server:'), l) | 2104 _('Unexpected response from remote server:'), l) |
2093 self.ui.status(_('%d files to transfer, %s of data\n') % | 2105 self.ui.status(_('%d files to transfer, %s of data\n') % |
2094 (total_files, util.bytecount(total_bytes))) | 2106 (total_files, util.bytecount(total_bytes))) |
2095 start = time.time() | 2107 start = time.time() |
2096 for i in xrange(total_files): | 2108 for i in xrange(total_files): |
2098 l = fp.readline() | 2110 l = fp.readline() |
2099 try: | 2111 try: |
2100 name, size = l.split('\0', 1) | 2112 name, size = l.split('\0', 1) |
2101 size = int(size) | 2113 size = int(size) |
2102 except (ValueError, TypeError): | 2114 except (ValueError, TypeError): |
2103 raise util.UnexpectedOutput( | 2115 raise error.ResponseError( |
2104 _('Unexpected response from remote server:'), l) | 2116 _('Unexpected response from remote server:'), l) |
2105 self.ui.debug(_('adding %s (%s)\n') % (name, util.bytecount(size))) | 2117 self.ui.debug(_('adding %s (%s)\n') % (name, util.bytecount(size))) |
2106 ofp = self.sopener(name, 'w') | 2118 ofp = self.sopener(name, 'w') |
2107 for chunk in util.filechunkiter(fp, limit=size): | 2119 for chunk in util.filechunkiter(fp, limit=size): |
2108 ofp.write(chunk) | 2120 ofp.write(chunk) |