hgext/rebase.py
changeset 34005 5e83a8fe6bc4
parent 34004 af609bb3487f
child 34006 32528419db64
equal deleted inserted replaced
34004:af609bb3487f 34005:5e83a8fe6bc4
    44     phases,
    44     phases,
    45     registrar,
    45     registrar,
    46     repair,
    46     repair,
    47     repoview,
    47     repoview,
    48     revset,
    48     revset,
       
    49     revsetlang,
    49     scmutil,
    50     scmutil,
    50     smartset,
    51     smartset,
    51     util,
    52     util,
    52 )
    53 )
    53 
    54 
   734 
   735 
   735     if ui.configbool('commands', 'rebase.requiredest') and not destf:
   736     if ui.configbool('commands', 'rebase.requiredest') and not destf:
   736         raise error.Abort(_('you must specify a destination'),
   737         raise error.Abort(_('you must specify a destination'),
   737                           hint=_('use: hg rebase -d REV'))
   738                           hint=_('use: hg rebase -d REV'))
   738 
   739 
   739     if destf:
   740     dest = None
   740         dest = scmutil.revsingle(repo, destf)
       
   741 
   741 
   742     if revf:
   742     if revf:
   743         rebaseset = scmutil.revrange(repo, revf)
   743         rebaseset = scmutil.revrange(repo, revf)
   744         if not rebaseset:
   744         if not rebaseset:
   745             ui.status(_('empty "rev" revision set - nothing to rebase\n'))
   745             ui.status(_('empty "rev" revision set - nothing to rebase\n'))
   755         base = scmutil.revrange(repo, [basef or '.'])
   755         base = scmutil.revrange(repo, [basef or '.'])
   756         if not base:
   756         if not base:
   757             ui.status(_('empty "base" revision set - '
   757             ui.status(_('empty "base" revision set - '
   758                         "can't compute rebase set\n"))
   758                         "can't compute rebase set\n"))
   759             return None
   759             return None
   760         if not destf:
   760         if destf:
       
   761             # --base does not support multiple destinations
       
   762             dest = scmutil.revsingle(repo, destf)
       
   763         else:
   761             dest = repo[_destrebase(repo, base, destspace=destspace)]
   764             dest = repo[_destrebase(repo, base, destspace=destspace)]
   762             destf = str(dest)
   765             destf = str(dest)
   763 
   766 
   764         roots = [] # selected children of branching points
   767         roots = [] # selected children of branching points
   765         bpbase = {} # {branchingpoint: [origbase]}
   768         bpbase = {} # {branchingpoint: [origbase]}
   804 
   807 
   805     if not destf:
   808     if not destf:
   806         dest = repo[_destrebase(repo, rebaseset, destspace=destspace)]
   809         dest = repo[_destrebase(repo, rebaseset, destspace=destspace)]
   807         destf = str(dest)
   810         destf = str(dest)
   808 
   811 
   809     # assign dest to each rev in rebaseset
   812     allsrc = revsetlang.formatspec('%ld', rebaseset)
   810     destrev = dest.rev()
   813     alias = {'ALLSRC': allsrc}
   811     destmap = {r: destrev for r in rebaseset} # {srcrev: destrev}
   814 
       
   815     if dest is None:
       
   816         try:
       
   817             # fast path: try to resolve dest without SRC alias
       
   818             dest = scmutil.revsingle(repo, destf, localalias=alias)
       
   819         except error.RepoLookupError:
       
   820             if not ui.configbool('experimental', 'rebase.multidest'):
       
   821                 raise
       
   822             # multi-dest path: resolve dest for each SRC separately
       
   823             destmap = {}
       
   824             for r in rebaseset:
       
   825                 alias['SRC'] = revsetlang.formatspec('%d', r)
       
   826                 # use repo.anyrevs instead of scmutil.revsingle because we
       
   827                 # don't want to abort if destset is empty.
       
   828                 destset = repo.anyrevs([destf], user=True, localalias=alias)
       
   829                 size = len(destset)
       
   830                 if size == 1:
       
   831                     destmap[r] = destset.first()
       
   832                 elif size == 0:
       
   833                     ui.note(_('skipping %s - empty destination\n') % repo[r])
       
   834                 else:
       
   835                     raise error.Abort(_('rebase destination for %s is not '
       
   836                                         'unique') % repo[r])
       
   837 
       
   838     if dest is not None:
       
   839         # single-dest case: assign dest to each rev in rebaseset
       
   840         destrev = dest.rev()
       
   841         destmap = {r: destrev for r in rebaseset} # {srcrev: destrev}
       
   842 
       
   843     if not destmap:
       
   844         ui.status(_('nothing to rebase - empty destination\n'))
       
   845         return None
   812 
   846 
   813     return destmap
   847     return destmap
   814 
   848 
   815 def externalparent(repo, state, destancestors):
   849 def externalparent(repo, state, destancestors):
   816     """Return the revision that should be used as the second parent
   850     """Return the revision that should be used as the second parent
   901 
   935 
   902     rev is what is being rebased. Return a list of two revs, which are the
   936     rev is what is being rebased. Return a list of two revs, which are the
   903     adjusted destinations for rev's p1 and p2, respectively. If a parent is
   937     adjusted destinations for rev's p1 and p2, respectively. If a parent is
   904     nullrev, return dest without adjustment for it.
   938     nullrev, return dest without adjustment for it.
   905 
   939 
   906     For example, when doing rebase -r B+E -d F, rebase will first move B to B1,
   940     For example, when doing rebasing B+E to F, C to G, rebase will first move B
   907     and E's destination will be adjusted from F to B1.
   941     to B1, and E's destination will be adjusted from F to B1.
   908 
   942 
   909         B1 <- written during rebasing B
   943         B1 <- written during rebasing B
   910         |
   944         |
   911         F <- original destination of B, E
   945         F <- original destination of B, E
   912         |
   946         |
   914         | |
   948         | |
   915         | D <- prev, one parent of rev being checked
   949         | D <- prev, one parent of rev being checked
   916         | |
   950         | |
   917         | x <- skipped, ex. no successor or successor in (::dest)
   951         | x <- skipped, ex. no successor or successor in (::dest)
   918         | |
   952         | |
   919         | C
   953         | C <- rebased as C', different destination
   920         | |
   954         | |
   921         | B <- rebased as B1
   955         | B <- rebased as B1     C'
   922         |/
   956         |/                       |
   923         A
   957         A                        G <- destination of C, different
   924 
   958 
   925     Another example about merge changeset, rebase -r C+G+H -d K, rebase will
   959     Another example about merge changeset, rebase -r C+G+H -d K, rebase will
   926     first move C to C1, G to G1, and when it's checking H, the adjusted
   960     first move C to C1, G to G1, and when it's checking H, the adjusted
   927     destinations will be [C1, G1].
   961     destinations will be [C1, G1].
   928 
   962