[cig-commits] commit: fix hg fcmd -R toprepo ...

Mercurial hg at geodynamics.org
Mon Nov 24 11:27:01 PST 2008


changeset:   38:b29f327bdc10
user:        Robin Farine <robin.farine at terminus.org>
date:        Fri Dec 22 02:14:02 2006 +0100
files:       forest.py test-forest test-forest.out
description:
fix hg fcmd -R toprepo ...

Refactor the code so more commands use a ForestSnapshot instance. The
current directory does not influence their behavior and thus using the
global -R option to specify a toplevel repository other than '.' works.


diff -r 44e66014dd8d -r b29f327bdc10 forest.py
--- a/forest.py	Thu Dec 21 16:51:24 2006 +0100
+++ b/forest.py	Fri Dec 22 02:14:02 2006 +0100
@@ -52,20 +52,14 @@ def cmd_options(ui, cmd, remove=None):
     return res
 
 
-def enumerate_repos(ui, top='.'):
+def enumerate_repos(ui, top):
     """Generate a lexicographically sorted list of repository roots.
 
-    When explicit, top must be a normalized path.
+    The roots are absolute paths in the filesystem representation.
     """
 
-    res = util.walkrepos(top)
-    pfxlen = len(top + os.sep)
-    res = [p[pfxlen:] for p in res]
+    res = list(util.walkrepos(top))
     res.sort()
-    # when the prefix is removed from top itself, it yields the empty string;
-    # let's replace it with '.'
-    res.remove('')
-    res.insert(0, '.')
     return res
 
 
@@ -159,14 +153,16 @@ class ForestSnapshot(object):
                 self.rootmap[root] = tree
                 self.trees.append(tree)
 
-    def __call__(self, ui, toprepo, func, pathalias=None):
+    def __call__(self, ui, toprepo, func, pathalias=None, mq_check=True):
         """Apply a function to trees matching a snapshot entry.
 
-        Call func(repo, rev, path) for each repo in toprepo and its
-        nested repositories where repo matches a snapshot entry.
+        Call func(repo, root, path, rev, mq_applied) for each repo in
+        toprepo and its nested repositories where repo matches a
+        snapshot entry.
         """
 
         repo = None
+        pfx = toprepo.root
         for t in self.trees:
             root, rev, path = t.info(pathalias)
             ui.write("[%s]\n" % root)
@@ -178,18 +174,17 @@ class ForestSnapshot(object):
                 repo = toprepo
             else:
                 try:
-                    repo = repository(ui, util.localpath(root))
+                    repo = repository(ui,
+                                      os.path.join(pfx, util.localpath(root)))
                 except RepoError:
                     ui.write(_("skipped, no valid repo found\n\n"))
                     continue
-            if mq_patches_applied(repo.root):
-                ui.write(_("skipped, mq patches applied\n\n"))
-                continue
-            func(repo, path, rev)
+            func(repo, root, path, rev,
+                 mq_check and mq_patches_applied(repo.root))
             ui.write("\n")
 
 
