Patchwork D6950: sidedatacopies: write copies information in sidedata when applicable

login
register
mail settings
Submitter phabricator
Date Oct. 3, 2019, 5:56 a.m.
Message ID <differential-rev-PHID-DREV-c72l67xl57fy5uafzpo3-req@mercurial-scm.org>
Download mbox | patch
Permalink /patch/41938/
State Superseded
Headers show

Comments

phabricator - Oct. 3, 2019, 5:56 a.m.
marmoute created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  If the format of the repository indicate it stores copies information into
  changeset's sidedata, then we actually write that information into sidedata at
  commit time. It will be put to use in later changesets.
  
  Currently, we store all field unconditionally, but that is likely to change in
  the future for the sake of efficiency.

REPOSITORY
  rHG Mercurial

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

AFFECTED FILES
  mercurial/changelog.py
  mercurial/interfaces/repository.py
  mercurial/localrepo.py
  mercurial/revlogutils/sidedata.py
  tests/test-copies-in-changeset.t

CHANGE DETAILS




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

Patch

diff --git a/tests/test-copies-in-changeset.t b/tests/test-copies-in-changeset.t
--- a/tests/test-copies-in-changeset.t
+++ b/tests/test-copies-in-changeset.t
@@ -75,7 +75,17 @@ 
   p1copies: 0\x00a (esc)
   1\x00a (esc)
   2\x00a (esc)
-
+#else
+  $ hg debugsidedata -c -v -- -1
+  4 sidedata entries
+   entry-0010 size 11
+    '0\x00a\n1\x00a\n2\x00a'
+   entry-0011 size 0
+    ''
+   entry-0012 size 5
+    '0\n1\n2'
+   entry-0013 size 0
+    ''
 #endif
 
   $ hg showcopies
@@ -107,6 +117,17 @@ 
   
   p1copies: 1\x00b (esc)
 
+#else
+  $ hg debugsidedata -c -v -- -1
+  4 sidedata entries
+   entry-0010 size 3
+    '1\x00b'
+   entry-0011 size 0
+    ''
+   entry-0012 size 1
+    '1'
+   entry-0013 size 1
+    '0'
 #endif
 
   $ hg showcopies
@@ -145,6 +166,17 @@ 
   
   p1copies: 0\x00b2 (esc)
 
+#else
+  $ hg debugsidedata -c -v -- -1
+  4 sidedata entries
+   entry-0010 size 4
+    '0\x00b2'
+   entry-0011 size 0
+    ''
+   entry-0012 size 0
+    ''
+   entry-0013 size 0
+    ''
 #endif
 
   $ hg showcopies
@@ -197,6 +229,17 @@ 
   2\x00f (esc)
   p2copies: 1\x00d (esc)
 
+#else
+  $ hg debugsidedata -c -v -- -1
+  4 sidedata entries
+   entry-0010 size 7
+    '0\x00a\n2\x00f'
+   entry-0011 size 3
+    '1\x00d'
+   entry-0012 size 5
+    '0\n1\n2'
+   entry-0013 size 0
+    ''
 #endif
 
   $ hg showcopies
@@ -218,6 +261,16 @@ 
   p2copies: 
 #else
   $ hg ci -m 'copy a to j'
+  $ hg debugsidedata -c -v -- -1
+  4 sidedata entries
+   entry-0010 size 3
+    '0\x00a'
+   entry-0011 size 0
+    ''
+   entry-0012 size 1
+    '0'
+   entry-0013 size 0
+    ''
 #endif
   $ hg debugdata j 0
   \x01 (esc)
