[PATCH RFC] status: show changed subrepos

Angel Ezquerra angel.ezquerra at gmail.com
Sat Mar 23 08:08:52 CDT 2013

# HG changeset patch
# User Angel Ezquerra <angel.ezquerra at gmail.com>
# Date 1364044094 -3600
#      Sat Mar 23 14:08:14 2013 +0100
# Node ID b157dada53f6a5570fcc166757c13a4362f9f1b5
# Parent  e2feb2896b75863fdff27292db32dbc56b20a3dd
status: show changed subrepos

This is a proof of concept of how we could show "changed subrepos" in the
output of the status command. The idea is to add new "S" status entries, which
show subrepos that have changed (i.e. that have been added, removed or that are
dirty because they have been updated to another revision or because they
contain changed files).

This patch is not complete and is not meant to be included (yet):

- It does not really handle new and deleted subrepos, despite what the docstring

- I added the code right into commands.status because it was very easy to add
there, but a proper version of this patch would probably modify
localrepo.status instead.

Other potential issues and things to discuss:

- I chose --changed-subrepos as the switch longstring to make it clear that it
is not the same as the existing --subrepos flag.

- I made the short version of the switch be "-s". There is already a -S flag. I
don't see that as a big problem since there are other cases where this happens
in mercurial (e.g. update -C vs update -c). Fortunatelly all other similar
switches (e.g. -m, -a) are also lower case.

diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -5121,6 +5121,7 @@
     ('c', 'clean', None, _('show only files without changes')),
     ('u', 'unknown', None, _('show only unknown (not tracked) files')),
     ('i', 'ignored', None, _('show only ignored files')),
+    ('s', 'changed-subrepos', None, _('show only changed subrepos (i.e. new, dirty or deleted)')),
     ('n', 'no-status', None, _('hide status prefix')),
     ('C', 'copies', None, _('show source of copied files')),
     ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
@@ -5161,6 +5162,7 @@
       ! = missing (deleted by non-hg command, but still tracked)
       ? = not tracked
       I = ignored
+      S = changed subrepo (i.e. new, dirty or deleted subrepo)
         = origin of the previous file listed as A (added)
     .. container:: verbose
@@ -5198,7 +5200,7 @@
     cwd = (pats and repo.getcwd()) or ''
     end = opts.get('print0') and '\0' or '\n'
     copy = {}
-    states = 'modified added removed deleted unknown ignored clean'.split()
+    states = 'modified added removed deleted unknown ignored clean changed_subrepos'.split()
     show = [k for k in states if opts.get(k)]
     if opts.get('all'):
         show += ui.quiet and (states[:4] + ['clean']) or states
@@ -5217,6 +5219,16 @@
     fmt = '%s' + end
     showchar = not opts.get('no_status')
+    if 'changed_subrepos' in show:
+        ctx = repo['.']
+        for subname, substate in ctx.substate.items():
+            s = ctx.sub(subname)
+            if s.dirty():
+                label = 'status.subrepo'
+                fm.startitem()
+                fm.condwrite(showchar, 'status', '%s ', 'S', label=label)
+                fm.write('path', fmt, repo.pathto(subname, cwd), label=label)
     for state, char, files in changestates:
         if state in show:
             label = 'status.' + state

More information about the Mercurial-devel mailing list