Patchwork D9570: debugcommands: introduce command to upgrade/downgrade shares

login
register
mail settings
Submitter phabricator
Date Dec. 12, 2020, 10:47 a.m.
Message ID <differential-rev-PHID-DREV-c6l6nv2yblvdmxc3p7xy-req@mercurial-scm.org>
Download mbox | patch
Permalink /patch/47869/
State New
Headers show

Comments

phabricator - Dec. 12, 2020, 10:47 a.m.
pulkit created this revision.
Herald added a reviewer: hg-reviewers.
Herald added a subscriber: mercurial-patches.

REVISION SUMMARY
  In past few months, we have developed functionality to share requirements and
  configs of share-source and a way to upgrade repository from old format to
  share-safe format using `debugupgraderepo` command.
  
  However there is still no way to upgrade the shares as `debugupgraderepo` does
  not support upgrading that.
  
  Having share-safe rolled out in existing setup is quite important and hence we
  need a way to upgrade existing shares once share-source upgrades.
  
  This patch introduces a new debug command `debugsharesafe` which can be used to
  upgrade or downgrade shares.
  
  Functionality to upgrade shares to use the new method is the last thing left in
  the whole work.

REPOSITORY
  rHG Mercurial

BRANCH
  default

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

AFFECTED FILES
  mercurial/debugcommands.py
  tests/test-completion.t
  tests/test-help.t
  tests/test-share-safe.t

CHANGE DETAILS




To: pulkit, #hg-reviewers
Cc: mercurial-patches, mercurial-devel

Patch

diff --git a/tests/test-share-safe.t b/tests/test-share-safe.t
--- a/tests/test-share-safe.t
+++ b/tests/test-share-safe.t
@@ -70,6 +70,16 @@ 
   $ echo c > c
   $ hg ci -Aqm "added c"
 
+  $ hg debugsharesafe
+  abort: nothing specified
+  [10]
+  $ hg debugsharesafe --upgrade --downgrade
+  abort: cannot specify both --upgrade and --downgrade
+  [10]
+  $ hg debugsharesafe --upgrade
+  abort: repository already uses share-safe method
+  [20]
+
 Check that config of the source repository is also loaded
 
   $ hg showconfig ui.curses
@@ -399,6 +409,26 @@ 
   o  f3ba8b99bb6f897c87bbc1c07b75c6ddf43a4f77: added foo
   
 
+  $ hg debugsharesafe -R ../nss-share --downgrade
+  warning: source repository supports share-safe functionality. Reshare to upgrade.
+  abort: repository does not uses share safe method, nothing to do
+  [20]
+
+  $ hg debugsharesafe -R ../nss-share --upgrade
+  warning: source repository supports share-safe functionality. Reshare to upgrade.
+  repository upgraded to use share-safe functionality
+  requirements and configs of shared-source will be read from now onwards
+
+  $ hg log -GT "{node}: {desc}\n" -R ../nss-share
+  @  f63db81e6dde1d9c78814167f77fb1fb49283f4f: added bar
+  |
+  o  f3ba8b99bb6f897c87bbc1c07b75c6ddf43a4f77: added foo
+  
+
+  $ hg debugsharesafe -R ../nss-share --downgrade
+  repository downgraded to not use share-safe functionality
+
+
 
 Create a safe share from upgrade one
 
diff --git a/tests/test-help.t b/tests/test-help.t
--- a/tests/test-help.t
+++ b/tests/test-help.t
@@ -1068,6 +1068,8 @@ 
    debugserve    run a server with advanced settings
    debugsetparents
                  manually set the parents of the current working directory
+   debugsharesafe
+                 upgrade or downgrade shares to enable/disable share-safe mode
    debugsidedata
                  dump the side data for a cl/manifest/file revision
    debugssl      test a secure connection to a server
diff --git a/tests/test-completion.t b/tests/test-completion.t
--- a/tests/test-completion.t
+++ b/tests/test-completion.t
@@ -129,6 +129,7 @@ 
   debugrevspec
   debugserve
   debugsetparents
+  debugsharesafe
   debugsidedata
   debugssl
   debugstrip
@@ -318,6 +319,7 @@ 
   debugrevspec: optimize, show-revs, show-set, show-stage, no-optimized, verify-optimized
   debugserve: sshstdio, logiofd, logiofile
   debugsetparents: 
+  debugsharesafe: upgrade, downgrade, force
   debugsidedata: changelog, manifest, dir
   debugssl: 
   debugstrip: rev, force, no-backup, nobackup, , keep, bookmark, soft
diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py
--- a/mercurial/debugcommands.py
+++ b/mercurial/debugcommands.py
@@ -69,6 +69,7 @@ 
     pycompat,
     registrar,
     repair,
+    requirements as requirementsmod,
     revlog,
     revset,
     revsetlang,
@@ -3695,6 +3696,107 @@ 
 
 
 @command(
+    b'debugsharesafe',
+    [
+        (b'', b'upgrade', False, _(b'upgrade current share to share safe')),
+        (b'', b'downgrade', False, _(b'downgrade current share')),
+        (b'', b'force', False, _(b'forcefully perform operation')),
+    ],
+)
+def debugsharesafe(ui, repo, *args, **opts):
+    """upgrade or downgrade shares to enable/disable share-safe mode"""
+    if not repo.shared():
+        raise error.InputError(_(b"current repository is not shared one"))
+
+    cmdutil.check_at_most_one_arg(opts, 'upgrade', 'downgrade')
+    upgrade = opts.get('upgrade')
+    downgrade = opts.get('downgrade')
+
+    if not upgrade and not downgrade:
+        raise error.InputError(_(b"nothing specified"))
+
+    current_requirements = repo.requirements
+    if upgrade:
+        if requirementsmod.SHARESAFE_REQUIREMENT in current_requirements:
+            raise error.StateError(
+                _(b"repository already uses share-safe method")
+            )
+
+        sharesourcerequires = localrepo._readrequires(
+            localrepo._getsharedvfs(repo.vfs, current_requirements), False
+        )
+        if requirementsmod.SHARESAFE_REQUIREMENT not in sharesourcerequires:
+            raise error.StateError(
+                _(
+                    b"share source does not support share-safe, unable to upgrade"
+                )
+            )
+
+        # share source has SHARESAFE requirement present, hence all the
+        # requirements will be store requires
+        storerequires = localrepo._readrequires(repo.svfs, False)
+
+        # after upgrade, store requires will be shared, so lets find
+        # the requirements which are not present in store and
+        # write them to share's .hg/requires
+        diffrequires = current_requirements - storerequires
+        # add share-safe requirement as it will mark the share as share-safe
+        diffrequires.add(requirementsmod.SHARESAFE_REQUIREMENT)
+        scmutil.writerequires(repo.vfs, diffrequires)
+        ui.status(_(b"repository upgraded to use share-safe functionality\n"))
+        ui.status(
+            _(
+                b"requirements and configs of shared-source will be "
+                b"read from now onwards\n"
+            )
+        )
+    else:
+        if requirementsmod.SHARESAFE_REQUIREMENT not in current_requirements:
+            raise error.StateError(
+                _(b"repository does not uses share safe method, nothing to do")
+            )
+
+        sharesourcerequires = localrepo._readrequires(
+            localrepo._getsharedvfs(repo.vfs, current_requirements), False
+        )
+
+        if requirementsmod.SHARESAFE_REQUIREMENT in sharesourcerequires:
+            # we should copy the store requires in .hg/requires and remove
+            # share-safe requirement
+            storerequires = localrepo._readrequires(repo.svfs, False)
+            current_requirements |= storerequires
+            current_requirements.remove(requirementsmod.SHARESAFE_REQUIREMENT)
+            scmutil.writerequires(repo.vfs, current_requirements)
+            ui.status(
+                _(
+                    b"repository downgraded to not use share-safe functionality\n"
+                )
+            )
+        else:
+            # share source does not use share-safe and has requirements in
+            # .hg/requires. We cannot be sure which requirement were shared
+            # earlier in share-safe mode. In other words, there can be wdir
+            # specific requirements which should not be copied but we have
+            # no way to detect them
+            if not opts.get('force'):
+                raise error.Abort(
+                    _(
+                        b"shared source does not support share-safe "
+                        b"functionality, downgrading may not lead correct result"
+                    ),
+                    hint=_(b"use --force to still downgrade"),
+                )
+            current_requirements |= sharesourcerequires
+            current_requirements.remove(requirementsmod.SHARESAFE_REQUIREMENT)
+            scmutil.writerequires(repo.vfs, current_requirements)
+            ui.status(
+                _(
+                    b"repository downgraded to not use share-safe functionality\n"
+                )
+            )
+
+
+@command(
     b'debugsub',
     [(b'r', b'rev', b'', _(b'revision to check'), _(b'REV'))],
     _(b'[-r REV] [REV]'),