changeset 52727:48572371d478

clonebundles: allow storing inline clonebundles outside .hg
author Joerg Sonnenberger <joerg@bec.de>
date Tue, 07 Jan 2025 14:05:51 +0100
parents 65839176cea9
children f8f14e6d032b
files hgext/clonebundles.py mercurial/bundlecaches.py mercurial/configitems.toml mercurial/wireprotov1server.py tests/test-clonebundles.t
diffstat 5 files changed, 36 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/hgext/clonebundles.py	Fri Jan 31 15:04:13 2025 +0000
+++ b/hgext/clonebundles.py	Tue Jan 07 14:05:51 2025 +0100
@@ -773,7 +773,8 @@
     inline = repo.ui.config(b'clone-bundles', b'auto-generate.serve-inline')
     basename = repo.vfs.basename(bundle.filepath)
     if inline:
-        dest_dir = repo.vfs.join(bundlecaches.BUNDLE_CACHE_DIR)
+        bundle_cache_root = repo.ui.config(b'server', b'peer-bundle-cache-root')
+        dest_dir = repo.vfs.join(bundle_cache_root)
         repo.vfs.makedirs(dest_dir)
         dest = repo.vfs.join(dest_dir, basename)
         util.copyfiles(bundle.filepath, dest, hardlink=True)
@@ -815,10 +816,8 @@
         repo.ui.debug(msg)
 
     if inline:
-        inline_path = repo.vfs.join(
-            bundlecaches.BUNDLE_CACHE_DIR,
-            bundle.basename,
-        )
+        bundle_cache_root = repo.ui.config(b'server', b'peer-bundle-cache-root')
+        inline_path = repo.vfs.join(bundle_cache_root, bundle.basename)
         util.tryunlink(inline_path)
     else:
         cmd = repo.ui.config(b'clone-bundles', b'delete-command')
--- a/mercurial/bundlecaches.py	Fri Jan 31 15:04:13 2025 +0000
+++ b/mercurial/bundlecaches.py	Tue Jan 07 14:05:51 2025 +0100
@@ -35,7 +35,6 @@
 
 urlreq = util.urlreq
 
-BUNDLE_CACHE_DIR = b'bundle-cache'
 CB_MANIFEST_FILE = b'clonebundles.manifest'
 CLONEBUNDLESCHEME = b"peer-bundle-cache://"
 
--- a/mercurial/configitems.toml	Fri Jan 31 15:04:13 2025 +0000
+++ b/mercurial/configitems.toml	Tue Jan 07 14:05:51 2025 +0100
@@ -2093,6 +2093,11 @@
 default = 3
 
 [[items]]
+section = "server"
+name = "peer-bundle-cache-root"
+default = "bundle-cache"
+
+[[items]]
 section = "share"
 name = "pool"
 
--- a/mercurial/wireprotov1server.py	Fri Jan 31 15:04:13 2025 +0000
+++ b/mercurial/wireprotov1server.py	Tue Jan 07 14:05:51 2025 +0100
@@ -279,17 +279,20 @@
             clonebundlepath=path,
         )
 
-    bundle_dir = repo.vfs.join(bundlecaches.BUNDLE_CACHE_DIR)
-    clonebundlepath = repo.vfs.join(bundle_dir, path)
+    bundle_root = repo.ui.config(b'server', b'peer-bundle-cache-root')
+    bundle_root_dir = repo.vfs.join(bundle_root)
+    clonebundlepath = repo.vfs.join(bundle_root, path)
     if not repo.vfs.exists(clonebundlepath):
         raise error.Abort(b'clonebundle %s does not exist' % path)
 
-    clonebundles_dir = os.path.realpath(bundle_dir)
+    clonebundles_dir = os.path.realpath(bundle_root_dir)
+    # audit invariance: absolute path of the bundle is below the bundle root
     if not os.path.realpath(clonebundlepath).startswith(clonebundles_dir):
         raise error.Abort(b'clonebundle %s is using an illegal path' % path)
 
     def generator(vfs, bundle_path):
-        with vfs(bundle_path) as f:
+        # path audited above already
+        with vfs(bundle_path, auditpath=False) as f:
             length = os.fstat(f.fileno())[6]
             yield util.uvarintencode(length)
             yield from util.filechunkiter(f)
--- a/tests/test-clonebundles.t	Fri Jan 31 15:04:13 2025 +0000
+++ b/tests/test-clonebundles.t	Tue Jan 07 14:05:51 2025 +0100
@@ -255,6 +255,26 @@
   no changes found
   2 local changesets published
 
+Out-of-repo storage for inline bundle
+-------------------------------------
+
+  $ cp -R server server-extern
+  $ cat >> server-extern/.hg/hgrc << EOF
+  > [server]
+  > peer-bundle-cache-root = `pwd`/server/.hg/bundle-cache
+  > EOF
+  $ rm -r server-extern/.hg/bundle-cache
+  $ hg clone -U ssh://user@dummy/server-extern ssh-inline-clone-extern
+  applying clone bundle from peer-bundle-cache://full.hg
+  adding changesets
+  adding manifests
+  adding file changes
+  added 2 changesets with 2 changes to 2 files
+  finished applying clone bundle
+  searching for changes
+  no changes found
+  2 local changesets published
+
 HTTP Supports
 -------------