@@ -243,6 +296,16 @@ 
 #else
   $ hg ci --amend -m 'copy a to j, v2'
   saved backup bundle to $TESTTMP/repo/.hg/strip-backup/*-*-amend.hg (glob)
+  $ hg debugsidedata -c -v -- -1
+  4 sidedata entries
+   entry-0010 size 3
+    '0\x00a'
+   entry-0011 size 0
+    ''
+   entry-0012 size 1
+    '0'
+   entry-0013 size 0
+    ''
 #endif
   $ hg showcopies --config experimental.copies.read-from=filelog-only
   a -> j
@@ -260,6 +323,16 @@ 
   p2copies: 
 #else
   $ hg ci -m 'modify j'
+  $ hg debugsidedata -c -v -- -1
+  4 sidedata entries
+   entry-0010 size 0
+    ''
+   entry-0011 size 0
+    ''
+   entry-0012 size 0
+    ''
+   entry-0013 size 0
+    ''
 #endif
 
 Test writing only to filelog
@@ -273,6 +346,16 @@ 
   
 #else
   $ hg ci -m 'copy a to k'
+  $ hg debugsidedata -c -v -- -1
+  4 sidedata entries
+   entry-0010 size 3
+    '0\x00a'
+   entry-0011 size 0
+    ''
+   entry-0012 size 1
+    '0'
+   entry-0013 size 0
+    ''
 #endif
 
   $ hg debugdata k 0
diff --git a/mercurial/revlogutils/sidedata.py b/mercurial/revlogutils/sidedata.py
--- a/mercurial/revlogutils/sidedata.py
+++ b/mercurial/revlogutils/sidedata.py
@@ -48,6 +48,12 @@ 
 SD_TEST6 = 6
 SD_TEST7 = 7
 
+# key to store copies related information
+SD_P1COPIES = 8
+SD_P2COPIES = 9
+SD_FILESADDED = 10
+SD_FILESREMOVED = 11
+
 # internal format constant
 SIDEDATA_HEADER = struct.Struct('>H')
 SIDEDATA_ENTRY = struct.Struct('>HL20s')
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -759,10 +759,13 @@ 
     else: # explicitly mark repo as using revlogv0
         options['revlogv0'] = True
 
-    writecopiesto = ui.config('experimental', 'copies.write-to')
-    copiesextramode = ('changeset-only', 'compatibility')
-    if (writecopiesto in copiesextramode):
-        options['copies-storage'] = 'extra'
+    if COPIESSDC_REQUIREMENT in requirements:
+        options['copies-storage'] = 'changeset-sidedata'
+    else:
+        writecopiesto = ui.config('experimental', 'copies.write-to')
+        copiesextramode = ('changeset-only', 'compatibility')
+        if (writecopiesto in copiesextramode):
+            options['copies-storage'] = 'extra'
 
     return options
 
@@ -1093,6 +1096,10 @@ 
 
         self._extrafilterid = repoview.extrafilter(ui)
 
+        self.filecopiesmode = None
+        if COPIESSDC_REQUIREMENT in self.requirements:
+            self.filecopiesmode = 'changeset-sidedata'
+
     def _getvfsward(self, origfunc):
         """build a ward for self.vfs"""
         rref = weakref.ref(self)
@@ -2686,10 +2693,15 @@ 
         p1, p2 = ctx.p1(), ctx.p2()
         user = ctx.user()
 
-        writecopiesto = self.ui.config('experimental', 'copies.write-to')
-        writefilecopymeta = writecopiesto != 'changeset-only'
-        writechangesetcopy = (writecopiesto in
-                              ('changeset-only', 'compatibility'))
+        if self.filecopiesmode == 'changeset-sidedata':
+            writechangesetcopy = True
+            writefilecopymeta = True
+            writecopiesto = None
+        else:
+            writecopiesto = self.ui.config('experimental', 'copies.write-to')
+            writefilecopymeta = writecopiesto != 'changeset-only'
+            writechangesetcopy = (writecopiesto in
+                                  ('changeset-only', 'compatibility'))
         p1copies, p2copies = None, None
         if writechangesetcopy:
             p1copies = ctx.p1copies()
diff --git a/mercurial/interfaces/repository.py b/mercurial/interfaces/repository.py
--- a/mercurial/interfaces/repository.py
+++ b/mercurial/interfaces/repository.py
@@ -1463,6 +1463,9 @@ 
     names = interfaceutil.Attribute(
         """A ``namespaces`` instance.""")
 
+    filecopiesmode = interfaceutil.Attribute(
+        """The way files copies should be dealt with in this repo.""")
+
     def close():
         """Close the handle on this repository."""
 
diff --git a/mercurial/changelog.py b/mercurial/changelog.py
--- a/mercurial/changelog.py
+++ b/mercurial/changelog.py
@@ -29,6 +29,10 @@ 
     stringutil,
 )
 
+from .revlogutils import (
+    sidedata as sidedatamod,
+)
+
 _defaultextra = {'branch': 'default'}
 
 def _string_escape(text):
@@ -635,6 +639,7 @@ 
                 raise error.StorageError(_('the name \'%s\' is reserved')
                                          % branch)
         sortedfiles = sorted(files)
+        sidedata = None
         if extra is not None:
             for name in ('p1copies', 'p2copies', 'filesadded', 'filesremoved'):
                 extra.pop(name, None)
@@ -658,13 +663,24 @@ 
                 extra['filesadded'] = filesadded
             if filesremoved is not None:
                 extra['filesremoved'] = filesremoved
+        elif self._copiesstorage == 'changeset-sidedata':
+            sidedata = {}
+            if p1copies is not None:
+                sidedata[sidedatamod.SD_P1COPIES] = p1copies
+            if p2copies is not None:
+                sidedata[sidedatamod.SD_P2COPIES] = p2copies
+            if filesadded is not None:
+                sidedata[sidedatamod.SD_FILESADDED] = filesadded
+            if filesremoved is not None:
+                sidedata[sidedatamod.SD_FILESREMOVED] = filesremoved
 
         if extra:
             extra = encodeextra(extra)
             parseddate = "%s %s" % (parseddate, extra)
         l = [hex(manifest), user, parseddate] + sortedfiles + ["", desc]
         text = "\n".join(l)
-        return self.addrevision(text, transaction, len(self), p1, p2)
+        return self.addrevision(text, transaction, len(self), p1, p2,
+                                sidedata=sidedata)
 
     def branchinfo(self, rev):
         """return the branch name and open/close state of a revision