# HG changeset patch # User Simon Law # Date 1188236905 14400 # Node ID f0d10035b05815b1743dacd64a5f5332a3ba2549 # Parent e19e732274b73a52b835986cc6cb14626e080100 `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: 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): @@ -544,6 +541,31 @@ 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 @@ forest.write(ui, opts['compatible']) -def status(ui, repo, walkhg='', *pats, **opts): - """Display the status of a forest of working directories.""" +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 doit(repo, root, path, rev, mq_applied): - if mq_applied: - ui.write("*mq*\n") - commands.status(repo.ui, repo, *pats, **opts) + 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) - snapshot = ForestSnapshot() - snapshot.update(ui, repo, False, walkhgenabled(ui, walkhg)) - snapshot(ui, repo, doit) + @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): @@ -1091,6 +1156,8 @@ snapshot(ui, toprepo, doit) +cmdtable = None + def uisetup(ui): global cmdtable walkhgopts = ('', 'walkhg', '', @@ -1128,10 +1195,10 @@ _("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 @@ + 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 @@ [.] [d/d/t] -M f +M d/d/t/f [e/d] [t] [t/t] -? f2 +? t/t/f2 [.] @@ -495,15 +495,15 @@ [e/d] [t] -*mq* +warning: 't' has mq patches applied [t/t] -*mq* +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 @@ ? b [a] -? b -? c +? a/b +? a/c [a/a]