Patchwork [2,of,2] subrepo: add basic support to hgsubrepo for the files command

login
register
mail settings
Submitter Matt Harbison
Date March 20, 2015, 1:40 a.m.
Message ID <724b1be91b19ee34e88a.1426815636@Envy>
Download mbox | patch
Permalink /patch/8195/
State Accepted
Commit a8595176dd6488f870d264e2eb5f9584c40889f2
Headers show

Comments

Matt Harbison - March 20, 2015, 1:40 a.m.
# HG changeset patch
# User Matt Harbison <matt_harbison@yahoo.com>
# Date 1426734221 14400
#      Wed Mar 18 23:03:41 2015 -0400
# Node ID 724b1be91b19ee34e88a128671745b0388a91380
# Parent  449fccab8331e05fb69d967b6916ebac9be614b7
subrepo: add basic support to hgsubrepo for the files command

Paths into the subrepo are not yet supported.

The need to use the workingctx in the subrepo will likely be used more in the
future, with the proposed working directory revset symbol.  It is also needed
with archive, if that code is to be reused to support 'extdiff -S'.
Unfortunately, it doesn't seem possible to put the smarts in subrepo.subrepo(),
as it breaks various status and diff tests.

I opted not to pass the desired revision into the subrepo method explicitly,
because the only ones that do pass an explicit revision are methods like status
and diff, which actually operate on two contexts- the subrepo state and the
explicitly passed revision.
Matt Mackall - March 20, 2015, 7:56 p.m.
On Thu, 2015-03-19 at 21:40 -0400, Matt Harbison wrote:
> # HG changeset patch
> # User Matt Harbison <matt_harbison@yahoo.com>
> # Date 1426734221 14400
> #      Wed Mar 18 23:03:41 2015 -0400
> # Node ID 724b1be91b19ee34e88a128671745b0388a91380
> # Parent  449fccab8331e05fb69d967b6916ebac9be614b7
> subrepo: add basic support to hgsubrepo for the files command

These are queued for default, thanks.

Patch

diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -2261,7 +2261,7 @@ 
     forgot.extend(f for f in forget if f not in rejected)
     return bad, forgot
 
-def files(ui, ctx, m, fm, fmt):
+def files(ui, ctx, m, fm, fmt, subrepos):
     rev = ctx.rev()
     ret = 1
     ds = ctx.repo().dirstate
@@ -2277,6 +2277,17 @@ 
         fm.write('path', fmt, m.rel(f))
         ret = 0
 
