comparison hgext/histedit.py @ 22977:29ae3b190ec5

histedit: use state object where necessary We are using the properties from the state object where necessary and ensure that the state is set correctly.
author David Soria Parra <davidsp@fb.com>
date Tue, 14 Oct 2014 20:35:17 -0700
parents 886711722db6
children d4e764521249
comparison
equal deleted inserted replaced
22976:886711722db6 22977:29ae3b190ec5
558 if len(revs) != 1: 558 if len(revs) != 1:
559 raise util.Abort( 559 raise util.Abort(
560 _('histedit requires exactly one ancestor revision')) 560 _('histedit requires exactly one ancestor revision'))
561 561
562 562
563 replacements = []
564 keep = opts.get('keep', False)
565
566 # rebuild state
563 if goal == 'continue': 567 if goal == 'continue':
564 (parentctxnode, rules, keep, topmost, replacements) = readstate(repo) 568 state = readstate(repo)
565 parentctx = repo[parentctxnode] 569 parentctx = repo[state.parentctxnode]
566 parentctx, repl = bootstrapcontinue(ui, repo, parentctx, rules, opts) 570 parentctx, repl = bootstrapcontinue(ui, repo, parentctx, state.rules,
567 replacements.extend(repl) 571 opts)
572 state.replacements.extend(repl)
573 state.parentctxnode = parentctx.node()
568 elif goal == 'abort': 574 elif goal == 'abort':
569 (parentctxnode, rules, keep, topmost, replacements) = readstate(repo) 575 state = readstate(repo)
570 mapping, tmpnodes, leafs, _ntm = processreplacement(repo, replacements) 576 mapping, tmpnodes, leafs, _ntm = processreplacement(repo,
571 ui.debug('restore wc to old parent %s\n' % node.short(topmost)) 577 state.replacements)
578 ui.debug('restore wc to old parent %s\n' % node.short(state.topmost))
572 # check whether we should update away 579 # check whether we should update away
573 parentnodes = [c.node() for c in repo[None].parents()] 580 parentnodes = [c.node() for c in repo[None].parents()]
574 for n in leafs | set([parentctxnode]): 581 for n in leafs | set([state.parentctxnode]):
575 if n in parentnodes: 582 if n in parentnodes:
576 hg.clean(repo, topmost) 583 hg.clean(repo, state.topmost)
577 break 584 break
578 else: 585 else:
579 pass 586 pass
580 cleanupnode(ui, repo, 'created', tmpnodes) 587 cleanupnode(ui, repo, 'created', tmpnodes)
581 cleanupnode(ui, repo, 'temp', leafs) 588 cleanupnode(ui, repo, 'temp', leafs)
597 if len(rr) != 1: 604 if len(rr) != 1:
598 raise util.Abort(_('The specified revisions must have ' 605 raise util.Abort(_('The specified revisions must have '
599 'exactly one common root')) 606 'exactly one common root'))
600 root = rr[0].node() 607 root = rr[0].node()
601 608
602 keep = opts.get('keep', False)
603 revs = between(repo, root, topmost, keep) 609 revs = between(repo, root, topmost, keep)
604 if not revs: 610 if not revs:
605 raise util.Abort(_('%s is not an ancestor of working directory') % 611 raise util.Abort(_('%s is not an ancestor of working directory') %
606 node.short(root)) 612 node.short(root))
607 613
627 rules = [l for l in (r.strip() for r in rules.splitlines()) 633 rules = [l for l in (r.strip() for r in rules.splitlines())
628 if l and not l.startswith('#')] 634 if l and not l.startswith('#')]
629 rules = verifyrules(rules, repo, ctxs) 635 rules = verifyrules(rules, repo, ctxs)
630 636
631 parentctx = repo[root].parents()[0] 637 parentctx = repo[root].parents()[0]
632 replacements = [] 638
633 639 state = histeditstate(repo, parentctx.node(), rules, keep,
634 640 topmost, replacements)
635 while rules: 641
636 writestate(repo, parentctx.node(), rules, keep, topmost, replacements) 642 while state.rules:
637 action, ha = rules.pop(0) 643 state.write()
644 action, ha = state.rules.pop(0)
638 ui.debug('histedit: processing %s %s\n' % (action, ha)) 645 ui.debug('histedit: processing %s %s\n' % (action, ha))
639 actfunc = actiontable[action] 646 actfunc = actiontable[action]
640 parentctx, replacement_ = actfunc(ui, repo, parentctx, ha, opts) 647 parentctx = repo[state.parentctxnode]
641 replacements.extend(replacement_) 648 parentctx, replacement_ = actfunc(ui, repo, parentctx,
642 649 ha, opts)
643 hg.update(repo, parentctx.node()) 650 state.parentctxnode = parentctx.node()
644 651 state.replacements.extend(replacement_)
645 mapping, tmpnodes, created, ntm = processreplacement(repo, replacements) 652
653 hg.update(repo, state.parentctxnode)
654
655 mapping, tmpnodes, created, ntm = processreplacement(repo,
656 state.replacements)
646 if mapping: 657 if mapping:
647 for prec, succs in mapping.iteritems(): 658 for prec, succs in mapping.iteritems():
648 if not succs: 659 if not succs:
649 ui.debug('histedit: %s is dropped\n' % node.short(prec)) 660 ui.debug('histedit: %s is dropped\n' % node.short(prec))
650 else: 661 else:
655 for n in succs[1:]: 666 for n in succs[1:]:
656 ui.debug(m % node.short(n)) 667 ui.debug(m % node.short(n))
657 668
658 if not keep: 669 if not keep:
659 if mapping: 670 if mapping:
660 movebookmarks(ui, repo, mapping, topmost, ntm) 671 movebookmarks(ui, repo, mapping, state.topmost, ntm)
661 # TODO update mq state 672 # TODO update mq state
662 if obsolete.isenabled(repo, obsolete.createmarkersopt): 673 if obsolete.isenabled(repo, obsolete.createmarkersopt):
663 markers = [] 674 markers = []
664 # sort by revision number because it sound "right" 675 # sort by revision number because it sound "right"
665 for prec in sorted(mapping, key=repo.changelog.rev): 676 for prec in sorted(mapping, key=repo.changelog.rev):
765 root = ctxs[0] # list is already sorted by repo.set 776 root = ctxs[0] # list is already sorted by repo.set
766 if not root.mutable(): 777 if not root.mutable():
767 raise util.Abort(_('cannot edit immutable changeset: %s') % root) 778 raise util.Abort(_('cannot edit immutable changeset: %s') % root)
768 return [c.node() for c in ctxs] 779 return [c.node() for c in ctxs]
769 780
770
771 def writestate(repo, parentnode, rules, keep, topmost, replacements):
772 fp = open(os.path.join(repo.path, 'histedit-state'), 'w')
773 pickle.dump((parentnode, rules, keep, topmost, replacements), fp)
774 fp.close()
775
776 def readstate(repo): 781 def readstate(repo):
777 """Returns a tuple of (parentnode, rules, keep, topmost, replacements). 782 """Reads a state from file and returns a histeditstate object
778 """ 783 """
779 try: 784 try:
780 fp = open(os.path.join(repo.path, 'histedit-state')) 785 fp = repo.vfs('histedit-state', 'r')
781 except IOError, err: 786 except IOError, err:
782 if err.errno != errno.ENOENT: 787 if err.errno != errno.ENOENT:
783 raise 788 raise
784 raise util.Abort(_('no histedit in progress')) 789 raise util.Abort(_('no histedit in progress'))
785 return pickle.load(fp) 790
786 791 (parentctxnode, rules, keep, topmost, replacements) = pickle.load(fp)
792
793 return histeditstate(repo, parentctxnode, rules,
794 keep, topmost, replacements)
787 795
788 def makedesc(c): 796 def makedesc(c):
789 """build a initial action line for a ctx `c` 797 """build a initial action line for a ctx `c`
790 798
791 line are in the form: 799 line are in the form:
948 release(lock) 956 release(lock)
949 957
950 def summaryhook(ui, repo): 958 def summaryhook(ui, repo):
951 if not os.path.exists(repo.join('histedit-state')): 959 if not os.path.exists(repo.join('histedit-state')):
952 return 960 return
953 (parentctxnode, rules, keep, topmost, replacements) = readstate(repo) 961 state = readstate(repo)
954 if rules: 962 if state.rules:
955 # i18n: column positioning for "hg summary" 963 # i18n: column positioning for "hg summary"
956 ui.write(_('hist: %s (histedit --continue)\n') % 964 ui.write(_('hist: %s (histedit --continue)\n') %
957 (ui.label(_('%d remaining'), 'histedit.remaining') % 965 (ui.label(_('%d remaining'), 'histedit.remaining') %
958 len(rules))) 966 len(state.rules)))
959 967
960 def extsetup(ui): 968 def extsetup(ui):
961 cmdutil.summaryhooks.add('histedit', summaryhook) 969 cmdutil.summaryhooks.add('histedit', summaryhook)
962 cmdutil.unfinishedstates.append( 970 cmdutil.unfinishedstates.append(
963 ['histedit-state', False, True, _('histedit in progress'), 971 ['histedit-state', False, True, _('histedit in progress'),