Show More
@@ -1041,11 +1041,14 b' def defineparents(repo, rev, dest, state' | |||
|
1041 | 1041 | for j, x in enumerate(newps[:i]): |
|
1042 | 1042 | if x == nullrev: |
|
1043 | 1043 | continue |
|
1044 | if isancestor(np, x): | |
|
1044 | if isancestor(np, x): # CASE-1 | |
|
1045 | 1045 | np = nullrev |
|
1046 | elif isancestor(x, np): | |
|
1046 | elif isancestor(x, np): # CASE-2 | |
|
1047 | 1047 | newps[j] = np |
|
1048 | 1048 | np = nullrev |
|
1049 | # New parents forming an ancestor relationship does not | |
|
1050 | # mean the old parents have a similar relationship. Do not | |
|
1051 | # set bases[x] to nullrev. | |
|
1049 | 1052 | bases[j], bases[i] = bases[i], bases[j] |
|
1050 | 1053 | |
|
1051 | 1054 | newps[i] = np |
@@ -1069,8 +1072,6 b' def defineparents(repo, rev, dest, state' | |||
|
1069 | 1072 | 'moving at least one of its parents') |
|
1070 | 1073 | % (rev, repo[rev])) |
|
1071 | 1074 | |
|
1072 | repo.ui.debug(" future parents are %d and %d\n" % tuple(newps)) | |
|
1073 | ||
|
1074 | 1075 | # "rebasenode" updates to new p1, use the corresponding merge base. |
|
1075 | 1076 | if bases[0] != nullrev: |
|
1076 | 1077 | base = bases[0] |
@@ -1093,28 +1094,47 b' def defineparents(repo, rev, dest, state' | |||
|
1093 | 1094 | # better than the default (ancestor(F, Z) == null). Therefore still |
|
1094 | 1095 | # pick one (so choose p1 above). |
|
1095 | 1096 | if sum(1 for b in bases if b != nullrev) > 1: |
|
1096 | assert base is not None | |
|
1097 | unwanted = [None, None] # unwanted[i]: unwanted revs if choose bases[i] | |
|
1098 | for i, base in enumerate(bases): | |
|
1099 | if base == nullrev: | |
|
1100 | continue | |
|
1101 | # Revisions in the side (not chosen as merge base) branch that | |
|
1102 | # might contain "surprising" contents | |
|
1103 | siderevs = list(repo.revs('((%ld-%d) %% (%d+%d))', | |
|
1104 | bases, base, base, dest)) | |
|
1097 | 1105 | |
|
1098 | # Revisions in the side (not chosen as merge base) branch that might | |
|
1099 | # contain "surprising" contents | |
|
1100 | siderevs = list(repo.revs('((%ld-%d) %% (%d+%d))', | |
|
1101 | bases, base, base, dest)) | |
|
1106 | # If those revisions are covered by rebaseset, the result is good. | |
|
1107 | # A merge in rebaseset would be considered to cover its ancestors. | |
|
1108 | if siderevs: | |
|
1109 | rebaseset = [r for r, d in state.items() if d > 0] | |
|
1110 | merges = [r for r in rebaseset | |
|
1111 | if cl.parentrevs(r)[1] != nullrev] | |
|
1112 | unwanted[i] = list(repo.revs('%ld - (::%ld) - %ld', | |
|
1113 | siderevs, merges, rebaseset)) | |
|
1102 | 1114 | |
|
1103 | # If those revisions are covered by rebaseset, the result is good. | |
|
1104 | # A merge in rebaseset would be considered to cover its ancestors. | |
|
1105 | if siderevs: | |
|
1106 | rebaseset = [r for r, d in state.items() if d > 0] | |
|
1107 | merges = [r for r in rebaseset if cl.parentrevs(r)[1] != nullrev] | |
|
1108 | unwantedrevs = list(repo.revs('%ld - (::%ld) - %ld', | |
|
1109 | siderevs, merges, rebaseset)) | |
|
1115 | # Choose a merge base that has a minimal number of unwanted revs. | |
|
1116 | l, i = min((len(revs), i) | |
|
1117 | for i, revs in enumerate(unwanted) if revs is not None) | |
|
1118 | base = bases[i] | |
|
1119 | ||
|
1120 | # newps[0] should match merge base if possible. Currently, if newps[i] | |
|
1121 | # is nullrev, the only case is newps[i] and newps[j] (j < i), one is | |
|
1122 | # the other's ancestor. In that case, it's fine to not swap newps here. | |
|
1123 | # (see CASE-1 and CASE-2 above) | |
|
1124 | if i != 0 and newps[i] != nullrev: | |
|
1125 | newps[0], newps[i] = newps[i], newps[0] | |
|
1110 | 1126 | |
|
1111 | # For revs not covered, it is worth a warning. | |
|
1112 | if unwantedrevs: | |
|
1113 | repo.ui.warn( | |
|
1114 | _('warning: rebasing %d:%s may include unwanted changes ' | |
|
1115 | 'from %s\n') | |
|
1116 | % (rev, repo[rev], ', '.join('%d:%s' % (r, repo[r]) | |
|
1117 | for r in unwantedrevs))) | |
|
1127 | # The merge will include unwanted revisions. Abort now. Revisit this if | |
|
1128 | # we have a more advanced merge algorithm that handles multiple bases. | |
|
1129 | if l > 0: | |
|
1130 | unwanteddesc = _(' or ').join( | |
|
1131 | (', '.join('%d:%s' % (r, repo[r]) for r in revs) | |
|
1132 | for revs in unwanted if revs is not None)) | |
|
1133 | raise error.Abort( | |
|
1134 | _('rebasing %d:%s will include unwanted changes from %s') | |
|
1135 | % (rev, repo[rev], unwanteddesc)) | |
|
1136 | ||
|
1137 | repo.ui.debug(" future parents are %d and %d\n" % tuple(newps)) | |
|
1118 | 1138 | |
|
1119 | 1139 | return newps[0], newps[1], base |
|
1120 | 1140 |
@@ -354,16 +354,8 b' may include unwanted content:' | |||
|
354 | 354 | rebasing 5:5f2c926dfecf "D" (D) |
|
355 | 355 | rebasing 6:b296604d9846 "E" (E) |
|
356 | 356 | rebasing 7:caa9781e507d "F" (F tip) |
|
357 |
|
|
|
358 | saved backup bundle to $TESTTMP/dual-merge-base1/.hg/strip-backup/b296604d9846-0516f6d2-rebase.hg (glob) | |
|
359 | $ hg log -r 4 -T '{files}\n' | |
|
360 | C | |
|
361 | $ hg manifest -r 'desc(F)' | |
|
362 | C | |
|
363 | D | |
|
364 | E | |
|
365 | R | |
|
366 | Z | |
|
357 | abort: rebasing 7:caa9781e507d will include unwanted changes from 4:d6003a550c2c or 3:c1e6b162678d | |
|
358 | [255] | |
|
367 | 359 | |
|
368 | 360 | The warning does not get printed if there is no unwanted change detected: |
|
369 | 361 |
@@ -1065,10 +1065,8 b' Rebase merge where successor of one pare' | |||
|
1065 | 1065 | note: not rebasing 3:7fb047a69f22 "E" (E), already in destination as 1:112478962961 "B" |
|
1066 | 1066 | rebasing 2:b18e25de2cf5 "D" (D) |
|
1067 | 1067 | rebasing 5:66f1a38021c9 "F" (F tip) |
|
1068 | warning: rebasing 5:66f1a38021c9 may include unwanted changes from 3:7fb047a69f22 | |
|
1068 | note: rebase of 5:66f1a38021c9 created no changes to commit | |
|
1069 | 1069 | $ hg log -G |
|
1070 | o 7:9ed45af61fa0 F | |
|
1071 | | | |
|
1072 | 1070 | o 6:8f47515dda15 D |
|
1073 | 1071 | | |
|
1074 | 1072 | | x 5:66f1a38021c9 F |
@@ -1102,11 +1100,9 b' Rebase merge where successor of other pa' | |||
|
1102 | 1100 | note: not rebasing 2:b18e25de2cf5 "D" (D), already in destination as 1:112478962961 "B" |
|
1103 | 1101 | rebasing 3:7fb047a69f22 "E" (E) |
|
1104 | 1102 | rebasing 5:66f1a38021c9 "F" (F tip) |
|
1105 | warning: rebasing 5:66f1a38021c9 may include unwanted changes from 2:b18e25de2cf5 | |
|
1103 | note: rebase of 5:66f1a38021c9 created no changes to commit | |
|
1106 | 1104 | |
|
1107 | 1105 | $ hg log -G |
|
1108 | o 7:502540f44880 F | |
|
1109 | | | |
|
1110 | 1106 | o 6:533690786a86 E |
|
1111 | 1107 | | |
|
1112 | 1108 | | x 5:66f1a38021c9 F |
@@ -1123,6 +1119,88 b' Rebase merge where successor of other pa' | |||
|
1123 | 1119 | |
|
1124 | 1120 | $ cd .. |
|
1125 | 1121 | |
|
1122 | Rebase merge where both parents have successors in destination | |
|
1123 | ||
|
1124 | $ hg init p12-succ-in-dest | |
|
1125 | $ cd p12-succ-in-dest | |
|
1126 | $ hg debugdrawdag <<'EOS' | |
|
1127 | > E F | |
|
1128 | > /| /| # replace: A -> C | |
|
1129 | > A B C D # replace: B -> D | |
|
1130 | > | | | |
|
1131 | > X Y | |
|
1132 | > EOS | |
|
1133 | $ hg rebase -r A+B+E -d F | |
|
1134 | note: not rebasing 4:a3d17304151f "A" (A), already in destination as 0:96cc3511f894 "C" | |
|
1135 | note: not rebasing 5:b23a2cc00842 "B" (B), already in destination as 1:058c1e1fb10a "D" | |
|
1136 | rebasing 7:dac5d11c5a7d "E" (E tip) | |
|
1137 | abort: rebasing 7:dac5d11c5a7d will include unwanted changes from 3:59c792af609c, 5:b23a2cc00842 or 2:ba2b7fa7166d, 4:a3d17304151f | |
|
1138 | [255] | |
|
1139 | $ cd .. | |
|
1140 | ||
|
1141 | Rebase a non-clean merge. One parent has successor in destination, the other | |
|
1142 | parent moves as requested. | |
|
1143 | ||
|
1144 | $ hg init p1-succ-p2-move | |
|
1145 | $ cd p1-succ-p2-move | |
|
1146 | $ hg debugdrawdag <<'EOS' | |
|
1147 | > D Z | |
|
1148 | > /| | # replace: A -> C | |
|
1149 | > A B C # D/D = D | |
|
1150 | > EOS | |
|
1151 | $ hg rebase -r A+B+D -d Z | |
|
1152 | note: not rebasing 0:426bada5c675 "A" (A), already in destination as 2:96cc3511f894 "C" | |
|
1153 | rebasing 1:fc2b737bb2e5 "B" (B) | |
|
1154 | rebasing 3:b8ed089c80ad "D" (D) | |
|
1155 | ||
|
1156 | $ rm .hg/localtags | |
|
1157 | $ hg log -G | |
|
1158 | o 6:e4f78693cc88 D | |
|
1159 | | | |
|
1160 | o 5:76840d832e98 B | |
|
1161 | | | |
|
1162 | o 4:50e41c1f3950 Z | |
|
1163 | | | |
|
1164 | o 2:96cc3511f894 C | |
|
1165 | ||
|
1166 | $ hg files -r tip | |
|
1167 | B | |
|
1168 | C | |
|
1169 | D | |
|
1170 | Z | |
|
1171 | ||
|
1172 | $ cd .. | |
|
1173 | ||
|
1174 | $ hg init p1-move-p2-succ | |
|
1175 | $ cd p1-move-p2-succ | |
|
1176 | $ hg debugdrawdag <<'EOS' | |
|
1177 | > D Z | |
|
1178 | > /| | # replace: B -> C | |
|
1179 | > A B C # D/D = D | |
|
1180 | > EOS | |
|
1181 | $ hg rebase -r B+A+D -d Z | |
|
1182 | note: not rebasing 1:fc2b737bb2e5 "B" (B), already in destination as 2:96cc3511f894 "C" | |
|
1183 | rebasing 0:426bada5c675 "A" (A) | |
|
1184 | rebasing 3:b8ed089c80ad "D" (D) | |
|
1185 | ||
|
1186 | $ rm .hg/localtags | |
|
1187 | $ hg log -G | |
|
1188 | o 6:1b355ed94d82 D | |
|
1189 | | | |
|
1190 | o 5:a81a74d764a6 A | |
|
1191 | | | |
|
1192 | o 4:50e41c1f3950 Z | |
|
1193 | | | |
|
1194 | o 2:96cc3511f894 C | |
|
1195 | ||
|
1196 | $ hg files -r tip | |
|
1197 | A | |
|
1198 | C | |
|
1199 | D | |
|
1200 | Z | |
|
1201 | ||
|
1202 | $ cd .. | |
|
1203 | ||
|
1126 | 1204 | Test that bookmark is moved and working dir is updated when all changesets have |
|
1127 | 1205 | equivalents in destination |
|
1128 | 1206 | $ hg init rbsrepo && cd rbsrepo |
General Comments 0
You need to be logged in to leave comments.
Login now