+    if subrepos:
+        for subpath in sorted(ctx.substate):
+            sub = ctx.sub(subpath)
+            try:
+                submatch = matchmod.narrowmatcher(subpath, m)
+                if sub.printfiles(ui, submatch, fm, fmt) == 0:
+                    ret = 0
+            except error.LookupError:
+                ui.status(_("skipping missing subrepository: %s\n")
+                               % m.abs(subpath))
+
     return ret
 
 def remove(ui, repo, m, prefix, after, force, subrepos):
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -3225,7 +3225,7 @@ 
 @command('files',
     [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
      ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
-    ] + walkopts + formatteropts,
+    ] + walkopts + formatteropts + subrepoopts,
     _('[OPTION]... [PATTERN]...'))
 def files(ui, repo, *pats, **opts):
     """list tracked files
@@ -3280,7 +3280,7 @@ 
     fmt = '%s' + end
 
     m = scmutil.match(ctx, pats, opts)
-    ret = cmdutil.files(ui, ctx, m, fm, fmt)
+    ret = cmdutil.files(ui, ctx, m, fm, fmt, opts.get('subrepos'))
 
     fm.end()
 
diff --git a/mercurial/help/subrepos.txt b/mercurial/help/subrepos.txt
--- a/mercurial/help/subrepos.txt
+++ b/mercurial/help/subrepos.txt
@@ -109,6 +109,10 @@ 
     elements. Git subrepositories do not support --include/--exclude.
     Subversion subrepositories are currently silently ignored.
 
+:files: files does not recurse into subrepos unless -S/--subrepos is
+    specified.  Git and Subversion subrepositories are currently
+    silently ignored.
+
 :forget: forget currently only handles exact file matches in subrepos.
     Git and Subversion subrepositories are currently silently ignored.
 
diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py
--- a/mercurial/subrepo.py
+++ b/mercurial/subrepo.py
@@ -469,6 +469,10 @@ 
         """return file flags"""
         return ''
 
+    def printfiles(self, ui, m, fm, fmt):
+        """handle the files command for this subrepo"""
+        return 1
+
     def archive(self, archiver, prefix, match=None):
         if match is not None:
             files = [f for f in self.files() if match(f)]
@@ -848,6 +852,17 @@ 
         ctx = self._repo[rev]
         return ctx.flags(name)
 
+    @annotatesubrepoerror
+    def printfiles(self, ui, m, fm, fmt):
+        # If the parent context is a workingctx, use the workingctx here for
+        # consistency.
+        if self._ctx.rev() is None:
+            ctx = self._repo[None]
+        else:
+            rev = self._state[1]
+            ctx = self._repo[rev]
+        return cmdutil.files(ui, ctx, m, fm, fmt, True)
+
     def walk(self, match):
         ctx = self._repo[None]
         return ctx.walk(match)
diff --git a/tests/test-completion.t b/tests/test-completion.t
--- a/tests/test-completion.t
+++ b/tests/test-completion.t
@@ -262,7 +262,7 @@ 
   debugsuccessorssets: 
   debugwalk: include, exclude
   debugwireargs: three, four, five, ssh, remotecmd, insecure
-  files: rev, print0, include, exclude, template
+  files: rev, print0, include, exclude, template, subrepos
   graft: rev, continue, edit, log, force, currentdate, currentuser, date, user, tool, dry-run
   grep: print0, all, text, follow, ignore-case, files-with-matches, line-number, rev, user, date, include, exclude
   heads: rev, topo, active, closed, style, template
diff --git a/tests/test-subrepo-deep-nested-change.t b/tests/test-subrepo-deep-nested-change.t
--- a/tests/test-subrepo-deep-nested-change.t
+++ b/tests/test-subrepo-deep-nested-change.t
@@ -186,6 +186,24 @@ 
   adding foo/bar/abc
   committing subrepository sub1
   committing subrepository sub1/sub2 (glob)
+
+  $ hg forget sub1/sub2/sub2
+  $ echo x > sub1/sub2/x.txt
+  $ hg add sub1/sub2/x.txt
+
+Files sees uncommitted adds and removes in subrepos
+  $ hg files -S
+  .hgsub
+  .hgsubstate
+  foo/bar/abc (glob)
+  main
+  sub1/.hgsub (glob)
+  sub1/.hgsubstate (glob)
+  sub1/foo (glob)
+  sub1/sub1 (glob)
+  sub1/sub2/folder/bar (glob)
+  sub1/sub2/x.txt (glob)
+
   $ hg rollback -q
   $ hg up -Cq
 
@@ -393,6 +411,7 @@ 
   R sub1/sub2/test.txt
   ? foo/bar/abc
   ? sub1/sub2/untracked.txt
+  ? sub1/sub2/x.txt
   $ hg add sub1/sub2
   $ hg ci -Sqm 'forget testing'
 
diff --git a/tests/test-subrepo.t b/tests/test-subrepo.t
--- a/tests/test-subrepo.t
+++ b/tests/test-subrepo.t
@@ -25,8 +25,13 @@ 
   abort: can't commit subrepos without .hgsub
   [255]
 
+  $ hg -R s add s/a
+  $ hg files -S
+  .hgsub
+  a
+  s/a (glob)
+
   $ hg -R s ci -Ams0
-  adding a
   $ hg sum
   parent: 0:f7b1eb17ad24 tip
    0