146 ##################################################################### |
146 ##################################################################### |
147 |
147 |
148 class exthelper(object): |
148 class exthelper(object): |
149 """Helper for modular extension setup |
149 """Helper for modular extension setup |
150 |
150 |
151 A single helper should be instanciated for each extension. Helper |
151 A single helper should be instantiated for each extension. Helper |
152 methods are then used as decorator for various purpose. |
152 methods are then used as decorators for various purpose. |
153 |
153 |
154 All decorators return the original function and may be chained. |
154 All decorators return the original function and may be chained. |
155 """ |
155 """ |
156 |
156 |
157 def __init__(self): |
157 def __init__(self): |
794 try: |
794 try: |
795 histedit = extensions.find('histedit') |
795 histedit = extensions.find('histedit') |
796 if histedit: |
796 if histedit: |
797 extensions.wrapcommand(histedit.cmdtable, 'histedit', warnobserrors) |
797 extensions.wrapcommand(histedit.cmdtable, 'histedit', warnobserrors) |
798 except KeyError: |
798 except KeyError: |
799 pass # rebase not found |
799 pass # histedit not found |
800 |
800 |
801 ##################################################################### |
801 ##################################################################### |
802 ### Old Evolve extension content ### |
802 ### Old Evolve extension content ### |
803 ##################################################################### |
803 ##################################################################### |
804 |
804 |
1100 _deprecatealias('gup', 'next') |
1100 _deprecatealias('gup', 'next') |
1101 _deprecatealias('gdown', 'previous') |
1101 _deprecatealias('gdown', 'previous') |
1102 |
1102 |
1103 @command('debugrecordpruneparents', [], '') |
1103 @command('debugrecordpruneparents', [], '') |
1104 def cmddebugrecordpruneparents(ui, repo): |
1104 def cmddebugrecordpruneparents(ui, repo): |
1105 """add parents data to prune markers when possible |
1105 """add parent data to prune markers when possible |
1106 |
1106 |
1107 This commands search the repo for prune markers without parent information. |
1107 This command searches the repo for prune markers without parent information. |
1108 If the pruned node is locally known, a new markers with parent data is |
1108 If the pruned node is locally known, it creates a new marker with parent |
1109 created.""" |
1109 data. |
|
1110 """ |
1110 pgop = 'reading markers' |
1111 pgop = 'reading markers' |
1111 |
1112 |
1112 # lock from the beginning to prevent race |
1113 # lock from the beginning to prevent race |
1113 wlock = lock = tr = None |
1114 wlock = lock = tr = None |
1114 try: |
1115 try: |
1136 finally: |
1137 finally: |
1137 lockmod.release(tr, lock, wlock) |
1138 lockmod.release(tr, lock, wlock) |
1138 |
1139 |
1139 @command('debugobsstorestat', [], '') |
1140 @command('debugobsstorestat', [], '') |
1140 def cmddebugobsstorestat(ui, repo): |
1141 def cmddebugobsstorestat(ui, repo): |
|
1142 """print statistics about obsolescence markers in the repo""" |
1141 def _updateclustermap(nodes, mark, clustersmap): |
1143 def _updateclustermap(nodes, mark, clustersmap): |
1142 c = (set(nodes), set([mark])) |
1144 c = (set(nodes), set([mark])) |
1143 toproceed = set(nodes) |
1145 toproceed = set(nodes) |
1144 while toproceed: |
1146 while toproceed: |
1145 n = toproceed.pop() |
1147 n = toproceed.pop() |
1153 continue |
1155 continue |
1154 clustersmap[on] = other |
1156 clustersmap[on] = other |
1155 c = other |
1157 c = other |
1156 clustersmap[n] = c |
1158 clustersmap[n] = c |
1157 |
1159 |
1158 """print statistic about obsolescence markers in the repo""" |
|
1159 store = repo.obsstore |
1160 store = repo.obsstore |
1160 unfi = repo.unfiltered() |
1161 unfi = repo.unfiltered() |
1161 nm = unfi.changelog.nodemap |
1162 nm = unfi.changelog.nodemap |
1162 ui.write(_('markers total: %9i\n') % len(store._all)) |
1163 ui.write(_('markers total: %9i\n') % len(store._all)) |
1163 sucscount = [0, 0 , 0, 0] |
1164 sucscount = [0, 0 , 0, 0] |
1368 ui.progress(_('evolve'), None) |
1369 ui.progress(_('evolve'), None) |
1369 if repo['.'] != startnode: |
1370 if repo['.'] != startnode: |
1370 ui.status(_('working directory is now at %s\n') % repo['.']) |
1371 ui.status(_('working directory is now at %s\n') % repo['.']) |
1371 |
1372 |
1372 class MultipleSuccessorsError(RuntimeError): |
1373 class MultipleSuccessorsError(RuntimeError): |
1373 """Exception raised by _singlesuccessor when multiple sucessors sets exists |
1374 """Exception raised by _singlesuccessor when multiple successor sets exists |
1374 |
1375 |
1375 The object contains the list of successorssets in its 'successorssets' |
1376 The object contains the list of successorssets in its 'successorssets' |
1376 attribute to call to easily recover. |
1377 attribute to call to easily recover. |
1377 """ |
1378 """ |
1378 |
1379 |
1472 |
1473 |
1473 |
1474 |
1474 def _orderrevs(repo, revs): |
1475 def _orderrevs(repo, revs): |
1475 """Compute an ordering to solve instability for the given revs |
1476 """Compute an ordering to solve instability for the given revs |
1476 |
1477 |
1477 - Takes revs a list of instable revisions |
1478 revs is a list of unstable revisions. |
1478 |
1479 |
1479 - Returns the same revisions ordered to solve their instability from the |
1480 Returns the same revisions ordered to solve their instability from the |
1480 bottom to the top of the stack that the stabilization process will produce |
1481 bottom to the top of the stack that the stabilization process will produce |
1481 eventually. |
1482 eventually. |
1482 |
1483 |
1483 This ensure the minimal number of stabilization as we can stabilize each |
1484 This ensures the minimal number of stabilizations, as we can stabilize each |
1484 revision on its final, stabilized, destination. |
1485 revision on its final stabilized destination. |
1485 """ |
1486 """ |
1486 # Step 1: Build the dependency graph |
1487 # Step 1: Build the dependency graph |
1487 dependencies, rdependencies = builddependencies(repo, revs) |
1488 dependencies, rdependencies = builddependencies(repo, revs) |
1488 # Step 2: Build the ordering |
1489 # Step 2: Build the ordering |
1489 # Remove the revisions with no dependency(A) and add them to the ordering. |
1490 # Remove the revisions with no dependency(A) and add them to the ordering. |
1730 result.add(unstable) |
1731 result.add(unstable) |
1731 return sorted(result - target) |
1732 return sorted(result - target) |
1732 |
1733 |
1733 def _solveunstable(ui, repo, orig, dryrun=False, confirm=False, |
1734 def _solveunstable(ui, repo, orig, dryrun=False, confirm=False, |
1734 progresscb=None): |
1735 progresscb=None): |
1735 """Stabilize a unstable changeset""" |
1736 """Stabilize an unstable changeset""" |
1736 obs = orig.parents()[0] |
1737 obs = orig.parents()[0] |
1737 if not obs.obsolete() and len(orig.parents()) == 2: |
1738 if not obs.obsolete() and len(orig.parents()) == 2: |
1738 obs = orig.parents()[1] # second parent is obsolete ? |
1739 obs = orig.parents()[1] # second parent is obsolete ? |
1739 |
1740 |
1740 if not obs.obsolete(): |
1741 if not obs.obsolete(): |
2056 ('', 'merge', False, _('bring uncommitted change along')), |
2057 ('', 'merge', False, _('bring uncommitted change along')), |
2057 ('n', 'dry-run', False, |
2058 ('n', 'dry-run', False, |
2058 _('do not perform actions, just print what would be done'))], |
2059 _('do not perform actions, just print what would be done'))], |
2059 '[OPTION]...') |
2060 '[OPTION]...') |
2060 def cmdprevious(ui, repo, **opts): |
2061 def cmdprevious(ui, repo, **opts): |
2061 """update to parent and display summary lines""" |
2062 """update to parent revision |
|
2063 |
|
2064 Displays the summary line of the destination for clarity.""" |
2062 wkctx = repo[None] |
2065 wkctx = repo[None] |
2063 wparents = wkctx.parents() |
2066 wparents = wkctx.parents() |
2064 dryrunopt = opts['dry_run'] |
2067 dryrunopt = opts['dry_run'] |
2065 if len(wparents) != 1: |
2068 if len(wparents) != 1: |
2066 raise error.Abort('merge in progress') |
2069 raise error.Abort('merge in progress') |
2112 ('', 'evolve', False, _('evolve the next changeset if necessary')), |
2115 ('', 'evolve', False, _('evolve the next changeset if necessary')), |
2113 ('n', 'dry-run', False, |
2116 ('n', 'dry-run', False, |
2114 _('do not perform actions, just print what would be done'))], |
2117 _('do not perform actions, just print what would be done'))], |
2115 '[OPTION]...') |
2118 '[OPTION]...') |
2116 def cmdnext(ui, repo, **opts): |
2119 def cmdnext(ui, repo, **opts): |
2117 """update to next child |
2120 """update to next child revision |
2118 |
2121 |
2119 You can use the --evolve flag to get unstable children evolved on demand. |
2122 Use the ``--evolve`` flag to evolve unstable children on demand. |
2120 |
2123 |
2121 The summary line of the destination is displayed for clarity""" |
2124 Displays the summary line of the destination for clarity. |
|
2125 """ |
2122 wkctx = repo[None] |
2126 wkctx = repo[None] |
2123 wparents = wkctx.parents() |
2127 wparents = wkctx.parents() |
2124 dryrunopt = opts['dry_run'] |
2128 dryrunopt = opts['dry_run'] |
2125 if len(wparents) != 1: |
2129 if len(wparents) != 1: |
2126 raise error.Abort('merge in progress') |
2130 raise error.Abort('merge in progress') |
2263 _('[OPTION] [-r] REV...')) |
2267 _('[OPTION] [-r] REV...')) |
2264 # -U --noupdate option to prevent wc update and or bookmarks update ? |
2268 # -U --noupdate option to prevent wc update and or bookmarks update ? |
2265 def cmdprune(ui, repo, *revs, **opts): |
2269 def cmdprune(ui, repo, *revs, **opts): |
2266 """hide changesets by marking them obsolete |
2270 """hide changesets by marking them obsolete |
2267 |
2271 |
2268 Obsolete changesets becomes invisible to all commands. |
2272 Pruned changesets are obsolete with no successors. If they also have no |
2269 |
2273 descendants, they are hidden (invisible to all commands). |
2270 Unpruned descendants of pruned changesets becomes "unstable". Use the |
2274 |
2271 :hg:`evolve` to handle such situation. |
2275 Non-obsolete descendants of pruned changesets become "unstable". Use :hg:`evolve` |
2272 |
2276 to handle this situation. |
2273 When the working directory parent is pruned, the repository is updated to a |
2277 |
2274 non-obsolete parent. |
2278 When you prune the parent of your working copy, Mercurial updates the working |
2275 |
2279 copy to a non-obsolete parent. |
2276 You can use the ``--succ`` option to inform mercurial that a newer version |
2280 |
2277 of the pruned changeset exists. |
2281 You can use ``--succ`` to tell Mercurial that a newer version (successor) of the |
2278 |
2282 pruned changeset exists. Mercurial records successor revisions in obsolescence |
2279 You can use the ``--biject`` option to specify a 1-1 (bijection) between |
2283 markers. |
2280 revisions to prune and successor changesets. This option may be removed in |
2284 |
2281 a future release (with the functionality absorbed automatically). |
2285 You can use the ``--biject`` option to specify a 1-1 mapping (bijection) between |
2282 |
2286 revisions to pruned (precursor) and successor changesets. This option may be |
2283 If you specify multiple revisions in --succ, you are recording a "split" |
2287 removed in a future release (with the functionality provided automatically). |
2284 and have to acknowledge it by usng --split. The same logic apply when you |
2288 |
2285 prune multiple changesets with a single successors, this will record a |
2289 If you specify multiple revisions in ``--succ``, you are recording a "split" and |
2286 "fold" requires a --fold flag. |
2290 must acknowledge it by passing ``--split``. Similarly, when you prune multiple |
|
2291 changesets with a single successor, you must pass the ``--fold`` option. |
2287 """ |
2292 """ |
2288 revs = scmutil.revrange(repo, list(revs) + opts.get('rev')) |
2293 revs = scmutil.revrange(repo, list(revs) + opts.get('rev')) |
2289 succs = opts['new'] + opts['succ'] |
2294 succs = opts['new'] + opts['succ'] |
2290 bookmarks = set(opts.get('bookmark')) |
2295 bookmarks = set(opts.get('bookmark')) |
2291 metadata = _getmetadata(**opts) |
2296 metadata = _getmetadata(**opts) |
2686 @command('^split', |
2691 @command('^split', |
2687 [('r', 'rev', [], _("revision to fold")), |
2692 [('r', 'rev', [], _("revision to fold")), |
2688 ] + commitopts + commitopts2, |
2693 ] + commitopts + commitopts2, |
2689 _('hg split [OPTION]... [-r] REV')) |
2694 _('hg split [OPTION]... [-r] REV')) |
2690 def cmdsplit(ui, repo, *revs, **opts): |
2695 def cmdsplit(ui, repo, *revs, **opts): |
2691 """Split the current commit using interactive selection |
2696 """split a changeset into smaller changesets |
2692 |
2697 |
2693 By default, split the current revision by prompting for all its hunk to be |
2698 By default, split the current revision by prompting for all its hunks to be |
2694 redistributed into new changesets. |
2699 redistributed into new changesets. |
2695 |
2700 |
2696 Use --rev for splitting a given changeset instead. |
2701 Use --rev to split a given changeset instead. |
2697 """ |
2702 """ |
2698 tr = wlock = lock = None |
2703 tr = wlock = lock = None |
2699 newcommits = [] |
2704 newcommits = [] |
2700 |
2705 |
2701 revopt = opts.get('rev') |
2706 revopt = opts.get('rev') |