##// END OF EJS Templates
with: use context manager for transaction in changegroup apply...
Bryan O'Sullivan -
r27867:7ced54eb default
parent child Browse files
Show More
@@ -323,162 +323,165 b' class cg1unpacker(object):'
323
323
324 changesets = files = revisions = 0
324 changesets = files = revisions = 0
325
325
326 tr = repo.transaction("\n".join([srctype, util.hidepassword(url)]))
327 try:
326 try:
328 # The transaction could have been created before and already
327 with repo.transaction("\n".join([srctype,
329 # carries source information. In this case we use the top
328 util.hidepassword(url)])) as tr:
330 # level data. We overwrite the argument because we need to use
329 # The transaction could have been created before and already
331 # the top level value (if they exist) in this function.
330 # carries source information. In this case we use the top
332 srctype = tr.hookargs.setdefault('source', srctype)
331 # level data. We overwrite the argument because we need to use
333 url = tr.hookargs.setdefault('url', url)
332 # the top level value (if they exist) in this function.
334 repo.hook('prechangegroup', throw=True, **tr.hookargs)
333 srctype = tr.hookargs.setdefault('source', srctype)
334 url = tr.hookargs.setdefault('url', url)
335 repo.hook('prechangegroup', throw=True, **tr.hookargs)
335
336
336 # write changelog data to temp files so concurrent readers
337 # write changelog data to temp files so concurrent readers
337 # will not see an inconsistent view
338 # will not see an inconsistent view
338 cl = repo.changelog
339 cl = repo.changelog
339 cl.delayupdate(tr)
340 cl.delayupdate(tr)
340 oldheads = cl.heads()
341 oldheads = cl.heads()
341
342
342 trp = weakref.proxy(tr)
343 trp = weakref.proxy(tr)
343 # pull off the changeset group
344 # pull off the changeset group
344 repo.ui.status(_("adding changesets\n"))
345 repo.ui.status(_("adding changesets\n"))
345 clstart = len(cl)
346 clstart = len(cl)
346 class prog(object):
347 class prog(object):
347 def __init__(self, step, total):
348 def __init__(self, step, total):
348 self._step = step
349 self._step = step
349 self._total = total
350 self._total = total
350 self._count = 1
351 self._count = 1
351 def __call__(self):
352 def __call__(self):
352 repo.ui.progress(self._step, self._count, unit=_('chunks'),
353 repo.ui.progress(self._step, self._count,
353 total=self._total)
354 unit=_('chunks'), total=self._total)
354 self._count += 1
355 self._count += 1
355 self.callback = prog(_('changesets'), expectedtotal)
356 self.callback = prog(_('changesets'), expectedtotal)
356
357
357 efiles = set()
358 efiles = set()
358 def onchangelog(cl, node):
359 def onchangelog(cl, node):
359 efiles.update(cl.read(node)[3])
360 efiles.update(cl.read(node)[3])
360
361
361 self.changelogheader()
362 self.changelogheader()
362 srccontent = cl.addgroup(self, csmap, trp,
363 srccontent = cl.addgroup(self, csmap, trp,
363 addrevisioncb=onchangelog)
364 addrevisioncb=onchangelog)
364 efiles = len(efiles)
365 efiles = len(efiles)
365
366
366 if not (srccontent or emptyok):
367 if not (srccontent or emptyok):
367 raise error.Abort(_("received changelog group is empty"))
368 raise error.Abort(_("received changelog group is empty"))
368 clend = len(cl)
369 clend = len(cl)
369 changesets = clend - clstart
370 changesets = clend - clstart
370 repo.ui.progress(_('changesets'), None)
371 repo.ui.progress(_('changesets'), None)
371
372
372 # pull off the manifest group
373 # pull off the manifest group
373 repo.ui.status(_("adding manifests\n"))
374 repo.ui.status(_("adding manifests\n"))
374 self._unpackmanifests(repo, revmap, trp, prog, changesets)
375 self._unpackmanifests(repo, revmap, trp, prog, changesets)
375
376
376 needfiles = {}
377 needfiles = {}
377 if repo.ui.configbool('server', 'validate', default=False):
378 if repo.ui.configbool('server', 'validate', default=False):
378 # validate incoming csets have their manifests
379 # validate incoming csets have their manifests
379 for cset in xrange(clstart, clend):
380 for cset in xrange(clstart, clend):
380 mfnode = repo.changelog.read(repo.changelog.node(cset))[0]
381 mfnode = repo.changelog.read(
381 mfest = repo.manifest.readdelta(mfnode)
382 repo.changelog.node(cset))[0]
382 # store file nodes we must see
383 mfest = repo.manifest.readdelta(mfnode)
383 for f, n in mfest.iteritems():
384 # store file nodes we must see
384 needfiles.setdefault(f, set()).add(n)
385 for f, n in mfest.iteritems():
386 needfiles.setdefault(f, set()).add(n)
385
387
386 # process the files
388 # process the files
387 repo.ui.status(_("adding file changes\n"))
389 repo.ui.status(_("adding file changes\n"))
388 self.callback = None
390 self.callback = None
389 pr = prog(_('files'), efiles)
391 pr = prog(_('files'), efiles)
390 newrevs, newfiles = _addchangegroupfiles(
392 newrevs, newfiles = _addchangegroupfiles(
391 repo, self, revmap, trp, pr, needfiles)
393 repo, self, revmap, trp, pr, needfiles)
392 revisions += newrevs
394 revisions += newrevs
393 files += newfiles
395 files += newfiles
394
396
395 dh = 0
397 dh = 0
396 if oldheads:
398 if oldheads:
397 heads = cl.heads()
399 heads = cl.heads()
398 dh = len(heads) - len(oldheads)
400 dh = len(heads) - len(oldheads)
399 for h in heads:
401 for h in heads:
400 if h not in oldheads and repo[h].closesbranch():
402 if h not in oldheads and repo[h].closesbranch():
401 dh -= 1
403 dh -= 1
402 htext = ""
404 htext = ""
403 if dh:
405 if dh:
404 htext = _(" (%+d heads)") % dh
406 htext = _(" (%+d heads)") % dh
405
407
406 repo.ui.status(_("added %d changesets"
408 repo.ui.status(_("added %d changesets"
407 " with %d changes to %d files%s\n")
409 " with %d changes to %d files%s\n")
408 % (changesets, revisions, files, htext))
410 % (changesets, revisions, files, htext))
409 repo.invalidatevolatilesets()
411 repo.invalidatevolatilesets()
410
412
411 if changesets > 0:
413 if changesets > 0:
412 if 'node' not in tr.hookargs:
414 if 'node' not in tr.hookargs:
413 tr.hookargs['node'] = hex(cl.node(clstart))
415 tr.hookargs['node'] = hex(cl.node(clstart))
414 tr.hookargs['node_last'] = hex(cl.node(clend - 1))
416 tr.hookargs['node_last'] = hex(cl.node(clend - 1))
415 hookargs = dict(tr.hookargs)
417 hookargs = dict(tr.hookargs)
416 else:
418 else:
417 hookargs = dict(tr.hookargs)
419 hookargs = dict(tr.hookargs)
418 hookargs['node'] = hex(cl.node(clstart))
420 hookargs['node'] = hex(cl.node(clstart))
419 hookargs['node_last'] = hex(cl.node(clend - 1))
421 hookargs['node_last'] = hex(cl.node(clend - 1))
420 repo.hook('pretxnchangegroup', throw=True, **hookargs)
422 repo.hook('pretxnchangegroup', throw=True, **hookargs)
421
423
422 added = [cl.node(r) for r in xrange(clstart, clend)]
424 added = [cl.node(r) for r in xrange(clstart, clend)]
423 publishing = repo.publishing()
425 publishing = repo.publishing()
424 if srctype in ('push', 'serve'):
426 if srctype in ('push', 'serve'):
425 # Old servers can not push the boundary themselves.
427 # Old servers can not push the boundary themselves.
426 # New servers won't push the boundary if changeset already
428 # New servers won't push the boundary if changeset already
427 # exists locally as secret
429 # exists locally as secret
428 #
430 #
429 # We should not use added here but the list of all change in
431 # We should not use added here but the list of all change in
430 # the bundle
432 # the bundle
431 if publishing:
433 if publishing:
432 phases.advanceboundary(repo, tr, phases.public, srccontent)
434 phases.advanceboundary(repo, tr, phases.public,
433 else:
435 srccontent)
434 # Those changesets have been pushed from the outside, their
436 else:
435 # phases are going to be pushed alongside. Therefor
437 # Those changesets have been pushed from the
436 # `targetphase` is ignored.
438 # outside, their phases are going to be pushed
437 phases.advanceboundary(repo, tr, phases.draft, srccontent)
439 # alongside. Therefor `targetphase` is
438 phases.retractboundary(repo, tr, phases.draft, added)
440 # ignored.
439 elif srctype != 'strip':
441 phases.advanceboundary(repo, tr, phases.draft,
440 # publishing only alter behavior during push
442 srccontent)
441 #
443 phases.retractboundary(repo, tr, phases.draft, added)
442 # strip should not touch boundary at all
444 elif srctype != 'strip':
443 phases.retractboundary(repo, tr, targetphase, added)
445 # publishing only alter behavior during push
444
446 #
445 if changesets > 0:
447 # strip should not touch boundary at all
446 if srctype != 'strip':
448 phases.retractboundary(repo, tr, targetphase, added)
447 # During strip, branchcache is invalid but coming call to
448 # `destroyed` will repair it.
449 # In other case we can safely update cache on disk.
450 branchmap.updatecache(repo.filtered('served'))
451
449
452 def runhooks():
450 if changesets > 0:
453 # These hooks run when the lock releases, not when the
451 if srctype != 'strip':
454 # transaction closes. So it's possible for the changelog
452 # During strip, branchcache is invalid but
455 # to have changed since we last saw it.
453 # coming call to `destroyed` will repair it.
456 if clstart >= len(repo):
454 # In other case we can safely update cache on
457 return
455 # disk.
456 branchmap.updatecache(repo.filtered('served'))
458
457
459 # forcefully update the on-disk branch cache
458 def runhooks():
460 repo.ui.debug("updating the branch cache\n")
459 # These hooks run when the lock releases, not when the
461 repo.hook("changegroup", **hookargs)
460 # transaction closes. So it's possible for the changelog
461 # to have changed since we last saw it.
462 if clstart >= len(repo):
463 return
462
464
463 for n in added:
465 # forcefully update the on-disk branch cache
464 args = hookargs.copy()
466 repo.ui.debug("updating the branch cache\n")
465 args['node'] = hex(n)
467 repo.hook("changegroup", **hookargs)
466 del args['node_last']
468
467 repo.hook("incoming", **args)
469 for n in added:
470 args = hookargs.copy()
471 args['node'] = hex(n)
472 del args['node_last']
473 repo.hook("incoming", **args)
468
474
469 newheads = [h for h in repo.heads() if h not in oldheads]
475 newheads = [h for h in repo.heads()
470 repo.ui.log("incoming",
476 if h not in oldheads]
471 "%s incoming changes - new heads: %s\n",
477 repo.ui.log("incoming",
472 len(added),
478 "%s incoming changes - new heads: %s\n",
473 ', '.join([hex(c[:6]) for c in newheads]))
479 len(added),
480 ', '.join([hex(c[:6]) for c in newheads]))
474
481
475 tr.addpostclose('changegroup-runhooks-%020i' % clstart,
482 tr.addpostclose('changegroup-runhooks-%020i' % clstart,
476 lambda tr: repo._afterlock(runhooks))
483 lambda tr: repo._afterlock(runhooks))
477
478 tr.close()
479
480 finally:
484 finally:
481 tr.release()
482 repo.ui.flush()
485 repo.ui.flush()
483 # never return 0 here:
486 # never return 0 here:
484 if dh < 0:
487 if dh < 0:
General Comments 0
You need to be logged in to leave comments. Login now