Comments
Patch
@@ -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 ..
@@ -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
@@ -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"""