Mercurial > hg
comparison hgext/histedit.py @ 19020:12c06686d371
histedit: move all arguments checks to the beginning of the command
This changeset move all checks and raises related to arguments
validation to the top of the file. This gathers all the logic in one
place and clarifies the code doing actual work. This paves the way for
splitting this gigantic function in separated functions.
A `goal` variable is introduced in the process. It holds the action to
be done by this invocation (new, continue or abort).
An invalid invocation is found in the process (the new code is a bit stricter).
author | Pierre-Yves David <pierre-yves.david@logilab.fr> |
---|---|
date | Tue, 16 Apr 2013 21:17:13 +0200 |
parents | 730614b9b352 |
children | 26b41a902195 |
comparison
equal
deleted
inserted
replaced
19019:53060cc1b601 | 19020:12c06686d371 |
---|---|
426 ('o', 'outgoing', False, _('changesets not found in destination')), | 426 ('o', 'outgoing', False, _('changesets not found in destination')), |
427 ('f', 'force', False, | 427 ('f', 'force', False, |
428 _('force outgoing even for unrelated repositories')), | 428 _('force outgoing even for unrelated repositories')), |
429 ('r', 'rev', [], _('first revision to be edited'))], | 429 ('r', 'rev', [], _('first revision to be edited'))], |
430 _("[PARENT]")) | 430 _("[PARENT]")) |
431 def histedit(ui, repo, *parent, **opts): | 431 def histedit(ui, repo, *freeargs, **opts): |
432 """interactively edit changeset history | 432 """interactively edit changeset history |
433 """ | 433 """ |
434 # TODO only abort if we try and histedit mq patches, not just | 434 # TODO only abort if we try and histedit mq patches, not just |
435 # blanket if mq patches are applied somewhere | 435 # blanket if mq patches are applied somewhere |
436 mq = getattr(repo, 'mq', None) | 436 mq = getattr(repo, 'mq', None) |
437 if mq and mq.applied: | 437 if mq and mq.applied: |
438 raise util.Abort(_('source has mq patches applied')) | 438 raise util.Abort(_('source has mq patches applied')) |
439 | 439 |
440 parent = list(parent) + opts.get('rev', []) | 440 # basic argument incompatibility processing |
441 outg = opts.get('outgoing') | |
442 cont = opts.get('continue') | |
443 abort = opts.get('abort') | |
444 force = opts.get('force') | |
445 rules = opts.get('commands', '') | |
446 revs = opts.get('rev', []) | |
447 goal = 'new' # This invocation goal, in new, continue, abort | |
448 if force and not outg: | |
449 raise util.Abort(_('--force only allowed with --outgoing')) | |
450 if cont: | |
451 if util.any((outg, abort, revs, freeargs, rules)): | |
452 raise util.Abort(_('no arguments allowed with --continue')) | |
453 goal = 'continue' | |
454 elif abort: | |
455 if util.any((outg, revs, freeargs, rules)): | |
456 raise util.Abort(_('no arguments allowed with --abort')) | |
457 goal = 'abort' | |
458 else: | |
459 if os.path.exists(os.path.join(repo.path, 'histedit-state')): | |
460 raise util.Abort(_('history edit already in progress, try ' | |
461 '--continue or --abort')) | |
462 if outg: | |
463 if revs: | |
464 raise util.Abort(_('no revisions allowed with --outgoing')) | |
465 if len(freeargs) > 1: | |
466 raise util.Abort( | |
467 _('only one repo argument allowed with --outgoing')) | |
468 else: | |
469 parent = list(freeargs) + opts.get('rev', []) | |
470 if len(parent) != 1: | |
471 raise util.Abort( | |
472 _('histedit requires exactly one parent revision')) | |
473 | |
441 if opts.get('outgoing'): | 474 if opts.get('outgoing'): |
442 if len(parent) > 1: | 475 if freeargs: |
443 raise util.Abort( | 476 parent = freeargs[0] |
444 _('only one repo argument allowed with --outgoing')) | |
445 elif parent: | |
446 parent = parent[0] | |
447 | 477 |
448 dest = ui.expandpath(parent or 'default-push', parent or 'default') | 478 dest = ui.expandpath(parent or 'default-push', parent or 'default') |
449 dest, revs = hg.parseurl(dest, None)[:2] | 479 dest, revs = hg.parseurl(dest, None)[:2] |
450 ui.status(_('comparing with %s\n') % util.hidepassword(dest)) | 480 ui.status(_('comparing with %s\n') % util.hidepassword(dest)) |
451 | 481 |
458 # hexlify nodes from outgoing, because we're going to parse | 488 # hexlify nodes from outgoing, because we're going to parse |
459 # parent[0] using revsingle below, and if the binary hash | 489 # parent[0] using revsingle below, and if the binary hash |
460 # contains special revset characters like ":" the revset | 490 # contains special revset characters like ":" the revset |
461 # parser can choke. | 491 # parser can choke. |
462 parent = [node.hex(n) for n in discovery.findcommonoutgoing( | 492 parent = [node.hex(n) for n in discovery.findcommonoutgoing( |
463 repo, other, revs, force=opts.get('force')).missing[0:1]] | 493 repo, other, revs, force=force).missing[0:1]] |
464 else: | 494 if not parent: |
465 if opts.get('force'): | 495 raise util.Abort(_('no outgoing ancestors')) |
466 raise util.Abort(_('--force only allowed with --outgoing')) | 496 |
467 | 497 if goal == 'continue': |
468 if opts.get('continue', False): | |
469 if len(parent) != 0: | |
470 raise util.Abort(_('no arguments allowed with --continue')) | |
471 (parentctxnode, rules, keep, topmost, replacements) = readstate(repo) | 498 (parentctxnode, rules, keep, topmost, replacements) = readstate(repo) |
472 currentparent, wantnull = repo.dirstate.parents() | 499 currentparent, wantnull = repo.dirstate.parents() |
473 parentctx = repo[parentctxnode] | 500 parentctx = repo[parentctxnode] |
474 parentctx, repl = bootstrapcontinue(ui, repo, parentctx, rules, opts) | 501 parentctx, repl = bootstrapcontinue(ui, repo, parentctx, rules, opts) |
475 replacements.extend(repl) | 502 replacements.extend(repl) |
476 elif opts.get('abort', False): | 503 elif goal == 'abort': |
477 if len(parent) != 0: | |
478 raise util.Abort(_('no arguments allowed with --abort')) | |
479 (parentctxnode, rules, keep, topmost, replacements) = readstate(repo) | 504 (parentctxnode, rules, keep, topmost, replacements) = readstate(repo) |
480 mapping, tmpnodes, leafs, _ntm = processreplacement(repo, replacements) | 505 mapping, tmpnodes, leafs, _ntm = processreplacement(repo, replacements) |
481 ui.debug('restore wc to old parent %s\n' % node.short(topmost)) | 506 ui.debug('restore wc to old parent %s\n' % node.short(topmost)) |
482 hg.clean(repo, topmost) | 507 hg.clean(repo, topmost) |
483 cleanupnode(ui, repo, 'created', tmpnodes) | 508 cleanupnode(ui, repo, 'created', tmpnodes) |
484 cleanupnode(ui, repo, 'temp', leafs) | 509 cleanupnode(ui, repo, 'temp', leafs) |
485 os.unlink(os.path.join(repo.path, 'histedit-state')) | 510 os.unlink(os.path.join(repo.path, 'histedit-state')) |
486 return | 511 return |
487 else: | 512 else: |
488 cmdutil.bailifchanged(repo) | 513 cmdutil.bailifchanged(repo) |
489 if os.path.exists(os.path.join(repo.path, 'histedit-state')): | |
490 raise util.Abort(_('history edit already in progress, try ' | |
491 '--continue or --abort')) | |
492 | 514 |
493 topmost, empty = repo.dirstate.parents() | 515 topmost, empty = repo.dirstate.parents() |
494 | 516 |
495 if len(parent) != 1: | |
496 raise util.Abort(_('histedit requires exactly one parent revision')) | |
497 parent = scmutil.revsingle(repo, parent[0]).node() | 517 parent = scmutil.revsingle(repo, parent[0]).node() |
498 | 518 |
499 keep = opts.get('keep', False) | 519 keep = opts.get('keep', False) |
500 revs = between(repo, parent, topmost, keep) | 520 revs = between(repo, parent, topmost, keep) |
501 if not revs: | 521 if not revs: |
502 raise util.Abort(_('%s is not an ancestor of working directory') % | 522 raise util.Abort(_('%s is not an ancestor of working directory') % |
503 node.short(parent)) | 523 node.short(parent)) |
504 | 524 |
505 ctxs = [repo[r] for r in revs] | 525 ctxs = [repo[r] for r in revs] |
506 rules = opts.get('commands', '') | |
507 if not rules: | 526 if not rules: |
508 rules = '\n'.join([makedesc(c) for c in ctxs]) | 527 rules = '\n'.join([makedesc(c) for c in ctxs]) |
509 rules += '\n\n' | 528 rules += '\n\n' |
510 rules += editcomment % (node.short(parent), node.short(topmost)) | 529 rules += editcomment % (node.short(parent), node.short(topmost)) |
511 rules = ui.edit(rules, ui.username()) | 530 rules = ui.edit(rules, ui.username()) |