Mercurial > hg
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: |