Patchwork D5990: context: introduce p[12]copies() methods and debugp[12]copies commands

login
register
mail settings
Submitter phabricator
Date Feb. 21, 2019, 2:36 a.m.
Message ID <3da2510d5db7031fac22ce63067a4774@localhost.localdomain>
Download mbox | patch
Permalink /patch/38851/
State Not Applicable
Headers show

Comments

phabricator - Feb. 21, 2019, 2:36 a.m.
This revision was automatically updated to reflect the committed changes.
Closed by commit rHG456ad0fd8e18: context: introduce p[12]copies() methods and debugp[12]copies commands (authored by martinvonz, committed by ).

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D5990?vs=14160&id=14170

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

AFFECTED FILES
  mercurial/context.py
  mercurial/debugcommands.py
  tests/test-completion.t
  tests/test-copies.t
  tests/test-help.t

CHANGE DETAILS




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

Patch

diff --git a/tests/test-help.t b/tests/test-help.t
--- a/tests/test-help.t
+++ b/tests/test-help.t
@@ -1011,6 +1011,10 @@ 
    debugoptADV   (no help text available)
    debugoptDEP   (no help text available)
    debugoptEXP   (no help text available)
+   debugp1copies
+                 dump copy information compared to p1
+   debugp2copies
+                 dump copy information compared to p2
    debugpathcomplete
                  complete part or all of a tracked path
    debugpathcopies
diff --git a/tests/test-copies.t b/tests/test-copies.t
--- a/tests/test-copies.t
+++ b/tests/test-copies.t
@@ -17,12 +17,17 @@ 
   $ echo x > x
   $ hg ci -Aqm 'add x'
   $ hg mv x y
+  $ hg debugp1copies
+  x -> y
+  $ hg debugp2copies
   $ hg ci -m 'rename x to y'
   $ hg l
   @  1 rename x to y
   |  x y
   o  0 add x
      x
+  $ hg debugp1copies -r 1
+  x -> y
   $ hg debugpathcopies 0 1
   x -> y
   $ hg debugpathcopies 1 0
@@ -41,12 +46,17 @@ 
   $ echo y > y
   $ hg ci -Aqm 'add x and y'
   $ hg cp -f x y
+  $ hg debugp1copies
+  x -> y
+  $ hg debugp2copies
   $ hg ci -m 'copy x onto y'
   $ hg l
   @  1 copy x onto y
   |  y
   o  0 add x and y
      x y
+  $ hg debugp1copies -r 1
+  x -> y
 Incorrectly doesn't show the rename
   $ hg debugpathcopies 0 1
 
@@ -63,6 +73,8 @@ 
   |  x2
   o  0 add x and x2 with same content
      x x2
+  $ hg debugp1copies -r 1
+  x -> x2
 Incorrectly doesn't show the rename
   $ hg debugpathcopies 0 1
 
@@ -85,14 +97,19 @@ 
   |  y
   o  0 add x
      x
+  $ hg debugp1copies -r 3
+  x -> y
   $ hg debugpathcopies 0 3
   x -> y
 
 Rename file in a loop: x->y->z->x
   $ newrepo
   $ echo x > x
   $ hg ci -Aqm 'add x'
   $ hg mv x y
+  $ hg debugp1copies
+  x -> y
+  $ hg debugp2copies
   $ hg ci -m 'rename x to y'
   $ hg mv y z
   $ hg ci -m 'rename y to z'
@@ -129,6 +146,7 @@ 
   |  x y
   o  0 add x
      x
+  $ hg debugp1copies -r 3
   $ hg debugpathcopies 0 3
 
 Copy x to z, then remove z, then copy x2 (same content as x) to z. With copy metadata in the
@@ -153,6 +171,8 @@ 
   |  z
   o  0 add x and x2 with same content
      x x2
+  $ hg debugp1copies -r 3
+  x2 -> z
   $ hg debugpathcopies 0 3
   x2 -> z
 
@@ -225,6 +245,8 @@ 
   $ echo z > z
   $ hg ci -Aqm 'add z'
   $ hg merge -q 1
