[PATCH 2 of 2] subrepo: hg pushes into local subrepos, after with source

alexraynepe196 at gmail.com alexraynepe196 at gmail.com
Thu Sep 12 21:46:19 UTC 2024


# HG changeset patch
# User alexrayne
# Date 1726176902 -10800
#      Fri Sep 13 00:35:02 2024 +0300
# Node ID fca662b31c85f27ecc0221c64666cafd9a9bbb97
# Parent  a000ac71e41a56e3b1c7697f44e34683d0fd47bd
subrepo: hg pushes into local subrepos, after with source.
        when --force claimed, subrepo push into local besides source

*       this should handy when push repo on local copy - flash/net-drive,
        and suposed sources not available. Since  There were aborted push if
        any subrepo source not avail, and it ocasionaly prevents
        save repo history on local/flash copyes.

diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py
--- a/mercurial/subrepo.py
+++ b/mercurial/subrepo.py
@@ -877,19 +877,38 @@
                     % (subrelpath(self), urlutil.hidepassword(dsturl))
                 )
                 return None
-        self.ui.status(
-            _(b'pushing subrepo %s to %s\n')
-            % (subrelpath(self), urlutil.hidepassword(dsturl))
-        )
-        other = hg.peer(self._repo, {b'ssh': ssh}, dsturl)
+
+        def dstpush(dsturl):
+            self.ui.status(
+                _(b'pushing subrepo %s to %s\n')
+                % (subrelpath(self), urlutil.hidepassword(dsturl))
+            )
+            other = hg.peer(self._repo, {b'ssh': ssh}, dsturl)
+            try:
+                res = exchange.push(self._repo, other, force, newbranch=newbranch).cgresult
+            finally:
+                other.close()
+            self._cachestorehash(dsturl)
+            return res
+
         try:
-            res = exchange.push(self._repo, other, force, newbranch=newbranch)
-        finally:
-            other.close()
+            res = dstpush(dsturl)
+        except:
+            if not force:
+                raise
+            if not (urlutil.url(self._repo.path).islocal):
+                raise
+            res = None;
+            
+        if res or force:
+            # push into local subrepo too
+            if (urlutil.url(self._repo.path).islocal):
+                localurl = _abssource(self._repo, None)
+                if util.normpath(localurl) != util.normpath(dsturl):
+                    res = dstpush(localurl)
 
         # the repo is now clean
-        self._cachestorehash(dsturl)
-        return res.cgresult
+        return res
 
     @annotatesubrepoerror
     def outgoing(self, ui, dest, opts):
diff --git a/mercurial/subrepoutil.py b/mercurial/subrepoutil.py
--- a/mercurial/subrepoutil.py
+++ b/mercurial/subrepoutil.py
@@ -15,6 +15,7 @@
     Any,
     Dict,
     List,
+    Union,
     Optional,
     Set,
     Tuple,
@@ -450,13 +451,17 @@
 
 def _abssource(
     repo: "localrepo.localrepository",
-    push: bool = False,
+    push: Union[bool, None] = False,
     abort: bool = True,
 ) -> Optional[bytes]:
     """return pull/push path of repo - either based on parent repo .hgsub info
-    or on the top repo config. Abort or return None if no source found."""
+    or on the top repo config. Abort or return None if no source found.
+    @arg push = None - supposed absolute path of repo besides source 
+    """
     if hasattr(repo, '_subparent'):
         source = repo._subsource
+        if push is None:
+            source = None
         if not source:
             if hasattr(repo, '_relpath'):
                 if urlutil.url(repo.root).islocal:



More information about the Mercurial-devel mailing list