[cig-commits] commit: `hg fstatus` now behaves much like `hg status`

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


changeset:   67:f0d10035b058
user:        Simon Law <simon at akoha.org>
date:        Mon Aug 27 13:48:25 2007 -0400
files:       forest.py test-forest.out
description:
`hg fstatus` now behaves much like `hg status`

You can use --quiet to suppress the [.] headings.

With --no-status and the new relative paths, you can feed the output
into xargs.

Finally, you can specify specific files within sub-repositories and
fstatus will do the right thing.


diff -r e19e732274b7 -r f0d10035b058 forest.py
--- a/forest.py	Mon Aug 27 13:45:44 2007 -0400
+++ b/forest.py	Mon Aug 27 13:48:25 2007 -0400
@@ -77,16 +77,13 @@ except:
 except:
     parseurl = cmdutil.parseurl
 
-cmdtable = None
-
-commands.norepo += " fclone fseed"
-
 
 def cmd_options(ui, cmd, remove=None):
     aliases, spec = findcmd(ui, cmd, commands.table)
     res = list(spec[1])
     if remove is not None:
-        res = [opt for opt in res if opt[0] not in remove]
+        res = [opt for opt in res
+               if opt[0] not in remove and opt[1] not in remove]
     return res
 
 def walkhgenabled(ui, walkhg):
@@ -543,6 +540,31 @@ class Forest(object):
             if top.ui:
                 top.ui.note(_("searching for repos in %s\n") % top.root)
             self.scan(walkhg)
+
+    def collate_files(self, pats):
+        """Returns a dictionary of absolute file paths, keyed Tree.
+
+        This lets us iterate over repositories with only the files
+        that belong to them.
+        """
+        result = {}
+        files = [os.path.abspath(path) for path in list(pats)]
+        if files:
+            files.sort(reverse=True)
+            trees = self.trees[:]
+            trees.sort(reverse=True, key=(lambda tree: tree.root))
+            for tree in trees:
+                paths = []
+                for path in files[:]:
+                    if not os.path.exists(path):
+                        raise util.Abort(_("%s not under root") % path)
+                    if path.startswith(tree.root):
+                        paths.append(path)
+                        files.remove(path)
+                if paths:
+                    result[tree] = paths
+        return result
+
 
     def apply(self, ui, function, paths, opts, prehooks=[]):
         """Apply function(repo, targetpath, opts) to the entire forest.
@@ -1037,17 +1059,60 @@ def snap(ui, top, snapshot=None, **opts)
     forest.write(ui, opts['compatible'])
 
 
-def status(ui, repo, walkhg='', *pats, **opts):
-    """Display the status of a forest of working directories."""
-
-    def doit(repo, root, path, rev, mq_applied):
-        if mq_applied:
-            ui.write("*mq*\n")
-        commands.status(repo.ui, repo, *pats, **opts)
-
-    snapshot = ForestSnapshot()
-    snapshot.update(ui, repo, False, walkhgenabled(ui, walkhg))
-    snapshot(ui, repo, doit)
+def status(ui, top, *pats, **opts):
+    """show changed files in the working forest
+
+    Show status of files in this forest's repositories.
+
+    Look at the help text for the status command for more information.
+    """
+    forest = Forest(top=top, walkhg=walkhgenabled(ui, opts['walkhg']))
+    die_on_numeric_revs(opts['rev'])
+    # Figure out which paths are relative to which roots
+    files = forest.collate_files(pats)
+    if files:
+        # Trim which trees we're going to look at
+        forest.trees = files.keys()
+
+    class munge_ui(object):
+        """This wrapper class allows us to munge the mercurial.ui.write() """
+        def __init__(self, transform, ui):
+            self._transform = transform
+            self._ui = ui
+        def write(self, output):
+            self._ui.write(self._transform(output))
+        def __getattr__(self, attrname):
+            return getattr(self._ui, attrname)
+
+    def function(tree, path, opts):
+        path = util.localpath(path)
+        if files:
+            pats = files[tree]
+        else:
+            pats = ()
+            if path == top.root:
+                path = ''
+            else:
+                path = relpath(top.root, path)
+            def prefix(output):
+                """This function shims the root in before the filename."""
+                if opts['no_status']:
+                    return os.path.join(path, output)
+                else:
+                    prefix, filename = output.split(' ', 1)
+                    return ' '.join((prefix, os.path.join(path, filename)))
+            localui = munge_ui(prefix, ui)
+        try:
+            commands.status(localui, tree.repo, *pats, **opts)
+        except RepoError, err:
+            ui.warn(_("skipped: %s\n") % err)
+
+    @Forest.Tree.warn
+    def check_mq(tree):
+        tree.die_on_mq(top.root)
+
+    forest.apply(ui, function, [top.root], opts,
+                 prehooks=[lambda tree: check_mq(tree)])
 
 
 def trees(ui, repo, convert=False, walkhg='', **opts):
@@ -1090,6 +1155,8 @@ def update(ui, toprepo, snapfile=None, t
 
     snapshot(ui, toprepo, doit)
 
+
+cmdtable = None
 
 def uisetup(ui):
     global cmdtable
@@ -1128,10 +1195,10 @@ def uisetup(ui):
                _("record tip instead of actual child revisions")),
               walkhgopts],
              _('hg fsnap [OPTION]... [SNAPSHOT-FILE]')),
-        "fstatus" :
+        "^fstatus|fst" :
             (status,
              [walkhgopts] + cmd_options(ui, 'status'),
-             _('hg fstatus [OPTIONS]')),
+             _('hg fstatus [OPTION]... [FILE]...')),
         "ftrees" :
             (trees,
              [('c', 'convert', False,
@@ -1146,3 +1213,5 @@ def uisetup(ui):
              + cmd_options(ui, 'update', remove=('d',)),
              _('hg fupdate [OPTIONS] (--tip | SNAPSHOT-FILE)'))
         }
+
+commands.norepo += " fclone fseed"
diff -r e19e732274b7 -r f0d10035b058 test-forest.out
--- a/test-forest.out	Mon Aug 27 13:45:44 2007 -0400
+++ b/test-forest.out	Mon Aug 27 13:48:25 2007 -0400
@@ -16,14 +16,14 @@ t/t
 [.]
 
 [d/d/t]
-M f
-
-[e/d]
-
-[t]
-
-[t/t]
-? f2
+M d/d/t/f
+
+[e/d]
+
+[t]
+
+[t/t]
+? t/t/f2
 
 [.]
 
@@ -495,15 +495,15 @@ skipped: received changelog group is emp
 [e/d]
 
 [t]
-*mq*
-
-[t/t]
-*mq*
+warning: 't' has mq patches applied
+
+[t/t]
+warning: 't/t' has mq patches applied
 
 [t/t/.hg/patches]
-A .hgignore
-A mq-patch
-A series
+A t/t/.hg/patches/.hgignore
+A t/t/.hg/patches/mq-patch
+A t/t/.hg/patches/series
 
 # fclone + mq
 [.]
@@ -592,8 +592,8 @@ a
 ? b
 
 [a]
-? b
-? c
+? a/b
+? a/c
 
 [a/a]
 



More information about the CIG-COMMITS mailing list