142 # Empty src or already obsoleted - Do not return a destination |
142 # Empty src or already obsoleted - Do not return a destination |
143 if not src or src in obsoleted: |
143 if not src or src in obsoleted: |
144 return smartset.baseset() |
144 return smartset.baseset() |
145 dests = destutil.orphanpossibledestination(repo, src) |
145 dests = destutil.orphanpossibledestination(repo, src) |
146 if len(dests) > 1: |
146 if len(dests) > 1: |
147 raise error.Abort( |
147 raise error.StateError( |
148 _(b"ambiguous automatic rebase: %r could end up on any of %r") |
148 _(b"ambiguous automatic rebase: %r could end up on any of %r") |
149 % (src, dests) |
149 % (src, dests) |
150 ) |
150 ) |
151 # We have zero or one destination, so we can just return here. |
151 # We have zero or one destination, so we can just return here. |
152 return smartset.baseset(dests) |
152 return smartset.baseset(dests) |
422 |
422 |
423 (self.originalwd, self.destmap, self.state) = result |
423 (self.originalwd, self.destmap, self.state) = result |
424 if self.collapsef: |
424 if self.collapsef: |
425 dests = set(self.destmap.values()) |
425 dests = set(self.destmap.values()) |
426 if len(dests) != 1: |
426 if len(dests) != 1: |
427 raise error.Abort( |
427 raise error.InputError( |
428 _(b'--collapse does not work with multiple destinations') |
428 _(b'--collapse does not work with multiple destinations') |
429 ) |
429 ) |
430 destrev = next(iter(dests)) |
430 destrev = next(iter(dests)) |
431 destancestors = self.repo.changelog.ancestors( |
431 destancestors = self.repo.changelog.ancestors( |
432 [destrev], inclusive=True |
432 [destrev], inclusive=True |
467 if self.collapsef: |
467 if self.collapsef: |
468 branches = set() |
468 branches = set() |
469 for rev in self.state: |
469 for rev in self.state: |
470 branches.add(repo[rev].branch()) |
470 branches.add(repo[rev].branch()) |
471 if len(branches) > 1: |
471 if len(branches) > 1: |
472 raise error.Abort( |
472 raise error.InputError( |
473 _(b'cannot collapse multiple named branches') |
473 _(b'cannot collapse multiple named branches') |
474 ) |
474 ) |
475 |
475 |
476 # Calculate self.obsoletenotrebased |
476 # Calculate self.obsoletenotrebased |
477 obsrevs = _filterobsoleterevs(self.repo, self.state) |
477 obsrevs = _filterobsoleterevs(self.repo, self.state) |
1091 elif action == b'stop': |
1091 elif action == b'stop': |
1092 rbsrt = rebaseruntime(repo, ui) |
1092 rbsrt = rebaseruntime(repo, ui) |
1093 with repo.wlock(), repo.lock(): |
1093 with repo.wlock(), repo.lock(): |
1094 rbsrt.restorestatus() |
1094 rbsrt.restorestatus() |
1095 if rbsrt.collapsef: |
1095 if rbsrt.collapsef: |
1096 raise error.Abort(_(b"cannot stop in --collapse session")) |
1096 raise error.StateError(_(b"cannot stop in --collapse session")) |
1097 allowunstable = obsolete.isenabled(repo, obsolete.allowunstableopt) |
1097 allowunstable = obsolete.isenabled(repo, obsolete.allowunstableopt) |
1098 if not (rbsrt.keepf or allowunstable): |
1098 if not (rbsrt.keepf or allowunstable): |
1099 raise error.Abort( |
1099 raise error.StateError( |
1100 _( |
1100 _( |
1101 b"cannot remove original changesets with" |
1101 b"cannot remove original changesets with" |
1102 b" unrebased descendants" |
1102 b" unrebased descendants" |
1103 ), |
1103 ), |
1104 hint=_( |
1104 hint=_( |
1218 b"interactive history editing is supported by the " |
1218 b"interactive history editing is supported by the " |
1219 b"'histedit' extension (see \"%s\")" |
1219 b"'histedit' extension (see \"%s\")" |
1220 ) |
1220 ) |
1221 % help |
1221 % help |
1222 ) |
1222 ) |
1223 raise error.Abort(msg) |
1223 raise error.InputError(msg) |
1224 |
1224 |
1225 if rbsrt.collapsemsg and not rbsrt.collapsef: |
1225 if rbsrt.collapsemsg and not rbsrt.collapsef: |
1226 raise error.Abort(_(b'message can only be specified with collapse')) |
1226 raise error.InputError( |
|
1227 _(b'message can only be specified with collapse') |
|
1228 ) |
1227 |
1229 |
1228 if action: |
1230 if action: |
1229 if rbsrt.collapsef: |
1231 if rbsrt.collapsef: |
1230 raise error.Abort( |
1232 raise error.InputError( |
1231 _(b'cannot use collapse with continue or abort') |
1233 _(b'cannot use collapse with continue or abort') |
1232 ) |
1234 ) |
1233 if action == b'abort' and opts.get(b'tool', False): |
1235 if action == b'abort' and opts.get(b'tool', False): |
1234 ui.warn(_(b'tool option will be ignored\n')) |
1236 ui.warn(_(b'tool option will be ignored\n')) |
1235 if action == b'continue': |
1237 if action == b'continue': |
1292 cmdutil.checkunfinished(repo) |
1294 cmdutil.checkunfinished(repo) |
1293 if not inmemory: |
1295 if not inmemory: |
1294 cmdutil.bailifchanged(repo) |
1296 cmdutil.bailifchanged(repo) |
1295 |
1297 |
1296 if ui.configbool(b'commands', b'rebase.requiredest') and not destf: |
1298 if ui.configbool(b'commands', b'rebase.requiredest') and not destf: |
1297 raise error.Abort( |
1299 raise error.InputError( |
1298 _(b'you must specify a destination'), |
1300 _(b'you must specify a destination'), |
1299 hint=_(b'use: hg rebase -d REV'), |
1301 hint=_(b'use: hg rebase -d REV'), |
1300 ) |
1302 ) |
1301 |
1303 |
1302 dest = None |
1304 dest = None |
1386 % (b'+'.join(bytes(repo[r]) for r in base), dest) |
1388 % (b'+'.join(bytes(repo[r]) for r in base), dest) |
1387 ) |
1389 ) |
1388 return None |
1390 return None |
1389 |
1391 |
1390 if wdirrev in rebaseset: |
1392 if wdirrev in rebaseset: |
1391 raise error.Abort(_(b'cannot rebase the working copy')) |
1393 raise error.InputError(_(b'cannot rebase the working copy')) |
1392 rebasingwcp = repo[b'.'].rev() in rebaseset |
1394 rebasingwcp = repo[b'.'].rev() in rebaseset |
1393 ui.log( |
1395 ui.log( |
1394 b"rebase", |
1396 b"rebase", |
1395 b"rebasing working copy parent: %r\n", |
1397 b"rebasing working copy parent: %r\n", |
1396 rebasingwcp, |
1398 rebasingwcp, |
1424 if size == 1: |
1426 if size == 1: |
1425 destmap[r] = destset.first() |
1427 destmap[r] = destset.first() |
1426 elif size == 0: |
1428 elif size == 0: |
1427 ui.note(_(b'skipping %s - empty destination\n') % repo[r]) |
1429 ui.note(_(b'skipping %s - empty destination\n') % repo[r]) |
1428 else: |
1430 else: |
1429 raise error.Abort( |
1431 raise error.InputError( |
1430 _(b'rebase destination for %s is not unique') % repo[r] |
1432 _(b'rebase destination for %s is not unique') % repo[r] |
1431 ) |
1433 ) |
1432 |
1434 |
1433 if dest is not None: |
1435 if dest is not None: |
1434 # single-dest case: assign dest to each rev in rebaseset |
1436 # single-dest case: assign dest to each rev in rebaseset |
1457 parents.add(p.rev()) |
1459 parents.add(p.rev()) |
1458 if not parents: |
1460 if not parents: |
1459 return nullrev |
1461 return nullrev |
1460 if len(parents) == 1: |
1462 if len(parents) == 1: |
1461 return parents.pop() |
1463 return parents.pop() |
1462 raise error.Abort( |
1464 raise error.StateError( |
1463 _( |
1465 _( |
1464 b'unable to collapse on top of %d, there is more ' |
1466 b'unable to collapse on top of %d, there is more ' |
1465 b'than one external parent: %s' |
1467 b'than one external parent: %s' |
1466 ) |
1468 ) |
1467 % (max(destancestors), b', '.join(b"%d" % p for p in sorted(parents))) |
1469 % (max(destancestors), b', '.join(b"%d" % p for p in sorted(parents))) |
1657 msg = _(b"this rebase will cause divergences from: %s") |
1659 msg = _(b"this rebase will cause divergences from: %s") |
1658 h = _( |
1660 h = _( |
1659 b"to force the rebase please set " |
1661 b"to force the rebase please set " |
1660 b"experimental.evolution.allowdivergence=True" |
1662 b"experimental.evolution.allowdivergence=True" |
1661 ) |
1663 ) |
1662 raise error.Abort(msg % (b",".join(divhashes),), hint=h) |
1664 raise error.StateError(msg % (b",".join(divhashes),), hint=h) |
1663 |
1665 |
1664 |
1666 |
1665 def successorrevs(unfi, rev): |
1667 def successorrevs(unfi, rev): |
1666 """yield revision numbers for successors of rev""" |
1668 """yield revision numbers for successors of rev""" |
1667 assert unfi.filtername is None |
1669 assert unfi.filtername is None |
1760 # |
1762 # |
1761 # C # rebase -r C -d D |
1763 # C # rebase -r C -d D |
1762 # /| # None of A and B will be changed to D and rebase fails. |
1764 # /| # None of A and B will be changed to D and rebase fails. |
1763 # A B D |
1765 # A B D |
1764 if set(newps) == set(oldps) and dest not in newps: |
1766 if set(newps) == set(oldps) and dest not in newps: |
1765 raise error.Abort( |
1767 raise error.InputError( |
1766 _( |
1768 _( |
1767 b'cannot rebase %d:%s without ' |
1769 b'cannot rebase %d:%s without ' |
1768 b'moving at least one of its parents' |
1770 b'moving at least one of its parents' |
1769 ) |
1771 ) |
1770 % (rev, repo[rev]) |
1772 % (rev, repo[rev]) |
1772 |
1774 |
1773 # Source should not be ancestor of dest. The check here guarantees it's |
1775 # Source should not be ancestor of dest. The check here guarantees it's |
1774 # impossible. With multi-dest, the initial check does not cover complex |
1776 # impossible. With multi-dest, the initial check does not cover complex |
1775 # cases since we don't have abstractions to dry-run rebase cheaply. |
1777 # cases since we don't have abstractions to dry-run rebase cheaply. |
1776 if any(p != nullrev and isancestor(rev, p) for p in newps): |
1778 if any(p != nullrev and isancestor(rev, p) for p in newps): |
1777 raise error.Abort(_(b'source is ancestor of destination')) |
1779 raise error.InputError(_(b'source is ancestor of destination')) |
1778 |
1780 |
1779 # Check if the merge will contain unwanted changes. That may happen if |
1781 # Check if the merge will contain unwanted changes. That may happen if |
1780 # there are multiple special (non-changelog ancestor) merge bases, which |
1782 # there are multiple special (non-changelog ancestor) merge bases, which |
1781 # cannot be handled well by the 3-way merge algorithm. For example: |
1783 # cannot be handled well by the 3-way merge algorithm. For example: |
1782 # |
1784 # |
1834 b', '.join(b'%d:%s' % (r, repo[r]) for r in revs) |
1836 b', '.join(b'%d:%s' % (r, repo[r]) for r in revs) |
1835 for revs in unwanted |
1837 for revs in unwanted |
1836 if revs is not None |
1838 if revs is not None |
1837 ) |
1839 ) |
1838 ) |
1840 ) |
1839 raise error.Abort( |
1841 raise error.InputError( |
1840 _(b'rebasing %d:%s will include unwanted changes from %s') |
1842 _(b'rebasing %d:%s will include unwanted changes from %s') |
1841 % (rev, repo[rev], unwanteddesc) |
1843 % (rev, repo[rev], unwanteddesc) |
1842 ) |
1844 ) |
1843 |
1845 |
1844 # newps[0] should match merge base if possible. Currently, if newps[i] |
1846 # newps[0] should match merge base if possible. Currently, if newps[i] |
1999 # applied patch. But it prevents messing up the working directory when |
2001 # applied patch. But it prevents messing up the working directory when |
2000 # a partially completed rebase is blocked by mq. |
2002 # a partially completed rebase is blocked by mq. |
2001 if b'qtip' in repo.tags(): |
2003 if b'qtip' in repo.tags(): |
2002 mqapplied = {repo[s.node].rev() for s in repo.mq.applied} |
2004 mqapplied = {repo[s.node].rev() for s in repo.mq.applied} |
2003 if set(destmap.values()) & mqapplied: |
2005 if set(destmap.values()) & mqapplied: |
2004 raise error.Abort(_(b'cannot rebase onto an applied mq patch')) |
2006 raise error.StateError(_(b'cannot rebase onto an applied mq patch')) |
2005 |
2007 |
2006 # Get "cycle" error early by exhausting the generator. |
2008 # Get "cycle" error early by exhausting the generator. |
2007 sortedsrc = list(sortsource(destmap)) # a list of sorted revs |
2009 sortedsrc = list(sortsource(destmap)) # a list of sorted revs |
2008 if not sortedsrc: |
2010 if not sortedsrc: |
2009 raise error.Abort(_(b'no matching revisions')) |
2011 raise error.InputError(_(b'no matching revisions')) |
2010 |
2012 |
2011 # Only check the first batch of revisions to rebase not depending on other |
2013 # Only check the first batch of revisions to rebase not depending on other |
2012 # rebaseset. This means "source is ancestor of destination" for the second |
2014 # rebaseset. This means "source is ancestor of destination" for the second |
2013 # (and following) batches of revisions are not checked here. We rely on |
2015 # (and following) batches of revisions are not checked here. We rely on |
2014 # "defineparents" to do that check. |
2016 # "defineparents" to do that check. |
2015 roots = list(repo.set(b'roots(%ld)', sortedsrc[0])) |
2017 roots = list(repo.set(b'roots(%ld)', sortedsrc[0])) |
2016 if not roots: |
2018 if not roots: |
2017 raise error.Abort(_(b'no matching revisions')) |
2019 raise error.InputError(_(b'no matching revisions')) |
2018 |
2020 |
2019 def revof(r): |
2021 def revof(r): |
2020 return r.rev() |
2022 return r.rev() |
2021 |
2023 |
2022 roots = sorted(roots, key=revof) |
2024 roots = sorted(roots, key=revof) |
2024 emptyrebase = len(sortedsrc) == 1 |
2026 emptyrebase = len(sortedsrc) == 1 |
2025 for root in roots: |
2027 for root in roots: |
2026 dest = repo[destmap[root.rev()]] |
2028 dest = repo[destmap[root.rev()]] |
2027 commonbase = root.ancestor(dest) |
2029 commonbase = root.ancestor(dest) |
2028 if commonbase == root: |
2030 if commonbase == root: |
2029 raise error.Abort(_(b'source is ancestor of destination')) |
2031 raise error.InputError(_(b'source is ancestor of destination')) |
2030 if commonbase == dest: |
2032 if commonbase == dest: |
2031 wctx = repo[None] |
2033 wctx = repo[None] |
2032 if dest == wctx.p1(): |
2034 if dest == wctx.p1(): |
2033 # when rebasing to '.', it will use the current wd branch name |
2035 # when rebasing to '.', it will use the current wd branch name |
2034 samebranch = root.branch() == wctx.branch() |
2036 samebranch = root.branch() == wctx.branch() |
2117 """Call rebase after pull if the latter has been invoked with --rebase""" |
2119 """Call rebase after pull if the latter has been invoked with --rebase""" |
2118 if opts.get('rebase'): |
2120 if opts.get('rebase'): |
2119 if ui.configbool(b'commands', b'rebase.requiredest'): |
2121 if ui.configbool(b'commands', b'rebase.requiredest'): |
2120 msg = _(b'rebase destination required by configuration') |
2122 msg = _(b'rebase destination required by configuration') |
2121 hint = _(b'use hg pull followed by hg rebase -d DEST') |
2123 hint = _(b'use hg pull followed by hg rebase -d DEST') |
2122 raise error.Abort(msg, hint=hint) |
2124 raise error.InputError(msg, hint=hint) |
2123 |
2125 |
2124 with repo.wlock(), repo.lock(): |
2126 with repo.wlock(), repo.lock(): |
2125 if opts.get('update'): |
2127 if opts.get('update'): |
2126 del opts['update'] |
2128 del opts['update'] |
2127 ui.debug( |
2129 ui.debug( |
2174 # not passing argument to get the bare update behavior |
2176 # not passing argument to get the bare update behavior |
2175 # with warning and trumpets |
2177 # with warning and trumpets |
2176 commands.update(ui, repo) |
2178 commands.update(ui, repo) |
2177 else: |
2179 else: |
2178 if opts.get('tool'): |
2180 if opts.get('tool'): |
2179 raise error.Abort(_(b'--tool can only be used with --rebase')) |
2181 raise error.InputError(_(b'--tool can only be used with --rebase')) |
2180 ret = orig(ui, repo, *args, **opts) |
2182 ret = orig(ui, repo, *args, **opts) |
2181 |
2183 |
2182 return ret |
2184 return ret |
2183 |
2185 |
2184 |
2186 |