Patchwork D1106: context: add workingfilectx.markcopied

login
register
mail settings
Submitter phabricator
Date Oct. 16, 2017, 3:40 a.m.
Message ID <differential-rev-PHID-DREV-bi4q4z55l3pvgkyj4ead-req@phab.mercurial-scm.org>
Download mbox | patch
Permalink /patch/24965/
State Superseded
Headers show

Comments

phabricator - Oct. 16, 2017, 3:40 a.m.
phillco created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  With in-memory merge, copy information needs to be stored in-memory, not in the
  dirstate.
  
  To make this transition easy, move the existing dirstate-based approach to
  workingfilectx; that way, other implementations can choose to store it
  somewhere else.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D1106

AFFECTED FILES
  hgext/rebase.py
  mercurial/context.py
  mercurial/copies.py
  mercurial/merge.py

CHANGE DETAILS




To: phillco, #hg-reviewers
Cc: mercurial-devel
phabricator - Oct. 16, 2017, 6:12 p.m.
phillco added a comment.


  I could split out the wctx passing, if necessary.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D1106

To: phillco, #hg-reviewers
Cc: mercurial-devel
phabricator - Oct. 19, 2017, 5:32 a.m.
martinvonz added inline comments.

INLINE COMMENTS

> context.py:1938
>  
> +    def markcopied(self, src):
> +        """marks this file a copy of `src`"""

I would probably have put this on workingctx instead (not per file). It feels like it better matches how copies are recorded in the dirstate (which is not per file). It looks like this would be a little simpler that way. Will future patches be simpler by doing it on the workingfilectx instead?

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D1106

To: phillco, #hg-reviewers, durin42
Cc: martinvonz, mercurial-devel

Patch

diff --git a/mercurial/merge.py b/mercurial/merge.py
--- a/mercurial/merge.py
+++ b/mercurial/merge.py
@@ -2001,5 +2001,5 @@ 
         repo.setparents(repo['.'].node(), pother)
         repo.dirstate.write(repo.currenttransaction())
         # fix up dirstate for copies and renames
-        copies.duplicatecopies(repo, ctx.rev(), pctx.rev())
+        copies.duplicatecopies(repo, repo[None], ctx.rev(), pctx.rev())
     return stats
diff --git a/mercurial/copies.py b/mercurial/copies.py
--- a/mercurial/copies.py
+++ b/mercurial/copies.py
@@ -842,7 +842,7 @@ 
                         data['incompletediverge'][sf] = [of, f]
                     return
 
-def duplicatecopies(repo, rev, fromrev, skiprev=None):
+def duplicatecopies(repo, wctx, rev, fromrev, skiprev=None):
     '''reproduce copies from fromrev to rev in the dirstate
 
     If skiprev is specified, it's a revision that should be used to
@@ -863,5 +863,4 @@ 
         # actually be in the dirstate
         if dst in exclude:
             continue
-        if repo.dirstate[dst] in "nma":
-            repo.dirstate.copy(src, dst)
+        wctx[dst].markcopied(src)
diff --git a/mercurial/context.py b/mercurial/context.py
--- a/mercurial/context.py
+++ b/mercurial/context.py
@@ -1935,6 +1935,11 @@ 
         self._repo.wwrite(self._path, data, flags,
                           backgroundclose=backgroundclose)
 
+    def markcopied(self, src):
+        """marks this file a copy of `src`"""
+        if self._repo.dirstate[self._path] in "nma":
+            self._repo.dirstate.copy(src, self._path)
+
     def clearunknown(self):
         """Removes conflicting items in the working directory so that
         ``write()`` can be called successfully.
diff --git a/hgext/rebase.py b/hgext/rebase.py
--- a/hgext/rebase.py
+++ b/hgext/rebase.py
@@ -977,18 +977,19 @@ 
         repo.ui.debug("   detach base %d:%s\n" % (base, repo[base]))
     # When collapsing in-place, the parent is the common ancestor, we
     # have to allow merging with it.
+    wctx = repo[None]
     stats = mergemod.update(repo, rev, True, True, base, collapse,
                             labels=['dest', 'source'])
     if collapse:
-        copies.duplicatecopies(repo, rev, dest)
+        copies.duplicatecopies(repo, wctx, rev, dest)
     else:
         # If we're not using --collapse, we need to
         # duplicate copies between the revision we're
         # rebasing and its first parent, but *not*
         # duplicate any copies that have already been
         # performed in the destination.
         p1rev = repo[rev].p1().rev()
-        copies.duplicatecopies(repo, rev, p1rev, skiprev=dest)
+        copies.duplicatecopies(repo, wctx, rev, p1rev, skiprev=dest)
     return stats
 
 def adjustdest(repo, rev, destmap, state, skipped):