changeset 35:4e6c1a940dbe

Snapshot files: allow missing sections and sort by root. New tree_sections(cfg,withtop) returns all sections in cfg matching "^tree(\w+)$", sorted by their roots. This aids manual snapshot maintenance: numbered sections [tree5] can be missing from the sequence, and named sections like [treeSomething] will work without changing tree order of from ftrees/fstatus etc. Tests included.
author Mark White <mark@celos.net>
date Mon, 18 Dec 2006 21:48:13 +0000
parents 3668035ca554
children 01a10f7bd85c
files forest.py test-forest test-forest.out
diffstat 3 files changed, 140 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/forest.py	Sun Dec 17 20:01:29 2006 +0100
+++ b/forest.py	Mon Dec 18 21:48:13 2006 +0000
@@ -33,6 +33,7 @@
 
 import ConfigParser
 import os
+import re
 
 from mercurial import commands, hg, node, util
 from mercurial.i18n import gettext as _
@@ -68,6 +69,29 @@
     return res
 
 
+tree_section_re = re.compile(r"^tree(\w+)$")
+
+def tree_sections(cfg, withtop=True):
+    """Return lexicographically sorted list of tree sections."""
+
+    allsecs = cfg.sections()
+    secs = []
+    top = None
+    for s in allsecs:
+        if tree_section_re.match(s):
+            secs.append(s)
+            if cfg.get(s, "root") == ".":
+                top = s
+    if top is None:
+        raise util.Abort(_("snapshot has no entry with root '.'"))
+    secs.sort(lambda a,b: cmp(cfg.get(a, "root"), cfg.get(b, "root")))
+    # ensure that '.' comes first, regardless of sort
+    secs.remove(top)
+    if withtop:
+        secs.insert(0, top)
+    return secs
+
+
 def mq_patches_applied(rpath):
     rpath = os.path.join(rpath, ".hg")
     entries = os.listdir(rpath)
@@ -128,12 +152,7 @@
         if snapfile is not None:
             cfg = ConfigParser.RawConfigParser()
             cfg.read([snapfile])
-            index = 0
-            while True:
-                index += 1
-                section = "tree" + str(index)
-                if not cfg.has_section(section):
-                    break
+            for section in tree_sections(cfg):
                 root = cfg.get(section, 'root')
                 tree = ForestSnapshot.Tree(root, cfg.get(section, 'revision'),
                                            dict(cfg.items(section + '.paths')))
@@ -286,15 +305,7 @@
     cfg = ConfigParser.RawConfigParser()
     cfg.read(snapshot)
     pfx = opts['root']
-    if pfx:
-        index = 0
-    else:
-        index = 1
-    while True:
-        index += 1
-        section = 'tree' + str(index)
-        if not cfg.has_section(section):
-            break
+    for section in tree_sections(cfg, bool(pfx)):
         root = cfg.get(section, 'root')
         ui.write("[%s]\n" % root)
         dest = os.path.normpath(os.path.join(pfx, util.localpath(root)))
@@ -321,7 +332,6 @@
         ui.write("\n")
 
 
-
 def snapshot(ui, repo, snapfile=None, **opts):
     """Generate a new or updated forest snapshot and display it."""
 
--- a/test-forest	Sun Dec 17 20:01:29 2006 +0100
+++ b/test-forest	Mon Dec 18 21:48:13 2006 +0000
@@ -68,6 +68,33 @@
 hg commit --cwd topcopy/d/d -m "remove new file" -d "0 0"
 hg fpush --cwd topcopy ../top-snap default | sed "s@$HGTMP@HGTMP@g"
 
+echo "# fseed and fpull, missing section"
+cat top-snap | \
+    sed -e '/\[tree2\]/,/^$/ d' \
+        -e '/\[tree2.paths\]/,/^$/ d' > top-snap-missing
+# with --root
+hg fseed --root missing top-snap-missing default
+hg ftrees --cwd missing
+rm -rf missing
+# without --root
+hg init missing
+hg fseed --cwd missing ../top-snap-missing default
+hg ftrees --cwd missing
+# pull (should find toplevel changesets)
+hg fpull --cwd missing ../top-snap-missing default \
+    | sed "s@$HGTMP@HGTMP@g"
+rm -rf missing
+
+echo "# fseed and fpull, named section"
+cat top-snap | \
+  sed 's/\[tree2/\[treenamed/' > top-snap-named
+hg fseed --root named top-snap-named default
+hg ftrees --cwd named
+# pull (should find nothing)
+hg fpull --cwd named ../top-snap-named default \
+    | sed "s@$HGTMP@HGTMP@g"
+rm -rf named
+
 # create an mq patch in topcopy/t
 hg qinit --cwd topcopy/t
 hg qnew --cwd topcopy/t mq-patch
--- a/test-forest.out	Sun Dec 17 20:01:29 2006 +0100
+++ b/test-forest.out	Mon Dec 18 21:48:13 2006 +0000
@@ -161,6 +161,93 @@
 adding file changes
 added 1 changesets with 1 changes to 1 files
 
+# fseed and fpull, missing section
+[.]
+3 files updated, 0 files merged, 0 files removed, 0 files unresolved
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+[t]
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+[t/t]
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+.
+t
+t/t
+[t]
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+[t/t]
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+.
+t
+t/t
+[.]
+pulling from HGTMP/test-forest/toplevel
+requesting all changes
+adding changesets
+adding manifests
+adding file changes
+added 3 changesets with 4 changes to 4 files
+(run 'hg update' to get a working copy)
+
+[t]
+pulling from HGTMP/test-forest/toplevel/t
+searching for changes
+no changes found
+
+[t/t]
+pulling from HGTMP/test-forest/toplevel/t/t
+searching for changes
+no changes found
+
+# fseed and fpull, named section
+[.]
+3 files updated, 0 files merged, 0 files removed, 0 files unresolved
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+[d/d/t]
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+[t]
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+[t/t]
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+.
+d/d/t
+t
+t/t
+[.]
+pulling from HGTMP/test-forest/toplevel
+searching for changes
+no changes found
+
+[d/d/t]
+pulling from HGTMP/test-forest/toplevel/d/d/t
+searching for changes
+no changes found
+
+[t]
+pulling from HGTMP/test-forest/toplevel/t
+searching for changes
+no changes found
+
+[t/t]
+pulling from HGTMP/test-forest/toplevel/t/t
+searching for changes
+no changes found
+
 # fstatus + mq
 [.]