[PATCH 08 of 12] Teach hg.clone to do overlay clones

Brendan Cully brendan at kublai.com
Tue Jan 2 15:42:20 CST 2007


# HG changeset patch
# User Brendan Cully <brendan at kublai.com>
# Date 1167777087 18000
# Node ID a0aef76bfa731112105f940f6fa8fd8751e8f726
# Parent  20ea1edd61887ffc98d1767b466dfde54c2e4f1a
Teach hg.clone to do overlay clones

diff --git a/mercurial/hg.py b/mercurial/hg.py
--- a/mercurial/hg.py
+++ b/mercurial/hg.py
@@ -64,7 +64,7 @@ def defaultdest(source):
     return os.path.basename(os.path.normpath(source))
 
 def clone(ui, source, dest=None, pull=False, rev=None, update=True,
-          stream=False):
+          stream=False, overlay=False):
     """Make a copy of an existing repository.
 
     Create a copy of an existing repository in a new directory.  The
@@ -74,7 +74,8 @@ def clone(ui, source, dest=None, pull=Fa
 
     The location of the source is added to the new repository's
     .hg/hgrc file, as the default to be used for future pulls and
-    pushes.
+    pushes. If overlay is True, that location is also used for
+    the parent.
 
     If an exception is raised, the partly cloned/updated destination
     repository will be deleted.
@@ -95,6 +96,9 @@ def clone(ui, source, dest=None, pull=Fa
 
     update: update working directory after clone completes, if
     destination is local repository
+
+    overlay: make the destination an overlay repository (use the
+    source repository for unavailable revisions)
     """
     if isinstance(source, str):
         src_repo = repository(ui, source)
@@ -138,6 +142,8 @@ def clone(ui, source, dest=None, pull=Fa
     if src_repo.local() and islocal(dest):
         abspath = os.path.abspath(source)
         copy = not pull and not rev
+    elif overlay:
+        raise util.Abort(_('overlay is only available for local clones'))
 
     src_lock, dest_lock = None, None
     if copy:
@@ -174,13 +180,22 @@ def clone(ui, source, dest=None, pull=Fa
         # we lock here to avoid premature writing to the target
         dest_lock = lock.lock(os.path.join(dest_store, "lock"))
 
-        files = ("data",
-                 "00manifest.d", "00manifest.i",
-                 "00changelog.d", "00changelog.i")
-        for f in files:
-            src = os.path.join(src_store, f)
-            dst = os.path.join(dest_store, f)
-            force_copy(src, dst)
+        if overlay:
+            # Fork changelog, leave everything else alone
+            src_repo.changelog.fork(util.opener(dest_store))
+            ropen = util.opener(dest_path)
+            fp = ropen("hgrc", "w", text=True)
+            fp.write("[repository]\n")
+            fp.write("parent = %s\n" % abspath)
+            fp.close()
+        else:
+            files = ("data",
+                     "00manifest.d", "00manifest.i",
+                     "00changelog.d", "00changelog.i")
+            for f in files:
+                src = os.path.join(src_store, f)
+                dst = os.path.join(dest_store, f)
+                force_copy(src, dst)
 
         # we need to re-init the repo after manually copying the data
         # into it
@@ -212,7 +227,7 @@ def clone(ui, source, dest=None, pull=Fa
         src_lock.release()
 
     if dest_repo.local():
-        fp = dest_repo.opener("hgrc", "w", text=True)
+        fp = dest_repo.opener("hgrc", "a", text=True)
         fp.write("[paths]\n")
         fp.write("default = %s\n" % abspath)
         fp.close()


More information about the Mercurial-devel mailing list