comparison hgext/rebase.py @ 35388:dd11df900f7f

rebase: replace --inmemory flag with rebase.experimental.inmemory config Differential Revision: https://phab.mercurial-scm.org/D1666
author Phil Cohen <phillco@fb.com>
date Mon, 11 Dec 2017 22:16:13 -0800
parents b9bdee046cc2
children 83014fa95435
comparison
equal deleted inserted replaced
35387:c0c6df81c9bb 35388:dd11df900f7f
134 desc += ' (%s)' % ' '.join(names) 134 desc += ' (%s)' % ' '.join(names)
135 return desc 135 return desc
136 136
137 class rebaseruntime(object): 137 class rebaseruntime(object):
138 """This class is a container for rebase runtime state""" 138 """This class is a container for rebase runtime state"""
139 def __init__(self, repo, ui, opts=None): 139 def __init__(self, repo, ui, inmemory=False, opts=None):
140 if opts is None: 140 if opts is None:
141 opts = {} 141 opts = {}
142 142
143 # prepared: whether we have rebasestate prepared or not. Currently it 143 # prepared: whether we have rebasestate prepared or not. Currently it
144 # decides whether "self.repo" is unfiltered or not. 144 # decides whether "self.repo" is unfiltered or not.
177 # keepopen is not meant for use on the command line, but by 177 # keepopen is not meant for use on the command line, but by
178 # other extensions 178 # other extensions
179 self.keepopen = opts.get('keepopen', False) 179 self.keepopen = opts.get('keepopen', False)
180 self.obsoletenotrebased = {} 180 self.obsoletenotrebased = {}
181 self.obsoletewithoutsuccessorindestination = set() 181 self.obsoletewithoutsuccessorindestination = set()
182 self.inmemory = opts.get('inmemory', False) 182 self.inmemory = inmemory
183 183
184 @property 184 @property
185 def repo(self): 185 def repo(self):
186 if self.prepared: 186 if self.prepared:
187 return self._repo.unfiltered() 187 return self._repo.unfiltered()
643 ('', 'keepbranches', False, _('keep original branch names')), 643 ('', 'keepbranches', False, _('keep original branch names')),
644 ('D', 'detach', False, _('(DEPRECATED)')), 644 ('D', 'detach', False, _('(DEPRECATED)')),
645 ('i', 'interactive', False, _('(DEPRECATED)')), 645 ('i', 'interactive', False, _('(DEPRECATED)')),
646 ('t', 'tool', '', _('specify merge tool')), 646 ('t', 'tool', '', _('specify merge tool')),
647 ('c', 'continue', False, _('continue an interrupted rebase')), 647 ('c', 'continue', False, _('continue an interrupted rebase')),
648 ('', 'inmemory', False, _('run rebase in-memory (EXPERIMENTAL)')),
649 ('a', 'abort', False, _('abort an interrupted rebase'))] + 648 ('a', 'abort', False, _('abort an interrupted rebase'))] +
650 cmdutil.formatteropts, 649 cmdutil.formatteropts,
651 _('[-s REV | -b REV] [-d REV] [OPTION]')) 650 _('[-s REV | -b REV] [-d REV] [OPTION]'))
652 def rebase(ui, repo, **opts): 651 def rebase(ui, repo, **opts):
653 """move changeset (and descendants) to a different branch 652 """move changeset (and descendants) to a different branch
755 unexpectedly:: 754 unexpectedly::
756 755
757 [rebase] 756 [rebase]
758 singletransaction = True 757 singletransaction = True
759 758
759 By default, rebase writes to the working copy, but you can configure it to
760 run in-memory for for better performance, and to allow it to run if the
761 working copy is dirty::
762
763 [rebase]
764 experimental.inmemory = True
765
760 Return Values: 766 Return Values:
761 767
762 Returns 0 on success, 1 if nothing to rebase or there are 768 Returns 0 on success, 1 if nothing to rebase or there are
763 unresolved conflicts. 769 unresolved conflicts.
764 770
765 """ 771 """
772 inmemory = ui.configbool('rebase', 'experimental.inmemory')
766 if opts.get('continue') or opts.get('abort'): 773 if opts.get('continue') or opts.get('abort'):
767 # in-memory rebase is not compatible with resuming rebases. 774 # in-memory rebase is not compatible with resuming rebases.
768 opts['inmemory'] = False 775 inmemory = False
769 776
770 if opts.get('inmemory', False): 777 if inmemory:
771 try: 778 try:
772 # in-memory merge doesn't support conflicts, so if we hit any, abort 779 # in-memory merge doesn't support conflicts, so if we hit any, abort
773 # and re-run as an on-disk merge. 780 # and re-run as an on-disk merge.
774 return _origrebase(ui, repo, **opts) 781 return _origrebase(ui, repo, inmemory=inmemory, **opts)
775 except error.InMemoryMergeConflictsError: 782 except error.InMemoryMergeConflictsError:
776 ui.warn(_('hit merge conflicts; re-running rebase without in-memory' 783 ui.warn(_('hit merge conflicts; re-running rebase without in-memory'
777 ' merge\n')) 784 ' merge\n'))
778 _origrebase(ui, repo, **{'abort': True}) 785 _origrebase(ui, repo, **{'abort': True})
779 opts['inmemory'] = False 786 return _origrebase(ui, repo, inmemory=False, **opts)
780 return _origrebase(ui, repo, **opts)
781 else: 787 else:
782 return _origrebase(ui, repo, **opts) 788 return _origrebase(ui, repo, **opts)
783 789
784 def _origrebase(ui, repo, **opts): 790 def _origrebase(ui, repo, inmemory=False, **opts):
785 opts = pycompat.byteskwargs(opts) 791 opts = pycompat.byteskwargs(opts)
786 if 'inmemory' not in opts: 792 rbsrt = rebaseruntime(repo, ui, inmemory, opts)
787 opts['inmemory'] = False
788 rbsrt = rebaseruntime(repo, ui, opts)
789 793
790 with repo.wlock(), repo.lock(): 794 with repo.wlock(), repo.lock():
791 # Validate input and define rebasing points 795 # Validate input and define rebasing points
792 destf = opts.get('dest', None) 796 destf = opts.get('dest', None)
793 srcf = opts.get('source', None) 797 srcf = opts.get('source', None)
830 834
831 retcode = rbsrt._prepareabortorcontinue(abortf) 835 retcode = rbsrt._prepareabortorcontinue(abortf)
832 if retcode is not None: 836 if retcode is not None:
833 return retcode 837 return retcode
834 else: 838 else:
835 destmap = _definedestmap(ui, repo, destf, srcf, basef, revf, 839 destmap = _definedestmap(ui, repo, rbsrt, destf, srcf, basef, revf,
836 destspace=destspace, 840 destspace=destspace)
837 opts=opts)
838 rbsrt.inmemory = opts['inmemory']
839 retcode = rbsrt._preparenewrebase(destmap) 841 retcode = rbsrt._preparenewrebase(destmap)
840 if retcode is not None: 842 if retcode is not None:
841 return retcode 843 return retcode
842 844
843 tr = None 845 tr = None
852 with util.acceptintervention(dsguard): 854 with util.acceptintervention(dsguard):
853 rbsrt._performrebase(tr) 855 rbsrt._performrebase(tr)
854 856
855 rbsrt._finishrebase() 857 rbsrt._finishrebase()
856 858
857 def _definedestmap(ui, repo, destf=None, srcf=None, basef=None, revf=None, 859 def _definedestmap(ui, repo, rbsrt, destf=None, srcf=None, basef=None,
858 destspace=None, opts=None): 860 revf=None, destspace=None):
859 """use revisions argument to define destmap {srcrev: destrev}""" 861 """use revisions argument to define destmap {srcrev: destrev}"""
860 if revf is None: 862 if revf is None:
861 revf = [] 863 revf = []
862 864
863 # destspace is here to work around issues with `hg pull --rebase` see 865 # destspace is here to work around issues with `hg pull --rebase` see
867 if revf and basef: 869 if revf and basef:
868 raise error.Abort(_('cannot specify both a revision and a base')) 870 raise error.Abort(_('cannot specify both a revision and a base'))
869 if revf and srcf: 871 if revf and srcf:
870 raise error.Abort(_('cannot specify both a revision and a source')) 872 raise error.Abort(_('cannot specify both a revision and a source'))
871 873
872 if not opts['inmemory']: 874 if not rbsrt.inmemory:
873 cmdutil.checkunfinished(repo) 875 cmdutil.checkunfinished(repo)
874 cmdutil.bailifchanged(repo) 876 cmdutil.bailifchanged(repo)
875 877
876 if ui.configbool('commands', 'rebase.requiredest') and not destf: 878 if ui.configbool('commands', 'rebase.requiredest') and not destf:
877 raise error.Abort(_('you must specify a destination'), 879 raise error.Abort(_('you must specify a destination'),
953 # 955 #
954 # Note that there are cases where this isn't true -- e.g., rebasing large 956 # Note that there are cases where this isn't true -- e.g., rebasing large
955 # stacks that include the WCP. However, I'm not yet sure where the cutoff 957 # stacks that include the WCP. However, I'm not yet sure where the cutoff
956 # is. 958 # is.
957 rebasingwcp = repo['.'].rev() in rebaseset 959 rebasingwcp = repo['.'].rev() in rebaseset
958 if opts['inmemory'] and rebasingwcp: 960 if rbsrt.inmemory and rebasingwcp:
959 opts['inmemory'] = False 961 rbsrt.inmemory = False
960 # Check these since we did not before. 962 # Check these since we did not before.
961 cmdutil.checkunfinished(repo) 963 cmdutil.checkunfinished(repo)
962 cmdutil.bailifchanged(repo) 964 cmdutil.bailifchanged(repo)
963 965
964 if not destf: 966 if not destf: