##// END OF EJS Templates
localrepo: add setparents() to adjust dirstate copies (issue3407)...
Patrick Mezard -
r16551:ebf6d38c stable
parent child Browse files
Show More
@@ -0,0 +1,30 b''
1 #!/bin/sh
2
3 # @ 3: 'move2'
4 # |
5 # o 2: 'move1'
6 # |
7 # | o 1: 'change'
8 # |/
9 # o 0: 'add'
10
11 hg init copies
12 cd copies
13 echo a > a
14 echo b > b
15 echo c > c
16 hg ci -Am add
17 echo a >> a
18 echo b >> b
19 echo c >> c
20 hg ci -m change
21 hg up -qC 0
22 hg cp a d
23 hg mv b e
24 hg mv c f
25 hg ci -m move1
26 hg mv e g
27 hg mv f c
28 hg ci -m move2
29 hg bundle -a ../renames.hg
30 cd ..
1 NO CONTENT: new file 100644, binary diff hidden
@@ -248,7 +248,7 b' def _commitcontext(rdst, parents, ctx, d'
248 248 mctx = context.memctx(rdst, parents, ctx.description(), dstfiles,
249 249 getfilectx, ctx.user(), ctx.date(), ctx.extra())
250 250 ret = rdst.commitctx(mctx)
251 rdst.dirstate.setparents(ret)
251 rdst.setparents(ret)
252 252 revmap[ctx.node()] = rdst.changelog.tip()
253 253
254 254 # Generate list of changed files
@@ -749,7 +749,7 b' class queue(object):'
749 749 for f in merged:
750 750 repo.dirstate.merge(f)
751 751 p1, p2 = repo.dirstate.parents()
752 repo.dirstate.setparents(p1, merge)
752 repo.setparents(p1, merge)
753 753
754 754 match = scmutil.matchfiles(repo, files or [])
755 755 oldtip = repo['tip']
@@ -1355,7 +1355,7 b' class queue(object):'
1355 1355 fctx = ctx[f]
1356 1356 repo.wwrite(f, fctx.data(), fctx.flags())
1357 1357 repo.dirstate.normal(f)
1358 repo.dirstate.setparents(qp, nullid)
1358 repo.setparents(qp, nullid)
1359 1359 for patch in reversed(self.applied[start:end]):
1360 1360 self.ui.status(_("popping %s\n") % patch.name)
1361 1361 del self.applied[start:end]
@@ -1546,7 +1546,7 b' class queue(object):'
1546 1546 oldphase = repo[top].phase()
1547 1547
1548 1548 # assumes strip can roll itself back if interrupted
1549 repo.dirstate.setparents(*cparents)
1549 repo.setparents(*cparents)
1550 1550 self.applied.pop()
1551 1551 self.applieddirty = True
1552 1552 self.strip(repo, [top], update=False,
@@ -277,7 +277,7 b' def rebase(ui, repo, **opts):'
277 277 editor=editor)
278 278 else:
279 279 # Skip commit if we are collapsing
280 repo.dirstate.setparents(repo[p1].node())
280 repo.setparents(repo[p1].node())
281 281 newrev = None
282 282 # Update the state
283 283 if newrev is not None:
@@ -361,7 +361,7 b' def checkexternal(repo, state, targetanc'
361 361 def concludenode(repo, rev, p1, p2, commitmsg=None, editor=None, extrafn=None):
362 362 'Commit the changes and store useful information in extra'
363 363 try:
364 repo.dirstate.setparents(repo[p1].node(), repo[p2].node())
364 repo.setparents(repo[p1].node(), repo[p2].node())
365 365 ctx = repo[rev]
366 366 if commitmsg is None:
367 367 commitmsg = ctx.description()
@@ -274,7 +274,7 b' class transplanter(object):'
274 274 files = None
275 275 if merge:
276 276 p1, p2 = repo.dirstate.parents()
277 repo.dirstate.setparents(p1, node)
277 repo.setparents(p1, node)
278 278 m = match.always(repo.root, '')
279 279 else:
280 280 m = match.exact(repo.root, '', files)
@@ -340,7 +340,7 b' class transplanter(object):'
340 340 _('working dir not at transplant parent %s') %
341 341 revlog.hex(parent))
342 342 if merge:
343 repo.dirstate.setparents(p1, parents[1])
343 repo.setparents(p1, parents[1])
344 344 n = repo.commit(message, user, date, extra=extra,
345 345 editor=self.editor)
346 346 if not n:
@@ -1384,7 +1384,7 b' def amend(ui, repo, commitfunc, old, ext'
1384 1384 newid = repo.commitctx(new)
1385 1385 if newid != old.node():
1386 1386 # Reroute the working copy parent to the new changeset
1387 repo.dirstate.setparents(newid, nullid)
1387 repo.setparents(newid, nullid)
1388 1388
1389 1389 # Move bookmarks from old parent to amend commit
1390 1390 bms = repo.nodebookmarks(old.node())
@@ -2270,7 +2270,7 b' def debugsetparents(ui, repo, rev1, rev2'
2270 2270
2271 2271 wlock = repo.wlock()
2272 2272 try:
2273 repo.dirstate.setparents(r1, r2)
2273 repo.setparents(r1, r2)
2274 2274 finally:
2275 2275 wlock.release()
2276 2276
@@ -2693,7 +2693,7 b' def graft(ui, repo, *revs, **opts):'
2693 2693 finally:
2694 2694 ui.setconfig('ui', 'forcemerge', '')
2695 2695 # drop the second merge parent
2696 repo.dirstate.setparents(current.node(), nullid)
2696 repo.setparents(current.node(), nullid)
2697 2697 repo.dirstate.write()
2698 2698 # fix up dirstate for copies and renames
2699 2699 cmdutil.duplicatecopies(repo, ctx.rev(), ctx.p1().rev())
@@ -3635,7 +3635,7 b' def import_(ui, repo, patch1=None, *patc'
3635 3635 if p1 != parents[0]:
3636 3636 hg.clean(repo, p1.node())
3637 3637 if p2 != parents[1]:
3638 repo.dirstate.setparents(p1.node(), p2.node())
3638 repo.setparents(p1.node(), p2.node())
3639 3639
3640 3640 if opts.get('exact') or opts.get('import_branch'):
3641 3641 repo.dirstate.setbranch(branch or 'default')
@@ -237,14 +237,26 b' class dirstate(object):'
237 237 return encoding.tolocal(self._branch)
238 238
239 239 def setparents(self, p1, p2=nullid):
240 """Set dirstate parents to p1 and p2.
241
242 When moving from two parents to one, 'm' merged entries a
243 adjusted to normal and previous copy records discarded and
244 returned by the call.
245
246 See localrepo.setparents()
247 """
240 248 self._dirty = self._dirtypl = True
241 249 oldp2 = self._pl[1]
242 250 self._pl = p1, p2
251 copies = {}
243 252 if oldp2 != nullid and p2 == nullid:
244 253 # Discard 'm' markers when moving away from a merge state
245 254 for f, s in self._map.iteritems():
246 255 if s[0] == 'm':
256 if f in self._copymap:
257 copies[f] = self._copymap[f]
247 258 self.normallookup(f)
259 return copies
248 260
249 261 def setbranch(self, branch):
250 262 if branch in ['tip', '.', 'null']:
@@ -633,6 +633,17 b' class localrepository(repo.repository):'
633 633 '''get list of changectxs for parents of changeid'''
634 634 return self[changeid].parents()
635 635
636 def setparents(self, p1, p2=nullid):
637 copies = self.dirstate.setparents(p1, p2)
638 if copies:
639 # Adjust copy records, the dirstate cannot do it, it
640 # requires access to parents manifests. Preserve them
641 # only for entries added to first parent.
642 pctx = self[p1]
643 for f in copies:
644 if f not in pctx and copies[f] in pctx:
645 self.dirstate.copy(copies[f], f)
646
636 647 def filectx(self, path, changeid=None, fileid=None):
637 648 """changeid can be a changeset revision, node, or tag.
638 649 fileid can be a file revision or node."""
@@ -596,7 +596,7 b' def update(repo, node, branchmerge, forc'
596 596 stats = applyupdates(repo, action, wc, p2, pa, overwrite)
597 597
598 598 if not partial:
599 repo.dirstate.setparents(fp1, fp2)
599 repo.setparents(fp1, fp2)
600 600 recordupdates(repo, action, branchmerge)
601 601 if not branchmerge:
602 602 repo.dirstate.setbranch(p2.branch())
@@ -541,3 +541,52 b' Interactions between collapse and keepbr'
541 541 @@ -0,0 +1,2 @@
542 542 +d
543 543 +blah
544
545 $ cd ..
546
547 Rebase, collapse and copies
548
549 $ hg init copies
550 $ cd copies
551 $ hg unbundle "$TESTDIR/bundles/renames.hg"
552 adding changesets
553 adding manifests
554 adding file changes
555 added 4 changesets with 11 changes to 7 files (+1 heads)
556 (run 'hg heads' to see heads, 'hg merge' to merge)
557 $ hg up -q tip
558 $ hg tglog
559 @ 3: 'move2'
560 |
561 o 2: 'move1'
562 |
563 | o 1: 'change'
564 |/
565 o 0: 'add'
566
567 $ hg rebase --collapse -d 1
568 merging a and d to d
569 merging b and e to e
570 merging c and f to f
571 merging e and g to g
572 merging f and c to c
573 saved backup bundle to $TESTTMP/copies/.hg/strip-backup/*-backup.hg (glob)
574 $ hg st
575 $ hg st --copies --change .
576 A d
577 a
578 A g
579 b
580 R b
581 $ cat c
582 c
583 c
584 $ cat d
585 a
586 a
587 $ cat g
588 b
589 b
590 $ hg log -r . --template "{file_copies}\n"
591 d (a)g (b)
592 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now