+  $ hg debugp1copies
+  $ hg debugp2copies
   $ hg ci -m 'merge rename from p2'
   $ hg l
   @    3 merge rename from p2
@@ -237,6 +259,8 @@ 
      x
 Perhaps we should indicate the rename here, but `hg status` is documented to be weird during
 merges, so...
+  $ hg debugp1copies -r 3
+  $ hg debugp2copies -r 3
   $ hg debugpathcopies 0 3
   x -> y
   $ hg debugpathcopies 1 2
@@ -254,10 +278,16 @@ 
   $ hg ci -Aqm 'add y'
   $ hg merge -q 0
   $ hg cp y z
+  $ hg debugp1copies
+  y -> z
+  $ hg debugp2copies
   $ hg ci -m 'copy file from p1 in merge'
   $ hg co -q 1
   $ hg merge -q 0
   $ hg cp x z
+  $ hg debugp1copies
+  $ hg debugp2copies
+  x -> z
   $ hg ci -qm 'copy file from p2 in merge'
   $ hg l
   @    3 copy file from p2 in merge
@@ -268,9 +298,15 @@ 
   |    y
   o  0 add x
      x
+  $ hg debugp1copies -r 2
+  y -> z
+  $ hg debugp2copies -r 2
   $ hg debugpathcopies 1 2
   y -> z
   $ hg debugpathcopies 0 2
+  $ hg debugp1copies -r 3
+  $ hg debugp2copies -r 3
+  x -> z
   $ hg debugpathcopies 1 3
   $ hg debugpathcopies 0 3
   x -> z
@@ -284,14 +320,20 @@ 
   $ hg ci -Aqm 'add x on branch 2'
   $ hg merge -q 0
   $ hg cp x z
+  $ hg debugp1copies
+  x -> z
+  $ hg debugp2copies
   $ hg ci -qm 'merge'
   $ hg l
   @    2 merge
   |\   z
   | o  1 add x on branch 2
   |    x
   o  0 add x on branch 1
      x
+  $ hg debugp1copies -r 2
+  x -> z
+  $ hg debugp2copies -r 2
 It's a little weird that it shows up on both sides
   $ hg debugpathcopies 1 2
   x -> z
@@ -312,14 +354,20 @@ 
   $ hg resolve -m x
   (no more unresolved files)
   $ hg cp x z
+  $ hg debugp1copies
+  x -> z
+  $ hg debugp2copies
   $ hg ci -qm 'merge'
   $ hg l
   @    2 merge
   |\   x z
   | o  1 add x on branch 2
   |    x
   o  0 add x on branch 1
      x
+  $ hg debugp1copies -r 2
+  $ hg debugp2copies -r 2
+  x -> z
   $ hg debugpathcopies 1 2
   $ hg debugpathcopies 0 2
   x -> z
@@ -345,6 +393,8 @@ 
   |/   y
   o  0 add x
      x
+  $ hg debugp1copies -r 3
+  $ hg debugp2copies -r 3
   $ hg debugpathcopies 2 3
   x -> y
   $ hg debugpathcopies 1 3
@@ -375,6 +425,9 @@ 
   |/   y
   o  0 add x
      x
+  $ hg debugp1copies -r 3
+  y -> z
+  $ hg debugp2copies -r 3
   $ hg debugpathcopies 2 3
   y -> z
   $ hg debugpathcopies 1 3
diff --git a/tests/test-completion.t b/tests/test-completion.t
--- a/tests/test-completion.t
+++ b/tests/test-completion.t
@@ -103,6 +103,8 @@ 
   debugmergestate
   debugnamecomplete
   debugobsolete
+  debugp1copies
+  debugp2copies
   debugpathcomplete
   debugpathcopies
   debugpeer
@@ -280,6 +282,8 @@ 
   debugmergestate: 
   debugnamecomplete: 
   debugobsolete: flags, record-parents, rev, exclusive, index, delete, date, user, template
+  debugp1copies: rev
+  debugp2copies: rev
   debugpathcomplete: full, normal, added, removed
   debugpathcopies: include, exclude
   debugpeer: 
diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py
--- a/mercurial/debugcommands.py
+++ b/mercurial/debugcommands.py
@@ -1741,6 +1741,28 @@ 
             cmdutil.showmarker(fm, m, index=ind)
         fm.end()
 
