Show More
@@ -0,0 +1,95 b'' | |||
|
1 | Tests rebasing with part of the rebase set already in the | |
|
2 | destination (issue5422) | |
|
3 | ||
|
4 | $ cat >> $HGRCPATH <<EOF | |
|
5 | > [extensions] | |
|
6 | > rebase= | |
|
7 | > drawdag=$TESTDIR/drawdag.py | |
|
8 | > | |
|
9 | > [experimental] | |
|
10 | > evolution=createmarkers,allowunstable | |
|
11 | > | |
|
12 | > [alias] | |
|
13 | > tglog = log -G --template "{rev}: {desc}" | |
|
14 | > EOF | |
|
15 | ||
|
16 | $ rebasewithdag() { | |
|
17 | > N=`$PYTHON -c "print($N+1)"` | |
|
18 | > hg init repo$N && cd repo$N | |
|
19 | > hg debugdrawdag | |
|
20 | > hg rebase "$@" > _rebasetmp | |
|
21 | > r=$? | |
|
22 | > grep -v 'saved backup bundle' _rebasetmp | |
|
23 | > [ $r -eq 0 ] && hg tglog | |
|
24 | > cd .. | |
|
25 | > return $r | |
|
26 | > } | |
|
27 | ||
|
28 | Rebase two commits, of which one is already in the right place | |
|
29 | ||
|
30 | $ rebasewithdag -r C+D -d B <<EOF | |
|
31 | > C | |
|
32 | > | | |
|
33 | > B D | |
|
34 | > |/ | |
|
35 | > A | |
|
36 | > EOF | |
|
37 | rebasing 2:b18e25de2cf5 "D" (D) | |
|
38 | already rebased 3:26805aba1e60 "C" (C tip) | |
|
39 | o 4: D | |
|
40 | | | |
|
41 | | o 3: C | |
|
42 | |/ | |
|
43 | | x 2: D | |
|
44 | | | | |
|
45 | o | 1: B | |
|
46 | |/ | |
|
47 | o 0: A | |
|
48 | ||
|
49 | Can collapse commits even if one is already in the right place | |
|
50 | ||
|
51 | $ rebasewithdag --collapse -r C+D -d B <<EOF | |
|
52 | > C | |
|
53 | > | | |
|
54 | > B D | |
|
55 | > |/ | |
|
56 | > A | |
|
57 | > EOF | |
|
58 | rebasing 2:b18e25de2cf5 "D" (D) | |
|
59 | rebasing 3:26805aba1e60 "C" (C tip) | |
|
60 | o 4: Collapsed revision | |
|
61 | | * D | |
|
62 | | * C | |
|
63 | | x 3: C | |
|
64 | |/ | |
|
65 | | x 2: D | |
|
66 | | | | |
|
67 | o | 1: B | |
|
68 | |/ | |
|
69 | o 0: A | |
|
70 | ||
|
71 | Rebase with "holes". The commits after the hole should end up on the parent of | |
|
72 | the hole (B below), not on top of the destination (A). | |
|
73 | ||
|
74 | $ rebasewithdag -r B+D -d A <<EOF | |
|
75 | > D | |
|
76 | > | | |
|
77 | > C | |
|
78 | > | | |
|
79 | > B | |
|
80 | > | | |
|
81 | > A | |
|
82 | > EOF | |
|
83 | already rebased 1:112478962961 "B" (B) | |
|
84 | not rebasing ignored 2:26805aba1e60 "C" (C) | |
|
85 | rebasing 3:f585351a92f8 "D" (D tip) | |
|
86 | o 4: D | |
|
87 | | | |
|
88 | | x 3: D | |
|
89 | | | | |
|
90 | | o 2: C | |
|
91 | |/ | |
|
92 | o 1: B | |
|
93 | | | |
|
94 | o 0: A | |
|
95 |
@@ -384,7 +384,9 b' class rebaseruntime(object):' | |||
|
384 | 384 | names = repo.nodetags(ctx.node()) + repo.nodebookmarks(ctx.node()) |
|
385 | 385 | if names: |
|
386 | 386 | desc += ' (%s)' % ' '.join(names) |
|
387 |
if self.state[rev] == rev |
|
|
387 | if self.state[rev] == rev: | |
|
388 | ui.status(_('already rebased %s\n') % desc) | |
|
389 | elif self.state[rev] == revtodo: | |
|
388 | 390 | pos += 1 |
|
389 | 391 | ui.status(_('rebasing %s\n') % desc) |
|
390 | 392 | ui.progress(_("rebasing"), pos, ("%d:%s" % (rev, ctx)), |
@@ -508,7 +510,7 b' class rebaseruntime(object):' | |||
|
508 | 510 | # Nodeids are needed to reset bookmarks |
|
509 | 511 | nstate = {} |
|
510 | 512 | for k, v in self.state.iteritems(): |
|
511 | if v > nullmerge: | |
|
513 | if v > nullmerge and v != k: | |
|
512 | 514 | nstate[repo[k].node()] = repo[v].node() |
|
513 | 515 | elif v == revprecursor: |
|
514 | 516 | succ = self.obsoletenotrebased[k] |
@@ -1248,6 +1250,7 b' def buildstate(repo, dest, rebaseset, co' | |||
|
1248 | 1250 | roots.sort() |
|
1249 | 1251 | state = dict.fromkeys(rebaseset, revtodo) |
|
1250 | 1252 | detachset = set() |
|
1253 | emptyrebase = True | |
|
1251 | 1254 | for root in roots: |
|
1252 | 1255 | commonbase = root.ancestor(dest) |
|
1253 | 1256 | if commonbase == root: |
@@ -1260,9 +1263,13 b' def buildstate(repo, dest, rebaseset, co' | |||
|
1260 | 1263 | else: |
|
1261 | 1264 | samebranch = root.branch() == dest.branch() |
|
1262 | 1265 | if not collapse and samebranch and root in dest.children(): |
|
1266 | # mark the revision as done by setting its new revision | |
|
1267 | # equal to its old (current) revisions | |
|
1268 | state[root.rev()] = root.rev() | |
|
1263 | 1269 | repo.ui.debug('source is a child of destination\n') |
|
1264 |
|
|
|
1270 | continue | |
|
1265 | 1271 | |
|
1272 | emptyrebase = False | |
|
1266 | 1273 | repo.ui.debug('rebase onto %s starting from %s\n' % (dest, root)) |
|
1267 | 1274 | # Rebase tries to turn <dest> into a parent of <root> while |
|
1268 | 1275 | # preserving the number of parents of rebased changesets: |
@@ -1305,6 +1312,13 b' def buildstate(repo, dest, rebaseset, co' | |||
|
1305 | 1312 | # ancestors of <root> not ancestors of <dest> |
|
1306 | 1313 | detachset.update(repo.changelog.findmissingrevs([commonbase.rev()], |
|
1307 | 1314 | [root.rev()])) |
|
1315 | if emptyrebase: | |
|
1316 | return None | |
|
1317 | for rev in sorted(state): | |
|
1318 | parents = [p for p in repo.changelog.parentrevs(rev) if p != nullrev] | |
|
1319 | # if all parents of this revision are done, then so is this revision | |
|
1320 | if parents and all((state.get(p) == p for p in parents)): | |
|
1321 | state[rev] = rev | |
|
1308 | 1322 | for r in detachset: |
|
1309 | 1323 | if r not in state: |
|
1310 | 1324 | state[r] = nullmerge |
@@ -1332,7 +1346,7 b' def clearrebased(ui, repo, state, skippe' | |||
|
1332 | 1346 | if obsolete.isenabled(repo, obsolete.createmarkersopt): |
|
1333 | 1347 | markers = [] |
|
1334 | 1348 | for rev, newrev in sorted(state.items()): |
|
1335 | if newrev >= 0: | |
|
1349 | if newrev >= 0 and newrev != rev: | |
|
1336 | 1350 | if rev in skipped: |
|
1337 | 1351 | succs = () |
|
1338 | 1352 | elif collapsedas is not None: |
@@ -1343,7 +1357,8 b' def clearrebased(ui, repo, state, skippe' | |||
|
1343 | 1357 | if markers: |
|
1344 | 1358 | obsolete.createmarkers(repo, markers) |
|
1345 | 1359 | else: |
|
1346 |
rebased = [rev for rev in state |
|
|
1360 | rebased = [rev for rev in state | |
|
1361 | if state[rev] > nullmerge and state[rev] != rev] | |
|
1347 | 1362 | if rebased: |
|
1348 | 1363 | stripped = [] |
|
1349 | 1364 | for root in repo.set('roots(%ld)', rebased): |
@@ -298,18 +298,6 b' Slightly more complex merge case (mentio' | |||
|
298 | 298 | | |
|
299 | 299 | o 0: M0 |
|
300 | 300 | |
|
301 | Mixed rebasable and non-rebasable bases (unresolved, issue5422): | |
|
302 | ||
|
303 | $ rebasewithdag -b C+D -d B <<'EOS' | |
|
304 | > D | |
|
305 | > / | |
|
306 | > B C | |
|
307 | > |/ | |
|
308 | > A | |
|
309 | > EOS | |
|
310 | nothing to rebase | |
|
311 | [1] | |
|
312 | ||
|
313 | 301 | Disconnected graph: |
|
314 | 302 | |
|
315 | 303 | $ rebasewithdag -b B -d Z <<'EOS' |
General Comments 0
You need to be logged in to leave comments.
Login now