Mercurial > public > mercurial-scm > hg
comparison mercurial/bundle2.py @ 34150:e9e0e1143fc5
bundle2: move part iterator a separate class
Currently, the part iterator logic is tightly coupled with the part handling
logic, which means it's hard to replace the part handling logic without
duplicating the part iterator bits.
In a future diff we'll want to be able to replace all part handling, so let's
begin refactoring the part iterator logic to it's own class.
Differential Revision: https://phab.mercurial-scm.org/D703
author | Durham Goode <durham@fb.com> |
---|---|
date | Wed, 13 Sep 2017 17:16:45 -0700 |
parents | 5ede882c249c |
children | 550343626bb2 |
comparison
equal
deleted
inserted
replaced
34149:75cc1f1e11f2 | 34150:e9e0e1143fc5 |
---|---|
344 else: | 344 else: |
345 # the transactiongetter won't be used, but we might as well set it | 345 # the transactiongetter won't be used, but we might as well set it |
346 op = bundleoperation(repo, lambda: tr) | 346 op = bundleoperation(repo, lambda: tr) |
347 _processchangegroup(op, unbundler, tr, source, url, **kwargs) | 347 _processchangegroup(op, unbundler, tr, source, url, **kwargs) |
348 return op | 348 return op |
349 | |
350 class partiterator(object): | |
351 def __init__(self, unbundler): | |
352 self.unbundler = unbundler | |
353 | |
354 def __enter__(self): | |
355 return enumerate(self.unbundler.iterparts()) | |
356 | |
357 def __exit__(self, type, value, tb): | |
358 pass | |
349 | 359 |
350 def processbundle(repo, unbundler, transactiongetter=None, op=None): | 360 def processbundle(repo, unbundler, transactiongetter=None, op=None): |
351 """This function process a bundle, apply effect to/from a repo | 361 """This function process a bundle, apply effect to/from a repo |
352 | 362 |
353 It iterates over each part then searches for and uses the proper handling | 363 It iterates over each part then searches for and uses the proper handling |
376 msg.append(' no-transaction') | 386 msg.append(' no-transaction') |
377 else: | 387 else: |
378 msg.append(' with-transaction') | 388 msg.append(' with-transaction') |
379 msg.append('\n') | 389 msg.append('\n') |
380 repo.ui.debug(''.join(msg)) | 390 repo.ui.debug(''.join(msg)) |
381 iterparts = enumerate(unbundler.iterparts()) | 391 |
382 part = None | 392 with partiterator(unbundler) as parts: |
383 nbpart = 0 | 393 part = None |
384 try: | 394 nbpart = 0 |
385 for nbpart, part in iterparts: | |
386 _processpart(op, part) | |
387 except Exception as exc: | |
388 # Any exceptions seeking to the end of the bundle at this point are | |
389 # almost certainly related to the underlying stream being bad. | |
390 # And, chances are that the exception we're handling is related to | |
391 # getting in that bad state. So, we swallow the seeking error and | |
392 # re-raise the original error. | |
393 seekerror = False | |
394 try: | 395 try: |
395 for nbpart, part in iterparts: | 396 for nbpart, part in parts: |
396 # consume the bundle content | 397 _processpart(op, part) |
397 part.seek(0, 2) | 398 except Exception as exc: |
398 except Exception: | 399 # Any exceptions seeking to the end of the bundle at this point are |
399 seekerror = True | 400 # almost certainly related to the underlying stream being bad. |
400 | 401 # And, chances are that the exception we're handling is related to |
401 # Small hack to let caller code distinguish exceptions from bundle2 | 402 # getting in that bad state. So, we swallow the seeking error and |
402 # processing from processing the old format. This is mostly | 403 # re-raise the original error. |
403 # needed to handle different return codes to unbundle according to the | 404 seekerror = False |
404 # type of bundle. We should probably clean up or drop this return code | 405 try: |
405 # craziness in a future version. | 406 for nbpart, part in parts: |
406 exc.duringunbundle2 = True | 407 # consume the bundle content |
407 salvaged = [] | 408 part.seek(0, 2) |
408 replycaps = None | 409 except Exception: |
409 if op.reply is not None: | 410 seekerror = True |
410 salvaged = op.reply.salvageoutput() | 411 |
411 replycaps = op.reply.capabilities | 412 # Small hack to let caller code distinguish exceptions from bundle2 |
412 exc._replycaps = replycaps | 413 # processing from processing the old format. This is mostly needed |
413 exc._bundle2salvagedoutput = salvaged | 414 # to handle different return codes to unbundle according to the type |
414 | 415 # of bundle. We should probably clean up or drop this return code |
415 # Re-raising from a variable loses the original stack. So only use | 416 # craziness in a future version. |
416 # that form if we need to. | 417 exc.duringunbundle2 = True |
417 if seekerror: | 418 salvaged = [] |
418 raise exc | 419 replycaps = None |
419 else: | 420 if op.reply is not None: |
420 raise | 421 salvaged = op.reply.salvageoutput() |
421 finally: | 422 replycaps = op.reply.capabilities |
422 repo.ui.debug('bundle2-input-bundle: %i parts total\n' % nbpart) | 423 exc._replycaps = replycaps |
424 exc._bundle2salvagedoutput = salvaged | |
425 | |
426 # Re-raising from a variable loses the original stack. So only use | |
427 # that form if we need to. | |
428 if seekerror: | |
429 raise exc | |
430 else: | |
431 raise | |
432 finally: | |
433 repo.ui.debug('bundle2-input-bundle: %i parts total\n' % nbpart) | |
423 | 434 |
424 return op | 435 return op |
425 | 436 |
426 def _processchangegroup(op, cg, tr, source, url, **kwargs): | 437 def _processchangegroup(op, cg, tr, source, url, **kwargs): |
427 ret = cg.apply(op.repo, tr, source, url, **kwargs) | 438 ret = cg.apply(op.repo, tr, source, url, **kwargs) |