##// END OF EJS Templates
rebase: choose merge base without unwanted revisions...
Jun Wu -
r33863:3160876c default
parent child Browse files
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 warning: rebasing 7:caa9781e507d may include unwanted changes from 4:d6003a550c2c
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