hgext/evolve.py
changeset 900 98b5ac44a259
parent 898 934b6f0feffd
parent 893 12ed6dfa8eea
child 907 c17ab719da56
equal deleted inserted replaced
899:4c305b8d4259 900:98b5ac44a259
    18       this feature,
    18       this feature,
    19     - improves some aspect of the early implementation in 2.3
    19     - improves some aspect of the early implementation in 2.3
    20 '''
    20 '''
    21 
    21 
    22 testedwith = 'default'
    22 testedwith = 'default'
       
    23 
    23 buglink = 'https://bitbucket.org/marmoute/mutable-history/issues'
    24 buglink = 'https://bitbucket.org/marmoute/mutable-history/issues'
    24 
    25 
    25 import sys
    26 import sys
    26 import random
    27 import random
    27 from StringIO import StringIO
    28 from StringIO import StringIO
  1071         ui.write('        median length:      %9i\n' % median)
  1072         ui.write('        median length:      %9i\n' % median)
  1072         mean = sum(len(x[1]) for x in allpclusters) // nbcluster
  1073         mean = sum(len(x[1]) for x in allpclusters) // nbcluster
  1073         ui.write('        mean length:        %9i\n' % mean)
  1074         ui.write('        mean length:        %9i\n' % mean)
  1074 
  1075 
  1075 @command('^evolve|stabilize|solve',
  1076 @command('^evolve|stabilize|solve',
  1076     [('n', 'dry-run', False, 'do not perform actions, print what to be done'),
  1077     [('n', 'dry-run', False, 'do not perform actions, just print what would be done'),
  1077     ('A', 'any', False, 'evolve any troubled changeset'),
  1078     ('A', 'any', False, 'evolve any troubled changeset'),
  1078     ('a', 'all', False, 'evolve all troubled changesets'),
  1079     ('a', 'all', False, 'evolve all troubled changesets'),
  1079     ('c', 'continue', False, 'continue an interrupted evolution'), ],
  1080     ('c', 'continue', False, 'continue an interrupted evolution'), ],
  1080     _('[OPTIONS]...'))
  1081     _('[OPTIONS]...'))
  1081 def evolve(ui, repo, **opts):
  1082 def evolve(ui, repo, **opts):
  1082     """Solve trouble in your repository
  1083     """Solve trouble in your repository
  1083 
  1084 
  1084     - rebase unstable changeset to make it stable again,
  1085     - rebase unstable changesets to make them stable again,
  1085     - create proper diff from bumped changeset,
  1086     - create proper diffs from bumped changesets,
  1086     - merge divergent changesets.
  1087     - merge divergent changesets,
  1087     - update to a successor if the working directory parent is
  1088     - update to a successor if the working directory parent is
  1088       obsolete
  1089       obsolete
  1089 
  1090 
  1090     By default, take the first trouble changeset that looks relevant.
  1091     By default, takes the first troubled changeset that looks relevant.
  1091 
  1092 
  1092     (The logic is still a bit fuzzy)
  1093     (The logic is still a bit fuzzy)
  1093 
  1094 
  1094     - For unstable, this means taking the first which could be rebased as a
  1095     - For unstable, this means taking the first which could be rebased as a
  1095       child of the working directory parent revision or one of its descendants
  1096       child of the working directory parent revision or one of its descendants
  1096       and rebasing it.
  1097       and rebasing it.
  1097 
  1098 
  1098     - For divergent, this means taking "." if applicable.
  1099     - For divergent, this means taking "." if applicable.
  1099 
  1100 
  1100     With --any, evolve picks any troubled changeset to solve.
  1101     With --any, evolve picks any troubled changeset to repair.
  1101 
  1102 
  1102     The working directory is updated to the newly created revision.
  1103     The working directory is updated to the newly created revision.
  1103     """
  1104     """
  1104 
  1105 
  1105     contopt = opts['continue']
  1106     contopt = opts['continue']
  1534 
  1535 
  1535     parents = wparents[0].parents()
  1536     parents = wparents[0].parents()
  1536     displayer = cmdutil.show_changeset(ui, repo, {'template': shorttemplate})
  1537     displayer = cmdutil.show_changeset(ui, repo, {'template': shorttemplate})
  1537     if len(parents) == 1:
  1538     if len(parents) == 1:
  1538         p = parents[0]
  1539         p = parents[0]
  1539         hg.update(repo, p.rev())
  1540         bm = bookmarks.readcurrent(repo)
       
  1541         shouldmove = bm is not None and bookmarks.iscurrent(repo, bm)
       
  1542         ret = hg.update(repo, p.rev())
       
  1543         if not ret and shouldmove:
       
  1544             repo._bookmarks[bm] = p.node()
       
  1545             repo._bookmarks.write()
  1540         displayer.show(p)
  1546         displayer.show(p)
  1541         return 0
  1547         return 0
  1542     else:
  1548     else:
  1543         for p in parents:
  1549         for p in parents:
  1544             displayer.show(p)
  1550             displayer.show(p)
  1560     if not children:
  1566     if not children:
  1561         ui.warn(_('no non-obsolete children\n'))
  1567         ui.warn(_('no non-obsolete children\n'))
  1562         return 1
  1568         return 1
  1563     if len(children) == 1:
  1569     if len(children) == 1:
  1564         c = children[0]
  1570         c = children[0]
  1565         hg.update(repo, c.rev())
  1571         bm = bookmarks.readcurrent(repo)
       
  1572         shouldmove = bm is not None and bookmarks.iscurrent(repo, bm)
       
  1573         ret = hg.update(repo, c.rev())
       
  1574         if not ret and shouldmove:
       
  1575             repo._bookmarks[bm] = c.node()
       
  1576             repo._bookmarks.write()
  1566         displayer.show(c)
  1577         displayer.show(c)
  1567         return 0
  1578         return 0
  1568     else:
  1579     else:
  1569         for c in children:
  1580         for c in children:
  1570             displayer.show(c)
  1581             displayer.show(c)
  1622      ('B', 'bookmark', '', _("remove revs only reachable from given"
  1633      ('B', 'bookmark', '', _("remove revs only reachable from given"
  1623                              " bookmark"))] + metadataopts,
  1634                              " bookmark"))] + metadataopts,
  1624     _('[OPTION] [-r] REV...'))
  1635     _('[OPTION] [-r] REV...'))
  1625     # -U  --noupdate option to prevent wc update and or bookmarks update ?
  1636     # -U  --noupdate option to prevent wc update and or bookmarks update ?
  1626 def cmdprune(ui, repo, *revs, **opts):
  1637 def cmdprune(ui, repo, *revs, **opts):
  1627     """get rid of changesets by marking them obsolete
  1638     """hide changesets by marking them obsolete
  1628 
  1639 
  1629     Obsolete changesets becomes invisible to all commands.
  1640     Obsolete changesets becomes invisible to all commands.
  1630 
  1641 
  1631     Non-pruned descendant of pruned changesets becomes "unstable". Use the
  1642     Unpruned descendants of pruned changesets becomes "unstable". Use the
  1632     :hg:`evolve` to handle such situation.
  1643     :hg:`evolve` to handle such situation.
  1633 
  1644 
  1634     When the working directory parent is pruned the repository is updated to a
  1645     When the working directory parent is pruned, the repository is updated to a
  1635     non obsolete parents.
  1646     non-obsolete parent.
  1636 
  1647 
  1637     You can use the ``--succ`` option to informs mercurial that a newer version
  1648     You can use the ``--succ`` option to inform mercurial that a newer version
  1638     of the pruned changeset exists.
  1649     of the pruned changeset exists.
  1639 
  1650 
  1640     You can use the ``--biject`` option to specify a 1-1 (bijection) between
  1651     You can use the ``--biject`` option to specify a 1-1 (bijection) between
  1641     revisions to prune and successor changesets. This option may be removed in
  1652     revisions to prune and successor changesets. This option may be removed in
  1642     a future release (with the functionality absored automatically).
  1653     a future release (with the functionality absorbed automatically).
  1643 
  1654 
  1644     """
  1655     """
  1645     revs = set(scmutil.revrange(repo, list(revs) + opts.get('rev')))
  1656     revs = set(scmutil.revrange(repo, list(revs) + opts.get('rev')))
  1646     succs = opts['new'] + opts['succ']
  1657     succs = opts['new'] + opts['succ']
  1647     bookmark = opts.get('bookmark')
  1658     bookmark = opts.get('bookmark')
  1835      ] + commands.walkopts,
  1846      ] + commands.walkopts,
  1836     _('[OPTION]... [NAME]'))
  1847     _('[OPTION]... [NAME]'))
  1837 def uncommit(ui, repo, *pats, **opts):
  1848 def uncommit(ui, repo, *pats, **opts):
  1838     """move changes from parent revision to working directory
  1849     """move changes from parent revision to working directory
  1839 
  1850 
  1840     Changes to selected files in parent revision appear again as
  1851     Changes to selected files in the checked out revision appear again as
  1841     uncommitted changed in the working directory. A new revision
  1852     uncommitted changed in the working directory. A new revision
  1842     without selected changes is created, becomes the new parent and
  1853     without the selected changes is created, becomes the checked out
  1843     obsoletes the previous one.
  1854     revision, and obsoletes the previous one.
  1844 
  1855 
  1845     The --include option specifies patterns to uncommit.
  1856     The --include option specifies patterns to uncommit.
  1846     The --exclude option specifies patterns to keep in the commit.
  1857     The --exclude option specifies patterns to keep in the commit.
  1847 
  1858 
  1848     Return 0 if changed files are uncommitted.
  1859     Return 0 if changed files are uncommitted.
  1919      ('D', 'duplicate', False,
  1930      ('D', 'duplicate', False,
  1920       'do not mark the new revision as successor of the old one')],
  1931       'do not mark the new revision as successor of the old one')],
  1921     # allow to choose the seed ?
  1932     # allow to choose the seed ?
  1922     _('[-r] revs'))
  1933     _('[-r] revs'))
  1923 def touch(ui, repo, *revs, **opts):
  1934 def touch(ui, repo, *revs, **opts):
  1924     """Create successors with exact same property but hash
  1935     """Create successors that are identical to their predecessors except for the changeset ID
  1925 
  1936 
  1926     This is used to "resurrect" changesets
  1937     This is used to "resurrect" changesets
  1927     """
  1938     """
  1928     duplicate = opts['duplicate']
  1939     duplicate = opts['duplicate']
  1929     revs = list(revs)
  1940     revs = list(revs)
  1975     # allow to choose the seed ?
  1986     # allow to choose the seed ?
  1976     _('rev'))
  1987     _('rev'))
  1977 def fold(ui, repo, *revs, **opts):
  1988 def fold(ui, repo, *revs, **opts):
  1978     """Fold multiple revisions into a single one
  1989     """Fold multiple revisions into a single one
  1979 
  1990 
  1980     Revision from your current working directory to the specified one are fold
  1991     The revisions from your current working directory to the given one are folded
  1981     as a new one replacing the other
  1992     into a single successor revision.
  1982 
  1993 
  1983     you can alternatively use --rev to explicitly specify revision to be fold
  1994     you can alternatively use --rev to explicitly specify revisions to be folded,
  1984     ignoring the current working directory parent.
  1995     ignoring the current working directory parent.
  1985     """
  1996     """
  1986     revs = list(revs)
  1997     revs = list(revs)
  1987     if revs:
  1998     if revs:
  1988         if opts.get('rev', ()):
  1999         if opts.get('rev', ()):