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 |