Show More
@@ -1041,11 +1041,14 b' def defineparents(repo, rev, dest, state' | |||||
1041 | for j, x in enumerate(newps[:i]): |
|
1041 | for j, x in enumerate(newps[:i]): | |
1042 | if x == nullrev: |
|
1042 | if x == nullrev: | |
1043 | continue |
|
1043 | continue | |
1044 | if isancestor(np, x): |
|
1044 | if isancestor(np, x): # CASE-1 | |
1045 | np = nullrev |
|
1045 | np = nullrev | |
1046 | elif isancestor(x, np): |
|
1046 | elif isancestor(x, np): # CASE-2 | |
1047 | newps[j] = np |
|
1047 | newps[j] = np | |
1048 | np = nullrev |
|
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 | bases[j], bases[i] = bases[i], bases[j] |
|
1052 | bases[j], bases[i] = bases[i], bases[j] | |
1050 |
|
1053 | |||
1051 | newps[i] = np |
|
1054 | newps[i] = np | |
@@ -1069,8 +1072,6 b' def defineparents(repo, rev, dest, state' | |||||
1069 | 'moving at least one of its parents') |
|
1072 | 'moving at least one of its parents') | |
1070 | % (rev, repo[rev])) |
|
1073 | % (rev, repo[rev])) | |
1071 |
|
1074 | |||
1072 | repo.ui.debug(" future parents are %d and %d\n" % tuple(newps)) |
|
|||
1073 |
|
||||
1074 | # "rebasenode" updates to new p1, use the corresponding merge base. |
|
1075 | # "rebasenode" updates to new p1, use the corresponding merge base. | |
1075 | if bases[0] != nullrev: |
|
1076 | if bases[0] != nullrev: | |
1076 | base = bases[0] |
|
1077 | base = bases[0] | |
@@ -1093,28 +1094,47 b' def defineparents(repo, rev, dest, state' | |||||
1093 | # better than the default (ancestor(F, Z) == null). Therefore still |
|
1094 | # better than the default (ancestor(F, Z) == null). Therefore still | |
1094 | # pick one (so choose p1 above). |
|
1095 | # pick one (so choose p1 above). | |
1095 | if sum(1 for b in bases if b != nullrev) > 1: |
|
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 |
|
1106 | # If those revisions are covered by rebaseset, the result is good. | |
1099 | # contain "surprising" contents |
|
1107 | # A merge in rebaseset would be considered to cover its ancestors. | |
1100 | siderevs = list(repo.revs('((%ld-%d) %% (%d+%d))', |
|
1108 | if siderevs: | |
1101 | bases, base, base, dest)) |
|
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. |
|
1115 | # Choose a merge base that has a minimal number of unwanted revs. | |
1104 | # A merge in rebaseset would be considered to cover its ancestors. |
|
1116 | l, i = min((len(revs), i) | |
1105 | if siderevs: |
|
1117 | for i, revs in enumerate(unwanted) if revs is not None) | |
1106 | rebaseset = [r for r, d in state.items() if d > 0] |
|
1118 | base = bases[i] | |
1107 | merges = [r for r in rebaseset if cl.parentrevs(r)[1] != nullrev] |
|
1119 | ||
1108 | unwantedrevs = list(repo.revs('%ld - (::%ld) - %ld', |
|
1120 | # newps[0] should match merge base if possible. Currently, if newps[i] | |
1109 | siderevs, merges, rebaseset)) |
|
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. |
|
1127 | # The merge will include unwanted revisions. Abort now. Revisit this if | |
1112 | if unwantedrevs: |
|
1128 | # we have a more advanced merge algorithm that handles multiple bases. | |
1113 | repo.ui.warn( |
|
1129 | if l > 0: | |
1114 | _('warning: rebasing %d:%s may include unwanted changes ' |
|
1130 | unwanteddesc = _(' or ').join( | |
1115 | 'from %s\n') |
|
1131 | (', '.join('%d:%s' % (r, repo[r]) for r in revs) | |
1116 | % (rev, repo[rev], ', '.join('%d:%s' % (r, repo[r]) |
|
1132 | for revs in unwanted if revs is not None)) | |
1117 | for r in unwantedrevs))) |
|
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 | return newps[0], newps[1], base |
|
1139 | return newps[0], newps[1], base | |
1120 |
|
1140 |
@@ -354,16 +354,8 b' may include unwanted content:' | |||||
354 | rebasing 5:5f2c926dfecf "D" (D) |
|
354 | rebasing 5:5f2c926dfecf "D" (D) | |
355 | rebasing 6:b296604d9846 "E" (E) |
|
355 | rebasing 6:b296604d9846 "E" (E) | |
356 | rebasing 7:caa9781e507d "F" (F tip) |
|
356 | rebasing 7:caa9781e507d "F" (F tip) | |
357 |
|
|
357 | abort: rebasing 7:caa9781e507d will include unwanted changes from 4:d6003a550c2c or 3:c1e6b162678d | |
358 | saved backup bundle to $TESTTMP/dual-merge-base1/.hg/strip-backup/b296604d9846-0516f6d2-rebase.hg (glob) |
|
358 | [255] | |
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 |
|
|||
367 |
|
359 | |||
368 | The warning does not get printed if there is no unwanted change detected: |
|
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 | note: not rebasing 3:7fb047a69f22 "E" (E), already in destination as 1:112478962961 "B" |
|
1065 | note: not rebasing 3:7fb047a69f22 "E" (E), already in destination as 1:112478962961 "B" | |
1066 | rebasing 2:b18e25de2cf5 "D" (D) |
|
1066 | rebasing 2:b18e25de2cf5 "D" (D) | |
1067 | rebasing 5:66f1a38021c9 "F" (F tip) |
|
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 | $ hg log -G |
|
1069 | $ hg log -G | |
1070 | o 7:9ed45af61fa0 F |
|
|||
1071 | | |
|
|||
1072 | o 6:8f47515dda15 D |
|
1070 | o 6:8f47515dda15 D | |
1073 | | |
|
1071 | | | |
1074 | | x 5:66f1a38021c9 F |
|
1072 | | x 5:66f1a38021c9 F | |
@@ -1102,11 +1100,9 b' Rebase merge where successor of other pa' | |||||
1102 | note: not rebasing 2:b18e25de2cf5 "D" (D), already in destination as 1:112478962961 "B" |
|
1100 | note: not rebasing 2:b18e25de2cf5 "D" (D), already in destination as 1:112478962961 "B" | |
1103 | rebasing 3:7fb047a69f22 "E" (E) |
|
1101 | rebasing 3:7fb047a69f22 "E" (E) | |
1104 | rebasing 5:66f1a38021c9 "F" (F tip) |
|
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 | $ hg log -G |
|
1105 | $ hg log -G | |
1108 | o 7:502540f44880 F |
|
|||
1109 | | |
|
|||
1110 | o 6:533690786a86 E |
|
1106 | o 6:533690786a86 E | |
1111 | | |
|
1107 | | | |
1112 | | x 5:66f1a38021c9 F |
|
1108 | | x 5:66f1a38021c9 F | |
@@ -1123,6 +1119,88 b' Rebase merge where successor of other pa' | |||||
1123 |
|
1119 | |||
1124 | $ cd .. |
|
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 | Test that bookmark is moved and working dir is updated when all changesets have |
|
1204 | Test that bookmark is moved and working dir is updated when all changesets have | |
1127 | equivalents in destination |
|
1205 | equivalents in destination | |
1128 | $ hg init rbsrepo && cd rbsrepo |
|
1206 | $ hg init rbsrepo && cd rbsrepo |
General Comments 0
You need to be logged in to leave comments.
Login now