+@command('debugp1copies',
+         [('r', 'rev', '', _('revision to debug'), _('REV'))],
+         _('[-r REV]'))
+def debugp1copies(ui, repo, **opts):
+    """dump copy information compared to p1"""
+
+    opts = pycompat.byteskwargs(opts)
+    ctx = scmutil.revsingle(repo, opts.get('rev'), default=None)
+    for dst, src in ctx.p1copies().items():
+        ui.write('%s -> %s\n' % (src, dst))
+
+@command('debugp2copies',
+         [('r', 'rev', '', _('revision to debug'), _('REV'))],
+         _('[-r REV]'))
+def debugp1copies(ui, repo, **opts):
+    """dump copy information compared to p2"""
+
+    opts = pycompat.byteskwargs(opts)
+    ctx = scmutil.revsingle(repo, opts.get('rev'), default=None)
+    for dst, src in ctx.p2copies().items():
+        ui.write('%s -> %s\n' % (src, dst))
+
 @command('debugpathcomplete',
          [('f', 'full', None, _('complete an entire path')),
           ('n', 'normal', None, _('show only normal files')),
diff --git a/mercurial/context.py b/mercurial/context.py
--- a/mercurial/context.py
+++ b/mercurial/context.py
@@ -439,6 +439,29 @@ 
         return self._changeset.date
     def files(self):
         return self._changeset.files
+    @propertycache
+    def _copies(self):
+        p1copies = {}
+        p2copies = {}
+        p1 = self.p1()
+        p2 = self.p2()
+        narrowmatch = self._repo.narrowmatch()
+        for dst in self.files():
+            if not narrowmatch(dst) or dst not in self:
+                continue
+            copied = self[dst].renamed()
+            if not copied:
+                continue
+            src, srcnode = copied
+            if src in p1 and p1[src].filenode() == srcnode:
+                p1copies[dst] = src
+            elif src in p2 and p2[src].filenode() == srcnode:
+                p2copies[dst] = src
+        return p1copies, p2copies
+    def p1copies(self):
+        return self._copies[0]
+    def p2copies(self):
+        return self._copies[1]
     def description(self):
         return self._changeset.description
     def branch(self):
@@ -1158,7 +1181,26 @@ 
     def files(self):
         return sorted(self._status.modified + self._status.added +
                       self._status.removed)
-
+    @propertycache
+    def _copies(self):
+        p1copies = {}
+        p2copies = {}
+        parents = self._repo.dirstate.parents()
+        p1manifest = self._repo[parents[0]].manifest()
+        p2manifest = self._repo[parents[1]].manifest()
+        narrowmatch = self._repo.narrowmatch()
+        for dst, src in self._repo.dirstate.copies().items():
+            if not narrowmatch(dst):
+                continue
+            if src in p1manifest:
+                p1copies[dst] = src
+            elif src in p2manifest:
+                p2copies[dst] = src
+        return p1copies, p2copies
+    def p1copies(self):
+        return self._copies[0]
+    def p2copies(self):
+        return self._copies[1]
     def modified(self):
         return self._status.modified
     def added(self):
@@ -1810,6 +1852,30 @@ 
         return [f for f in self._cache.keys() if
                 not self._cache[f]['exists'] and self._existsinparent(f)]
 
+    def p1copies(self):
+        copies = self._repo._wrappedctx.p1copies().copy()
+        narrowmatch = self._repo.narrowmatch()
+        for f in self._cache.keys():
+            if not narrowmatch(f):
+                continue
+            copies.pop(f, None) # delete if it exists
+            source = self._cache[f]['copied']
+            if source:
+                copies[f] = source
+        return copies
+
+    def p2copies(self):
+        copies = self._repo._wrappedctx.p2copies().copy()
+        narrowmatch = self._repo.narrowmatch()
+        for f in self._cache.keys():
+            if not narrowmatch(f):
+                continue
+            copies.pop(f, None) # delete if it exists
+            source = self._cache[f]['copied']
+            if source:
+                copies[f] = source
+        return copies
+
     def isinmemory(self):
         return True