-    def update(self, ui, repo, **opts):
+    def update(self, ui, repo, mq_fatal, tip=False):
         """Update a snapshot by scanning a forest.
 
         If the ForestSnapshot instance to update was initialized from
@@ -201,13 +196,16 @@ class ForestSnapshot(object):
 
         rootmap = {}
         self.trees = []
-        for rpath in enumerate_repos(ui):
-            root = util.pconvert(rpath)
-            if mq_patches_applied(rpath):
+        pfxlen = len(repo.root + os.sep)
+        for rpath in enumerate_repos(ui, repo.root):
+            root = util.pconvert(rpath[pfxlen:])
+            if root == '':
+                root = '.'
+            else:
+                repo = repository(ui, rpath)
+            if mq_fatal and mq_patches_applied(rpath):
                 raise util.Abort(_("'%s' has mq patches applied") % root)
-            if rpath != '.':
-                repo = repository(ui, rpath)
-            if opts['tip']:
+            if tip:
                 rev = 'tip'
             else:
                 rev = node.hex(repo.dirstate.parents()[0])
@@ -233,28 +231,23 @@ class ForestSnapshot(object):
 
 def clone(ui, source, dest, **opts):
     """Clone a local forest."""
-    source = os.path.normpath(source)
     dest = os.path.normpath(dest)
-    opts['rev'] = []
-    roots = []
-    for rpath in enumerate_repos(ui, source):
-        if rpath == '.':
-            srcpath = source
+
+    def doit(repo, root, path, rev, *unused):
+        if root == '.':
             destpath = dest
         else:
-            srcpath = os.path.join(source, rpath)
-            destpath = os.path.join(dest, rpath)
-        if mq_patches_applied(srcpath):
-            raise util.Abort(
-                _("'%s' has mq patches applied") % util.pconvert(rpath))
-        roots.append((rpath, srcpath, destpath))
-    for root in roots:
-        destpfx = os.path.dirname(root[2])
-        if destpfx and not os.path.exists(destpfx):
-            os.makedirs(destpfx)
-        ui.write("[%s]\n" % util.pconvert(root[0]))
-        commands.clone(ui, root[1], root[2], **opts)
-        ui.write("\n")
+            destpath = os.path.join(dest, util.localpath(root))
+            destpfx = os.path.dirname(destpath)
+            if not os.path.exists(destpfx):
+                os.makedirs(destpfx)
+        opts['rev'] = [rev]
+        commands.clone(ui, repo.root, destpath, **opts)
+
+    snapshot = ForestSnapshot()
+    repo = repository(ui, source)
+    snapshot.update(ui, repo, True)
+    snapshot(ui, repo, doit, mq_check=False)
 
 
 def pull(ui, toprepo, snapfile, pathalias, **opts):
@@ -271,8 +264,11 @@ def pull(ui, toprepo, snapfile, pathalia
     opts['force'] = None
     opts['rev'] = []
 
-    def doit(repo, path, *unused):
-        commands.pull(repo.ui, repo, path, **opts)
+    def doit(repo, root, path, rev, mq_applied):
+        if mq_applied:
+            ui.write(_("skipped, mq patches applied\n"))
+        else:
+            commands.pull(repo.ui, repo, path, **opts)
 
     snapshot = ForestSnapshot(snapfile)
     snapshot(ui, toprepo, doit, pathalias)
@@ -292,8 +288,11 @@ def push(ui, toprepo, snapfile, pathalia
     opts['force'] = None
     opts['rev'] = []
 
-    def doit(repo, path, *unused):
-        commands.push(repo.ui, repo, path, **opts)
+    def doit(repo, root, path, rev, mq_applied):
+        if mq_applied:
+            ui.write(_("skipped, mq patches applied\n"))
+        else:
+            commands.push(repo.ui, repo, path, **opts)
 
     snapshot = ForestSnapshot(snapfile)
     snapshot(ui, toprepo, doit, pathalias)
@@ -336,30 +335,33 @@ def snapshot(ui, repo, snapfile=None, **
     """Generate a new or updated forest snapshot and display it."""
 
     snapshot = ForestSnapshot(snapfile)
-    snapshot.update(ui, repo, **opts)
+    snapshot.update(ui, repo, True, **opts)
     snapshot.write(ui)
 
 
 def status(ui, repo, *pats, **opts):
     """Display the status of a forest of working directories."""
 
-    for rpath in enumerate_repos(ui):
-        mqflag = ""
-        if mq_patches_applied(rpath):
-            mqflag = " *mq*"
-        ui.write("[%s]%s\n" % (util.pconvert(rpath), mqflag))
-        repo = repository(ui, rpath)
+    def doit(repo, root, path, rev, mq_applied):
+        if mq_applied:
+            ui.write("*mq*\n")
         commands.status(repo.ui, repo, *pats, **opts)
-        ui.write("\n")
-
-
-def trees(ui, *unused, **opts):
+
+    snapshot = ForestSnapshot()
+    snapshot.update(ui, repo, False)
+    snapshot(ui, repo, doit)
+
+
+def trees(ui, repo, **opts):
     """List the roots of the repositories."""
 
     if opts['convert']:
-        l = [util.pconvert(p) for p in enumerate_repos(ui)]
+        pfxlen = len(repo.root + os.sep)
+        l = [util.pconvert(p[pfxlen:]) for p in enumerate_repos(ui, repo.root)]
+        l.remove('')
+        l.insert(0, '.')
     else:
-        l = enumerate_repos(ui)
+        l = enumerate_repos(ui, repo.root)
     for t in l:
         ui.write(t + '\n')
 
@@ -378,18 +380,18 @@ def update(ui, toprepo, snapfile=None, t
     if snapfile is not None and tip or snapfile is None and not tip:
         raise util.Abort(_("need either --tip or SNAPSHOT-FILE"))
     if tip:
-        for rpath in enumerate_repos(ui):
-            repo = repository(ui, rpath)
-            ui.write("[%s]\n" % util.pconvert(rpath))
-            commands.update(repo.ui, repo, node='tip', **opts)
-            ui.write("\n")
+        snapshot = ForestSnapshot()
+        snapshot.update(ui, toprepo, False, True)
     else:
-
-        def doit(repo, path, rev):
+        snapshot = ForestSnapshot(snapfile)
+
+    def doit(repo, root, path, rev, mq_applied):
+        if mq_applied:
+            ui.write(_("skipped, mq patches applied\n"))
+        else:
             commands.update(repo.ui, repo, node=rev, **opts)
 
-        snapshot = ForestSnapshot(snapfile)
-        snapshot(ui, toprepo, doit)
+    snapshot(ui, toprepo, doit)
 
 
 def uisetup(ui):
diff -r 44e66014dd8d -r b29f327bdc10 test-forest
--- a/test-forest	Thu Dec 21 16:51:24 2006 +0100
+++ b/test-forest	Fri Dec 22 02:14:02 2006 +0100
@@ -49,14 +49,14 @@ hg commit --cwd toplevel/t/t -m "new lin
 hg commit --cwd toplevel/t/t -m "new line" -d "0 0"
 echo "f2" > toplevel/d/d/f2
 hg commit --cwd toplevel/d/d -A -m "new file" -d "0 0"
-hg fsnap --cwd toplevel > top-snap2
+hg fsnap -R toplevel > top-snap2
 diff -u top-snap1 top-snap2 | \
     sed -e 's/--- top-snap1.*$/--- top-snap1/' \
         -e 's/+++ top-snap2.*$/+++ top-snap2/'
 
 echo "# fupdate"
 hg fclone toplevel newtop > /dev/null
-hg fupdate --cwd newtop ../top-snap > /dev/null
+hg fupdate -R newtop top-snap > /dev/null
 hg parents --cwd newtop/d/d/t
 hg parents --cwd newtop/t/t
 hg fupdate --cwd newtop --tip > /dev/null
@@ -66,10 +66,10 @@ rm -rf newtop
 
 echo "# fseed"
 hg clone toplevel newtop
-hg fseed --cwd newtop ../top-snap default
+hg fseed -R newtop top-snap default
 rm -rf newtop
 hg fseed --root newtop top-snap default >/dev/null
-hg --cwd newtop fsnap | sed "s@$HGTMP at HGTMP@g"
+hg fsnap --cwd newtop | sed "s@$HGTMP at HGTMP@g"
 rm -rf newtop
 
 echo "# fpull"
@@ -78,9 +78,9 @@ echo "# fpush"
 echo "# fpush"
 echo "t/t/f" > topcopy/t/t/f
 hg commit --cwd topcopy/t/t -m "delete new line" -d "0 0"
-hg remove --cwd topcopy d/d/f2
-hg commit --cwd topcopy/d/d -m "remove new file" -d "0 0"
-hg fpush --cwd topcopy ../top-snap default | sed "s@$HGTMP at HGTMP@g"
+hg remove --cwd topcopy/d/d f2
+hg commit -R topcopy -m "remove new file" -d "0 0"
+hg fpush -R topcopy top-snap default | sed "s@$HGTMP at HGTMP@g"
 
 echo "# fseed and fpull, missing section"
 cat top-snap | \
@@ -88,14 +88,14 @@ cat top-snap | \
         -e '/\[tree2.paths\]/,/^$/ d' > top-snap-missing
 # with --root
 hg fseed --root missing top-snap-missing default
-hg ftrees --cwd missing
+hg ftrees --cwd missing --convert
 rm -rf missing
 # without --root
 hg init missing
 hg fseed --cwd missing ../top-snap-missing default
-hg ftrees --cwd missing
+hg ftrees -R missing --convert
 # pull (should find toplevel changesets)
-hg fpull --cwd missing ../top-snap-missing default \
+hg fpull -R missing top-snap-missing default \
     | sed "s@$HGTMP at HGTMP@g"
 rm -rf missing
 
@@ -103,7 +103,7 @@ cat top-snap | \
 cat top-snap | \
   sed 's/\[tree2/\[treenamed/' > top-snap-named
 hg fseed --root named top-snap-named default
-hg ftrees --cwd named
+hg ftrees --cwd named --convert
 # pull (should find nothing)
 hg fpull --cwd named ../top-snap-named default \
     | sed "s@$HGTMP at HGTMP@g"
diff -r 44e66014dd8d -r b29f327bdc10 test-forest.out
--- a/test-forest.out	Thu Dec 21 16:51:24 2006 +0100
+++ b/test-forest.out	Fri Dec 22 02:14:02 2006 +0100
@@ -37,18 +37,43 @@ M f
 
 # fclone
 [.]
+requesting all changes
+adding changesets
+adding manifests
+adding file changes
+added 1 changesets with 3 changes to 3 files
 3 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
-
-[e/d]
-1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-
-[t]
-1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-
-[t/t]
+requesting all changes
+adding changesets
+adding manifests
+adding file changes
+added 1 changesets with 1 changes to 1 files
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+[e/d]
+requesting all changes
+adding changesets
+adding manifests
+adding file changes
+added 1 changesets with 1 changes to 1 files
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+[t]
+requesting all changes
+adding changesets
+adding manifests
+adding file changes
+added 1 changesets with 1 changes to 1 files
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+[t/t]
+requesting all changes
+adding changesets
+adding manifests
+adding file changes
+added 1 changesets with 1 changes to 1 files
 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
 # fsnap
@@ -334,7 +359,8 @@ no changes found
 
 [e/d]
 
-[t] *mq*
+[t]
+*mq*
 
 [t/t]
 



More information about the CIG-COMMITS mailing list