223 except KeyError: |
223 except KeyError: |
224 enablehistedit = " --config extensions.histedit=" |
224 enablehistedit = " --config extensions.histedit=" |
225 help = "hg%s help -e histedit" % enablehistedit |
225 help = "hg%s help -e histedit" % enablehistedit |
226 msg = _("interactive history editing is supported by the " |
226 msg = _("interactive history editing is supported by the " |
227 "'histedit' extension (see \"%s\")") % help |
227 "'histedit' extension (see \"%s\")") % help |
228 raise util.Abort(msg) |
228 raise error.Abort(msg) |
229 |
229 |
230 if collapsemsg and not collapsef: |
230 if collapsemsg and not collapsef: |
231 raise util.Abort( |
231 raise error.Abort( |
232 _('message can only be specified with collapse')) |
232 _('message can only be specified with collapse')) |
233 |
233 |
234 if contf or abortf: |
234 if contf or abortf: |
235 if contf and abortf: |
235 if contf and abortf: |
236 raise util.Abort(_('cannot use both abort and continue')) |
236 raise error.Abort(_('cannot use both abort and continue')) |
237 if collapsef: |
237 if collapsef: |
238 raise util.Abort( |
238 raise error.Abort( |
239 _('cannot use collapse with continue or abort')) |
239 _('cannot use collapse with continue or abort')) |
240 if srcf or basef or destf: |
240 if srcf or basef or destf: |
241 raise util.Abort( |
241 raise error.Abort( |
242 _('abort and continue do not allow specifying revisions')) |
242 _('abort and continue do not allow specifying revisions')) |
243 if abortf and opts.get('tool', False): |
243 if abortf and opts.get('tool', False): |
244 ui.warn(_('tool option will be ignored\n')) |
244 ui.warn(_('tool option will be ignored\n')) |
245 |
245 |
246 try: |
246 try: |
253 ' only broken state is cleared)\n')) |
253 ' only broken state is cleared)\n')) |
254 return 0 |
254 return 0 |
255 else: |
255 else: |
256 msg = _('cannot continue inconsistent rebase') |
256 msg = _('cannot continue inconsistent rebase') |
257 hint = _('use "hg rebase --abort" to clear broken state') |
257 hint = _('use "hg rebase --abort" to clear broken state') |
258 raise util.Abort(msg, hint=hint) |
258 raise error.Abort(msg, hint=hint) |
259 if abortf: |
259 if abortf: |
260 return abort(repo, originalwd, target, state, |
260 return abort(repo, originalwd, target, state, |
261 activebookmark=activebookmark) |
261 activebookmark=activebookmark) |
262 else: |
262 else: |
263 if srcf and basef: |
263 if srcf and basef: |
264 raise util.Abort(_('cannot specify both a ' |
264 raise error.Abort(_('cannot specify both a ' |
265 'source and a base')) |
265 'source and a base')) |
266 if revf and basef: |
266 if revf and basef: |
267 raise util.Abort(_('cannot specify both a ' |
267 raise error.Abort(_('cannot specify both a ' |
268 'revision and a base')) |
268 'revision and a base')) |
269 if revf and srcf: |
269 if revf and srcf: |
270 raise util.Abort(_('cannot specify both a ' |
270 raise error.Abort(_('cannot specify both a ' |
271 'revision and a source')) |
271 'revision and a source')) |
272 |
272 |
273 cmdutil.checkunfinished(repo) |
273 cmdutil.checkunfinished(repo) |
274 cmdutil.bailifchanged(repo) |
274 cmdutil.bailifchanged(repo) |
275 |
275 |
333 |
333 |
334 allowunstable = obsolete.isenabled(repo, obsolete.allowunstableopt) |
334 allowunstable = obsolete.isenabled(repo, obsolete.allowunstableopt) |
335 if (not (keepf or allowunstable) |
335 if (not (keepf or allowunstable) |
336 and repo.revs('first(children(%ld) - %ld)', |
336 and repo.revs('first(children(%ld) - %ld)', |
337 rebaseset, rebaseset)): |
337 rebaseset, rebaseset)): |
338 raise util.Abort( |
338 raise error.Abort( |
339 _("can't remove original changesets with" |
339 _("can't remove original changesets with" |
340 " unrebased descendants"), |
340 " unrebased descendants"), |
341 hint=_('use --keep to keep original changesets')) |
341 hint=_('use --keep to keep original changesets')) |
342 |
342 |
343 obsoletenotrebased = {} |
343 obsoletenotrebased = {} |
359 ui.status(_('nothing to rebase\n')) |
359 ui.status(_('nothing to rebase\n')) |
360 return 1 |
360 return 1 |
361 |
361 |
362 root = min(rebaseset) |
362 root = min(rebaseset) |
363 if not keepf and not repo[root].mutable(): |
363 if not keepf and not repo[root].mutable(): |
364 raise util.Abort(_("can't rebase public changeset %s") |
364 raise error.Abort(_("can't rebase public changeset %s") |
365 % repo[root], |
365 % repo[root], |
366 hint=_('see "hg help phases" for details')) |
366 hint=_('see "hg help phases" for details')) |
367 |
367 |
368 originalwd, target, state = result |
368 originalwd, target, state = result |
369 if collapsef: |
369 if collapsef: |
382 if collapsef: |
382 if collapsef: |
383 branches = set() |
383 branches = set() |
384 for rev in state: |
384 for rev in state: |
385 branches.add(repo[rev].branch()) |
385 branches.add(repo[rev].branch()) |
386 if len(branches) > 1: |
386 if len(branches) > 1: |
387 raise util.Abort(_('cannot collapse multiple named ' |
387 raise error.Abort(_('cannot collapse multiple named ' |
388 'branches')) |
388 'branches')) |
389 |
389 |
390 # Rebase |
390 # Rebase |
391 if not targetancestors: |
391 if not targetancestors: |
392 targetancestors = repo.changelog.ancestors([target], inclusive=True) |
392 targetancestors = repo.changelog.ancestors([target], inclusive=True) |
562 parents.add(p.rev()) |
562 parents.add(p.rev()) |
563 if not parents: |
563 if not parents: |
564 return nullrev |
564 return nullrev |
565 if len(parents) == 1: |
565 if len(parents) == 1: |
566 return parents.pop() |
566 return parents.pop() |
567 raise util.Abort(_('unable to collapse on top of %s, there is more ' |
567 raise error.Abort(_('unable to collapse on top of %s, there is more ' |
568 'than one external parent: %s') % |
568 'than one external parent: %s') % |
569 (max(targetancestors), |
569 (max(targetancestors), |
570 ', '.join(str(p) for p in sorted(parents)))) |
570 ', '.join(str(p) for p in sorted(parents)))) |
571 |
571 |
572 def concludenode(repo, rev, p1, p2, commitmsg=None, editor=None, extrafn=None, |
572 def concludenode(repo, rev, p1, p2, commitmsg=None, editor=None, extrafn=None, |
675 p2 = target |
675 p2 = target |
676 else: |
676 else: |
677 p2 = state[p2n] |
677 p2 = state[p2n] |
678 else: # p2n external |
678 else: # p2n external |
679 if p2 != nullrev: # p1n external too => rev is a merged revision |
679 if p2 != nullrev: # p1n external too => rev is a merged revision |
680 raise util.Abort(_('cannot use revision %d as base, result ' |
680 raise error.Abort(_('cannot use revision %d as base, result ' |
681 'would have 3 parents') % rev) |
681 'would have 3 parents') % rev) |
682 p2 = p2n |
682 p2 = p2n |
683 repo.ui.debug(" future parents are %d and %d\n" % |
683 repo.ui.debug(" future parents are %d and %d\n" % |
684 (repo[p1].rev(), repo[p2].rev())) |
684 (repo[p1].rev(), repo[p2].rev())) |
685 |
685 |
864 # Legacy compat special case |
864 # Legacy compat special case |
865 else: |
865 else: |
866 state[repo[oldrev].rev()] = repo[newrev].rev() |
866 state[repo[oldrev].rev()] = repo[newrev].rev() |
867 |
867 |
868 if keepbranches is None: |
868 if keepbranches is None: |
869 raise util.Abort(_('.hg/rebasestate is incomplete')) |
869 raise error.Abort(_('.hg/rebasestate is incomplete')) |
870 |
870 |
871 skipped = set() |
871 skipped = set() |
872 # recompute the set of skipped revs |
872 # recompute the set of skipped revs |
873 if not collapse: |
873 if not collapse: |
874 seen = set([target]) |
874 seen = set([target]) |
883 return (originalwd, target, state, skipped, |
883 return (originalwd, target, state, skipped, |
884 collapse, keep, keepbranches, external, activebookmark) |
884 collapse, keep, keepbranches, external, activebookmark) |
885 except IOError as err: |
885 except IOError as err: |
886 if err.errno != errno.ENOENT: |
886 if err.errno != errno.ENOENT: |
887 raise |
887 raise |
888 raise util.Abort(_('no rebase in progress')) |
888 raise error.Abort(_('no rebase in progress')) |
889 |
889 |
890 def needupdate(repo, state): |
890 def needupdate(repo, state): |
891 '''check whether we should `update --clean` away from a merge, or if |
891 '''check whether we should `update --clean` away from a merge, or if |
892 somehow the working dir got forcibly updated, e.g. by older hg''' |
892 somehow the working dir got forcibly updated, e.g. by older hg''' |
893 parents = [p.rev() for p in repo.parents()] |
893 parents = [p.rev() for p in repo.parents()] |
957 # This check isn't strictly necessary, since mq detects commits over an |
957 # This check isn't strictly necessary, since mq detects commits over an |
958 # applied patch. But it prevents messing up the working directory when |
958 # applied patch. But it prevents messing up the working directory when |
959 # a partially completed rebase is blocked by mq. |
959 # a partially completed rebase is blocked by mq. |
960 if 'qtip' in repo.tags() and (dest.node() in |
960 if 'qtip' in repo.tags() and (dest.node() in |
961 [s.node for s in repo.mq.applied]): |
961 [s.node for s in repo.mq.applied]): |
962 raise util.Abort(_('cannot rebase onto an applied mq patch')) |
962 raise error.Abort(_('cannot rebase onto an applied mq patch')) |
963 |
963 |
964 roots = list(repo.set('roots(%ld)', rebaseset)) |
964 roots = list(repo.set('roots(%ld)', rebaseset)) |
965 if not roots: |
965 if not roots: |
966 raise util.Abort(_('no matching revisions')) |
966 raise error.Abort(_('no matching revisions')) |
967 roots.sort() |
967 roots.sort() |
968 state = {} |
968 state = {} |
969 detachset = set() |
969 detachset = set() |
970 for root in roots: |
970 for root in roots: |
971 commonbase = root.ancestor(dest) |
971 commonbase = root.ancestor(dest) |
972 if commonbase == root: |
972 if commonbase == root: |
973 raise util.Abort(_('source is ancestor of destination')) |
973 raise error.Abort(_('source is ancestor of destination')) |
974 if commonbase == dest: |
974 if commonbase == dest: |
975 samebranch = root.branch() == dest.branch() |
975 samebranch = root.branch() == dest.branch() |
976 if not collapse and samebranch and root in dest.children(): |
976 if not collapse and samebranch and root in dest.children(): |
977 repo.ui.debug('source is a child of destination\n') |
977 repo.ui.debug('source is a child of destination\n') |
978 return None |
978 return None |
1112 % repo._activebookmark) |
1112 % repo._activebookmark) |
1113 finally: |
1113 finally: |
1114 release(lock, wlock) |
1114 release(lock, wlock) |
1115 else: |
1115 else: |
1116 if opts.get('tool'): |
1116 if opts.get('tool'): |
1117 raise util.Abort(_('--tool can only be used with --rebase')) |
1117 raise error.Abort(_('--tool can only be used with --rebase')) |
1118 orig(ui, repo, *args, **opts) |
1118 orig(ui, repo, *args, **opts) |
1119 |
1119 |
1120 def _setrebasesetvisibility(repo, revs): |
1120 def _setrebasesetvisibility(repo, revs): |
1121 """store the currently rebased set on the repo object |
1121 """store the currently rebased set on the repo object |
1122 |
1122 |