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 | names = repo.nodetags(ctx.node()) + repo.nodebookmarks(ctx.node()) |
|
384 | names = repo.nodetags(ctx.node()) + repo.nodebookmarks(ctx.node()) | |
385 | if names: |
|
385 | if names: | |
386 | desc += ' (%s)' % ' '.join(names) |
|
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 | pos += 1 |
|
390 | pos += 1 | |
389 | ui.status(_('rebasing %s\n') % desc) |
|
391 | ui.status(_('rebasing %s\n') % desc) | |
390 | ui.progress(_("rebasing"), pos, ("%d:%s" % (rev, ctx)), |
|
392 | ui.progress(_("rebasing"), pos, ("%d:%s" % (rev, ctx)), | |
@@ -508,7 +510,7 b' class rebaseruntime(object):' | |||||
508 | # Nodeids are needed to reset bookmarks |
|
510 | # Nodeids are needed to reset bookmarks | |
509 | nstate = {} |
|
511 | nstate = {} | |
510 | for k, v in self.state.iteritems(): |
|
512 | for k, v in self.state.iteritems(): | |
511 | if v > nullmerge: |
|
513 | if v > nullmerge and v != k: | |
512 | nstate[repo[k].node()] = repo[v].node() |
|
514 | nstate[repo[k].node()] = repo[v].node() | |
513 | elif v == revprecursor: |
|
515 | elif v == revprecursor: | |
514 | succ = self.obsoletenotrebased[k] |
|
516 | succ = self.obsoletenotrebased[k] | |
@@ -1248,6 +1250,7 b' def buildstate(repo, dest, rebaseset, co' | |||||
1248 | roots.sort() |
|
1250 | roots.sort() | |
1249 | state = dict.fromkeys(rebaseset, revtodo) |
|
1251 | state = dict.fromkeys(rebaseset, revtodo) | |
1250 | detachset = set() |
|
1252 | detachset = set() | |
|
1253 | emptyrebase = True | |||
1251 | for root in roots: |
|
1254 | for root in roots: | |
1252 | commonbase = root.ancestor(dest) |
|
1255 | commonbase = root.ancestor(dest) | |
1253 | if commonbase == root: |
|
1256 | if commonbase == root: | |
@@ -1260,9 +1263,13 b' def buildstate(repo, dest, rebaseset, co' | |||||
1260 | else: |
|
1263 | else: | |
1261 | samebranch = root.branch() == dest.branch() |
|
1264 | samebranch = root.branch() == dest.branch() | |
1262 | if not collapse and samebranch and root in dest.children(): |
|
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 | repo.ui.debug('source is a child of destination\n') |
|
1269 | repo.ui.debug('source is a child of destination\n') | |
1264 |
|
|
1270 | continue | |
1265 |
|
1271 | |||
|
1272 | emptyrebase = False | |||
1266 | repo.ui.debug('rebase onto %s starting from %s\n' % (dest, root)) |
|
1273 | repo.ui.debug('rebase onto %s starting from %s\n' % (dest, root)) | |
1267 | # Rebase tries to turn <dest> into a parent of <root> while |
|
1274 | # Rebase tries to turn <dest> into a parent of <root> while | |
1268 | # preserving the number of parents of rebased changesets: |
|
1275 | # preserving the number of parents of rebased changesets: | |
@@ -1305,6 +1312,13 b' def buildstate(repo, dest, rebaseset, co' | |||||
1305 | # ancestors of <root> not ancestors of <dest> |
|
1312 | # ancestors of <root> not ancestors of <dest> | |
1306 | detachset.update(repo.changelog.findmissingrevs([commonbase.rev()], |
|
1313 | detachset.update(repo.changelog.findmissingrevs([commonbase.rev()], | |
1307 | [root.rev()])) |
|
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 | for r in detachset: |
|
1322 | for r in detachset: | |
1309 | if r not in state: |
|
1323 | if r not in state: | |
1310 | state[r] = nullmerge |
|
1324 | state[r] = nullmerge | |
@@ -1332,7 +1346,7 b' def clearrebased(ui, repo, state, skippe' | |||||
1332 | if obsolete.isenabled(repo, obsolete.createmarkersopt): |
|
1346 | if obsolete.isenabled(repo, obsolete.createmarkersopt): | |
1333 | markers = [] |
|
1347 | markers = [] | |
1334 | for rev, newrev in sorted(state.items()): |
|
1348 | for rev, newrev in sorted(state.items()): | |
1335 | if newrev >= 0: |
|
1349 | if newrev >= 0 and newrev != rev: | |
1336 | if rev in skipped: |
|
1350 | if rev in skipped: | |
1337 | succs = () |
|
1351 | succs = () | |
1338 | elif collapsedas is not None: |
|
1352 | elif collapsedas is not None: | |
@@ -1343,7 +1357,8 b' def clearrebased(ui, repo, state, skippe' | |||||
1343 | if markers: |
|
1357 | if markers: | |
1344 | obsolete.createmarkers(repo, markers) |
|
1358 | obsolete.createmarkers(repo, markers) | |
1345 | else: |
|
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 | if rebased: |
|
1362 | if rebased: | |
1348 | stripped = [] |
|
1363 | stripped = [] | |
1349 | for root in repo.set('roots(%ld)', rebased): |
|
1364 | for root in repo.set('roots(%ld)', rebased): |
@@ -298,18 +298,6 b' Slightly more complex merge case (mentio' | |||||
298 | | |
|
298 | | | |
299 | o 0: M0 |
|
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 | Disconnected graph: |
|
301 | Disconnected graph: | |
314 |
|
302 | |||
315 | $ rebasewithdag -b B -d Z <<'EOS' |
|
303 | $ rebasewithdag -b B -d Z <<'EOS' |
General Comments 0
You need to be logged in to leave comments.
Login now