##// 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
NO CONTENT: new file 100644, binary diff hidden
@@ -248,7 +248,7 b' def _commitcontext(rdst, parents, ctx, d'
248 mctx = context.memctx(rdst, parents, ctx.description(), dstfiles,
248 mctx = context.memctx(rdst, parents, ctx.description(), dstfiles,
249 getfilectx, ctx.user(), ctx.date(), ctx.extra())
249 getfilectx, ctx.user(), ctx.date(), ctx.extra())
250 ret = rdst.commitctx(mctx)
250 ret = rdst.commitctx(mctx)
251 rdst.dirstate.setparents(ret)
251 rdst.setparents(ret)
252 revmap[ctx.node()] = rdst.changelog.tip()
252 revmap[ctx.node()] = rdst.changelog.tip()
253
253
254 # Generate list of changed files
254 # Generate list of changed files
@@ -749,7 +749,7 b' class queue(object):'
749 for f in merged:
749 for f in merged:
750 repo.dirstate.merge(f)
750 repo.dirstate.merge(f)
751 p1, p2 = repo.dirstate.parents()
751 p1, p2 = repo.dirstate.parents()
752 repo.dirstate.setparents(p1, merge)
752 repo.setparents(p1, merge)
753
753
754 match = scmutil.matchfiles(repo, files or [])
754 match = scmutil.matchfiles(repo, files or [])
755 oldtip = repo['tip']
755 oldtip = repo['tip']
@@ -1355,7 +1355,7 b' class queue(object):'
1355 fctx = ctx[f]
1355 fctx = ctx[f]
1356 repo.wwrite(f, fctx.data(), fctx.flags())
1356 repo.wwrite(f, fctx.data(), fctx.flags())
1357 repo.dirstate.normal(f)
1357 repo.dirstate.normal(f)
1358 repo.dirstate.setparents(qp, nullid)
1358 repo.setparents(qp, nullid)
1359 for patch in reversed(self.applied[start:end]):
1359 for patch in reversed(self.applied[start:end]):
1360 self.ui.status(_("popping %s\n") % patch.name)
1360 self.ui.status(_("popping %s\n") % patch.name)
1361 del self.applied[start:end]
1361 del self.applied[start:end]
@@ -1546,7 +1546,7 b' class queue(object):'
1546 oldphase = repo[top].phase()
1546 oldphase = repo[top].phase()
1547
1547
1548 # assumes strip can roll itself back if interrupted
1548 # assumes strip can roll itself back if interrupted
1549 repo.dirstate.setparents(*cparents)
1549 repo.setparents(*cparents)
1550 self.applied.pop()
1550 self.applied.pop()
1551 self.applieddirty = True
1551 self.applieddirty = True
1552 self.strip(repo, [top], update=False,
1552 self.strip(repo, [top], update=False,
@@ -277,7 +277,7 b' def rebase(ui, repo, **opts):'
277 editor=editor)
277 editor=editor)
278 else:
278 else:
279 # Skip commit if we are collapsing
279 # Skip commit if we are collapsing
280 repo.dirstate.setparents(repo[p1].node())
280 repo.setparents(repo[p1].node())
281 newrev = None
281 newrev = None
282 # Update the state
282 # Update the state
283 if newrev is not None:
283 if newrev is not None:
@@ -361,7 +361,7 b' def checkexternal(repo, state, targetanc'
361 def concludenode(repo, rev, p1, p2, commitmsg=None, editor=None, extrafn=None):
361 def concludenode(repo, rev, p1, p2, commitmsg=None, editor=None, extrafn=None):
362 'Commit the changes and store useful information in extra'
362 'Commit the changes and store useful information in extra'
363 try:
363 try:
364 repo.dirstate.setparents(repo[p1].node(), repo[p2].node())
364 repo.setparents(repo[p1].node(), repo[p2].node())
365 ctx = repo[rev]
365 ctx = repo[rev]
366 if commitmsg is None:
366 if commitmsg is None:
367 commitmsg = ctx.description()
367 commitmsg = ctx.description()
@@ -274,7 +274,7 b' class transplanter(object):'
274 files = None
274 files = None
275 if merge:
275 if merge:
276 p1, p2 = repo.dirstate.parents()
276 p1, p2 = repo.dirstate.parents()
277 repo.dirstate.setparents(p1, node)
277 repo.setparents(p1, node)
278 m = match.always(repo.root, '')
278 m = match.always(repo.root, '')
279 else:
279 else:
280 m = match.exact(repo.root, '', files)
280 m = match.exact(repo.root, '', files)
@@ -340,7 +340,7 b' class transplanter(object):'
340 _('working dir not at transplant parent %s') %
340 _('working dir not at transplant parent %s') %
341 revlog.hex(parent))
341 revlog.hex(parent))
342 if merge:
342 if merge:
343 repo.dirstate.setparents(p1, parents[1])
343 repo.setparents(p1, parents[1])
344 n = repo.commit(message, user, date, extra=extra,
344 n = repo.commit(message, user, date, extra=extra,
345 editor=self.editor)
345 editor=self.editor)
346 if not n:
346 if not n:
@@ -1384,7 +1384,7 b' def amend(ui, repo, commitfunc, old, ext'
1384 newid = repo.commitctx(new)
1384 newid = repo.commitctx(new)
1385 if newid != old.node():
1385 if newid != old.node():
1386 # Reroute the working copy parent to the new changeset
1386 # Reroute the working copy parent to the new changeset
1387 repo.dirstate.setparents(newid, nullid)
1387 repo.setparents(newid, nullid)
1388
1388
1389 # Move bookmarks from old parent to amend commit
1389 # Move bookmarks from old parent to amend commit
1390 bms = repo.nodebookmarks(old.node())
1390 bms = repo.nodebookmarks(old.node())
@@ -2270,7 +2270,7 b' def debugsetparents(ui, repo, rev1, rev2'
2270
2270
2271 wlock = repo.wlock()
2271 wlock = repo.wlock()
2272 try:
2272 try:
2273 repo.dirstate.setparents(r1, r2)
2273 repo.setparents(r1, r2)
2274 finally:
2274 finally:
2275 wlock.release()
2275 wlock.release()
2276
2276
@@ -2693,7 +2693,7 b' def graft(ui, repo, *revs, **opts):'
2693 finally:
2693 finally:
2694 ui.setconfig('ui', 'forcemerge', '')
2694 ui.setconfig('ui', 'forcemerge', '')
2695 # drop the second merge parent
2695 # drop the second merge parent
2696 repo.dirstate.setparents(current.node(), nullid)
2696 repo.setparents(current.node(), nullid)
2697 repo.dirstate.write()
2697 repo.dirstate.write()
2698 # fix up dirstate for copies and renames
2698 # fix up dirstate for copies and renames
2699 cmdutil.duplicatecopies(repo, ctx.rev(), ctx.p1().rev())
2699 cmdutil.duplicatecopies(repo, ctx.rev(), ctx.p1().rev())
@@ -3635,7 +3635,7 b' def import_(ui, repo, patch1=None, *patc'
3635 if p1 != parents[0]:
3635 if p1 != parents[0]:
3636 hg.clean(repo, p1.node())
3636 hg.clean(repo, p1.node())
3637 if p2 != parents[1]:
3637 if p2 != parents[1]:
3638 repo.dirstate.setparents(p1.node(), p2.node())
3638 repo.setparents(p1.node(), p2.node())
3639
3639
3640 if opts.get('exact') or opts.get('import_branch'):
3640 if opts.get('exact') or opts.get('import_branch'):
3641 repo.dirstate.setbranch(branch or 'default')
3641 repo.dirstate.setbranch(branch or 'default')
@@ -237,14 +237,26 b' class dirstate(object):'
237 return encoding.tolocal(self._branch)
237 return encoding.tolocal(self._branch)
238
238
239 def setparents(self, p1, p2=nullid):
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 self._dirty = self._dirtypl = True
248 self._dirty = self._dirtypl = True
241 oldp2 = self._pl[1]
249 oldp2 = self._pl[1]
242 self._pl = p1, p2
250 self._pl = p1, p2
251 copies = {}
243 if oldp2 != nullid and p2 == nullid:
252 if oldp2 != nullid and p2 == nullid:
244 # Discard 'm' markers when moving away from a merge state
253 # Discard 'm' markers when moving away from a merge state
245 for f, s in self._map.iteritems():
254 for f, s in self._map.iteritems():
246 if s[0] == 'm':
255 if s[0] == 'm':
256 if f in self._copymap:
257 copies[f] = self._copymap[f]
247 self.normallookup(f)
258 self.normallookup(f)
259 return copies
248
260
249 def setbranch(self, branch):
261 def setbranch(self, branch):
250 if branch in ['tip', '.', 'null']:
262 if branch in ['tip', '.', 'null']:
@@ -633,6 +633,17 b' class localrepository(repo.repository):'
633 '''get list of changectxs for parents of changeid'''
633 '''get list of changectxs for parents of changeid'''
634 return self[changeid].parents()
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 def filectx(self, path, changeid=None, fileid=None):
647 def filectx(self, path, changeid=None, fileid=None):
637 """changeid can be a changeset revision, node, or tag.
648 """changeid can be a changeset revision, node, or tag.
638 fileid can be a file revision or node."""
649 fileid can be a file revision or node."""
@@ -596,7 +596,7 b' def update(repo, node, branchmerge, forc'
596 stats = applyupdates(repo, action, wc, p2, pa, overwrite)
596 stats = applyupdates(repo, action, wc, p2, pa, overwrite)
597
597
598 if not partial:
598 if not partial:
599 repo.dirstate.setparents(fp1, fp2)
599 repo.setparents(fp1, fp2)
600 recordupdates(repo, action, branchmerge)
600 recordupdates(repo, action, branchmerge)
601 if not branchmerge:
601 if not branchmerge:
602 repo.dirstate.setbranch(p2.branch())
602 repo.dirstate.setbranch(p2.branch())
@@ -541,3 +541,52 b' Interactions between collapse and keepbr'
541 @@ -0,0 +1,2 @@
541 @@ -0,0 +1,2 @@
542 +d
542 +d
543 +blah
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