D7616: exchange: ensure all outgoing subrepo references are present before pushing

mharbison72 (Matt Harbison) phabricator at mercurial-scm.org
Tue Dec 17 07:56:57 EST 2019


Closed by commit rHG4b7d5d10c45d: exchange: ensure all outgoing subrepo references are present before pushing (authored by mharbison72).
This revision was automatically updated to reflect the committed changes.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7616?vs=18646&id=18808

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7616/new/

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

AFFECTED FILES
  mercurial/exchange.py
  mercurial/subrepo.py
  tests/test-amend-subrepo.t

CHANGE DETAILS

diff --git a/tests/test-amend-subrepo.t b/tests/test-amend-subrepo.t
--- a/tests/test-amend-subrepo.t
+++ b/tests/test-amend-subrepo.t
@@ -164,4 +164,35 @@
   R .hgsub
   R .hgsubstate
 
+broken repositories will refuse to push
+
+#if obsstore-off
+  $ hg up -q -C 2
+#else
+  $ hg up -q -C 6
+#endif
+  $ echo c >> t/b
+  $ hg amend -q -R t
+
+  $ hg init ../dest
+  $ hg init ../dest/t
+  $ hg init ../dest/s
+  $ hg push -q ../dest
+  abort: subrepo 't' is hidden in revision 04aa62396ec6 (obsstore-on !)
+  abort: subrepo 't' not found in revision 04aa62396ec6 (obsstore-off !)
+  [255]
+
+... unless forced
+
+  $ hg push --force -q ../dest
+  $ hg verify -R ../dest
+  checking changesets
+  checking manifests
+  crosschecking files in changesets and manifests
+  checking files
+  checked 5 changesets with 12 changes to 4 files
+  checking subrepo links
+  subrepo 't' not found in revision 04aa62396ec6
+  subrepo 't' not found in revision 6bce99600681
+
   $ cd ..
diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py
--- a/mercurial/subrepo.py
+++ b/mercurial/subrepo.py
@@ -429,10 +429,12 @@
         convert this repository from shared to normal storage.
         '''
 
-    def verify(self):
-        '''verify the integrity of the repository.  Return 0 on success or
-        warning, 1 on any error.
-        '''
+    def verify(self, onpush=False):
+        """verify the revision of this repository that is held in `_state` is
+        present and not hidden.  Return 0 on success or warning, 1 on any
+        error.  In the case of ``onpush``, warnings or errors will raise an
+        exception if the result of pushing would be a broken remote repository.
+        """
         return 0
 
     @propertycache
@@ -1013,26 +1015,35 @@
 
         hg.unshare(self.ui, self._repo)
 
-    def verify(self):
+    def verify(self, onpush=False):
         try:
             rev = self._state[1]
             ctx = self._repo.unfiltered()[rev]
             if ctx.hidden():
                 # Since hidden revisions aren't pushed/pulled, it seems worth an
                 # explicit warning.
-                ui = self._repo.ui
-                ui.warn(
-                    _(b"subrepo '%s' is hidden in revision %s\n")
-                    % (self._relpath, node.short(self._ctx.node()))
+                msg = _(b"subrepo '%s' is hidden in revision %s") % (
+                    self._relpath,
+                    node.short(self._ctx.node()),
                 )
+
+                if onpush:
+                    raise error.Abort(msg)
+                else:
+                    self._repo.ui.warn(b'%s\n' % msg)
             return 0
         except error.RepoLookupError:
             # A missing subrepo revision may be a case of needing to pull it, so
-            # don't treat this as an error.
-            self._repo.ui.warn(
-                _(b"subrepo '%s' not found in revision %s\n")
-                % (self._relpath, node.short(self._ctx.node()))
+            # don't treat this as an error for `hg verify`.
+            msg = _(b"subrepo '%s' not found in revision %s") % (
+                self._relpath,
+                node.short(self._ctx.node()),
             )
+
+            if onpush:
+                raise error.Abort(msg)
+            else:
+                self._repo.ui.warn(b'%s\n' % msg)
             return 0
 
     @propertycache
diff --git a/mercurial/exchange.py b/mercurial/exchange.py
--- a/mercurial/exchange.py
+++ b/mercurial/exchange.py
@@ -646,6 +646,8 @@
                 pushop.repo.checkpush(pushop)
                 _checkpublish(pushop)
                 _pushdiscovery(pushop)
+                if not pushop.force:
+                    _checksubrepostate(pushop)
                 if not _forcebundle1(pushop):
                     _pushbundle2(pushop)
                 _pushchangeset(pushop)
@@ -694,6 +696,17 @@
         step(pushop)
 
 
+def _checksubrepostate(pushop):
+    """Ensure all outgoing referenced subrepo revisions are present locally"""
+    for n in pushop.outgoing.missing:
+        ctx = pushop.repo[n]
+
+        if b'.hgsub' in ctx.manifest() and b'.hgsubstate' in ctx.files():
+            for subpath in sorted(ctx.substate):
+                sub = ctx.sub(subpath)
+                sub.verify(onpush=True)
+
+
 @pushdiscovery(b'changeset')
 def _pushdiscoverychangeset(pushop):
     """discover the changeset that need to be pushed"""



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


More information about the Mercurial-devel mailing list