Patchwork sparse: --include 'dir1/dir2' should not include 'dir1/*'

login
register
mail settings
Submitter Hollis Blanchard
Date Jan. 18, 2018, 9:39 p.m.
Message ID <0056cfcec61857cee0fa.1516311569@aurora.wv.mentorg.com>
Download mbox | patch
Permalink /patch/26934/
State Accepted
Headers show

Comments

Hollis Blanchard - Jan. 18, 2018, 9:39 p.m.
# HG changeset patch
# User Hollis Blanchard <hollis_blanchard@mentor.com>
# Date 1516311201 28800
#      Thu Jan 18 13:33:21 2018 -0800
# Node ID 0056cfcec61857cee0fa330865bd08ca1e704046
# Parent  659dfbd852e28656fad791dce4f2a22646888ba8
sparse: --include 'dir1/dir2' should not include 'dir1/*'

In 2015 there was a workaround added (f39bace2d6cad32907c0d7961b3c0dbd64a1b7ad)
to sparse in the hg-experimental repo. That workaround:
a) no longer seems to be needed, since its testcase passes even with the code
   removed, and
b) caused a new problem: --include 'dir1/dir2' ended up including dir1/*
   too. (--include 'glob:dir1/dir2' is a user-level workaround.)

Remove the offending code, and add a testcase for situation B.
Augie Fackler - Jan. 19, 2018, 7:42 p.m.
On Thu, Jan 18, 2018 at 01:39:29PM -0800, Hollis Blanchard wrote:
> # HG changeset patch
> # User Hollis Blanchard <hollis_blanchard@mentor.com>
> # Date 1516311201 28800
> #      Thu Jan 18 13:33:21 2018 -0800
> # Node ID 0056cfcec61857cee0fa330865bd08ca1e704046
> # Parent  659dfbd852e28656fad791dce4f2a22646888ba8
> sparse: --include 'dir1/dir2' should not include 'dir1/*'
>
> In 2015 there was a workaround added (f39bace2d6cad32907c0d7961b3c0dbd64a1b7ad)
> to sparse in the hg-experimental repo. That workaround:
> a) no longer seems to be needed, since its testcase passes even with the code
>    removed, and
> b) caused a new problem: --include 'dir1/dir2' ended up including dir1/*
>    too. (--include 'glob:dir1/dir2' is a user-level workaround.)
>
> Remove the offending code, and add a testcase for situation B.

Nice. Queued, with tests modified to use $TESTDIR/list-tree.py instead
of the non-portable tree(1). Thanks!

>
> diff --git a/mercurial/sparse.py b/mercurial/sparse.py
> --- a/mercurial/sparse.py
> +++ b/mercurial/sparse.py
> @@ -294,24 +294,9 @@ def matcher(repo, revs=None, includetemp
>              includes, excludes, profiles = patternsforrev(repo, rev)
>
>              if includes or excludes:
> -                # Explicitly include subdirectories of includes so
> -                # status will walk them down to the actual include.
> -                subdirs = set()
> -                for include in includes:
> -                    # TODO consider using posix path functions here so Windows
> -                    # \ directory separators don't come into play.
> -                    dirname = os.path.dirname(include)
> -                    # basename is used to avoid issues with absolute
> -                    # paths (which on Windows can include the drive).
> -                    while os.path.basename(dirname):
> -                        subdirs.add(dirname)
> -                        dirname = os.path.dirname(dirname)
> -
>                  matcher = matchmod.match(repo.root, '', [],
>                                           include=includes, exclude=excludes,
>                                           default='relpath')
> -                if subdirs:
> -                    matcher = forceincludematcher(matcher, subdirs)
>                  matchers.append(matcher)
>          except IOError:
>              pass
> diff --git a/tests/test-sparse.t b/tests/test-sparse.t
> --- a/tests/test-sparse.t
> +++ b/tests/test-sparse.t
> @@ -284,6 +284,31 @@ Test status on a file in a subdir
>    $ hg status
>    ? dir1/dir2/file
>
> +Mix files and subdirectories, both "glob:" and unprefixed
> +
> +  $ hg debugsparse --reset
> +  $ touch dir1/notshown
> +  $ hg commit -A dir1/notshown -m "notshown"
> +  $ hg debugsparse --include 'dir1/dir2'
> +  $ tree
> +  .
> +  |-- dir1
> +  |   `-- dir2
> +  |       `-- file
> +  `-- hide.orig
> +
> +  2 directories, 2 files
> +  $ hg debugsparse --delete 'dir1/dir2'
> +  $ hg debugsparse --include 'glob:dir1/dir2'
> +  $ tree
> +  .
> +  |-- dir1
> +  |   `-- dir2
> +  |       `-- file
> +  `-- hide.orig
> +
> +  2 directories, 2 files
> +
>  Test that add -s adds dirs to sparse profile
>
>    $ hg debugsparse --reset
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel@mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel

Patch

diff --git a/mercurial/sparse.py b/mercurial/sparse.py
--- a/mercurial/sparse.py
+++ b/mercurial/sparse.py
@@ -294,24 +294,9 @@  def matcher(repo, revs=None, includetemp
             includes, excludes, profiles = patternsforrev(repo, rev)
 
             if includes or excludes:
-                # Explicitly include subdirectories of includes so
-                # status will walk them down to the actual include.
-                subdirs = set()
-                for include in includes:
-                    # TODO consider using posix path functions here so Windows
-                    # \ directory separators don't come into play.
-                    dirname = os.path.dirname(include)
-                    # basename is used to avoid issues with absolute
-                    # paths (which on Windows can include the drive).
-                    while os.path.basename(dirname):
-                        subdirs.add(dirname)
-                        dirname = os.path.dirname(dirname)
-
                 matcher = matchmod.match(repo.root, '', [],
                                          include=includes, exclude=excludes,
                                          default='relpath')
-                if subdirs:
-                    matcher = forceincludematcher(matcher, subdirs)
                 matchers.append(matcher)
         except IOError:
             pass
diff --git a/tests/test-sparse.t b/tests/test-sparse.t
--- a/tests/test-sparse.t
+++ b/tests/test-sparse.t
@@ -284,6 +284,31 @@  Test status on a file in a subdir
   $ hg status
   ? dir1/dir2/file
 
+Mix files and subdirectories, both "glob:" and unprefixed
+
+  $ hg debugsparse --reset
+  $ touch dir1/notshown
+  $ hg commit -A dir1/notshown -m "notshown"
+  $ hg debugsparse --include 'dir1/dir2'
+  $ tree
+  .
+  |-- dir1
+  |   `-- dir2
+  |       `-- file
+  `-- hide.orig
+  
+  2 directories, 2 files
+  $ hg debugsparse --delete 'dir1/dir2'
+  $ hg debugsparse --include 'glob:dir1/dir2'
+  $ tree
+  .
+  |-- dir1
+  |   `-- dir2
+  |       `-- file
+  `-- hide.orig
+  
+  2 directories, 2 files
+
 Test that add -s adds dirs to sparse profile
 
   $ hg debugsparse --reset