[PATCH 16 of 19 STABLE] largefiles: show unknown files matching against 'directory pattern' correctly

FUJIWARA Katsunori foozy at lares.dti.ne.jp
Mon Feb 27 05:52:14 CST 2012


At Mon, 27 Feb 2012 19:46:41 +0900,
FUJIWARA Katsunori wrote:
> 
> # HG changeset patch
> # User FUJIWARA Katsunori <foozy at lares.dti.ne.jp>
> # Date 1330335216 -32400
> # Branch stable
> # Node ID 65d6e452e239d195df6c14f5191ac7d802fdc51f
> # Parent  0e26a7e35a1ec4cfde13987fd15e977336e570ce
> largefiles: show unknown files matching against 'directory pattern' correctly
> 
> current implementation can't show status for unknown files correctly
> in 'working' route, if specified pattern is:
> 
>     - 'directory pattern', and
>     - related to largefiles
> 
> there are some examination ways for listing specified (non-STANDIN)
> 'directory pattern' in 'match.files()':
> 
>     1. always:
> 
>        this causes unexpected warning message ('No such file or
>        directory'), if:
> 
>            a. specified directory doesn't exist, and
>            b. there is no normal file matching against specified
>               pattern in source context
> 
>     2. only if it is related to normal files in current/target context:
> 
>        this works right, only if already tracked normal file happens
>        to exist under specified directory, because dirstate has no
>        entry in 'dirs()' for unknown files
> 
>     3. (2) or specified directory exists:
> 
>        this works right, but increases cost by stat system call
> 
> this patch chooses (3) for correct behavior.
> 
> diff -r 0e26a7e35a1e -r 65d6e452e239 hgext/largefiles/reposetup.py
> --- a/hgext/largefiles/reposetup.py	Mon Feb 27 18:33:36 2012 +0900
> +++ b/hgext/largefiles/reposetup.py	Mon Feb 27 18:33:36 2012 +0900
> @@ -170,7 +170,10 @@
>                              continue
>                          if dinctx(sf):
>                              yield sf # directory pattern for large file
> -                            continue
> +                            # file existence check is needed to
> +                            # show unknown files correctly
> +                            if not (dinctx(f) or os.path.lexists(f)):
> +                                continue
>                          yield f
>                  def matchfn(orgmatchfn, f):
>                      wf = lfutil.splitstandin(f)

After patch posting, I hit upon another idea show below, from relation
between 'changectx.walk()' and 'commands.revert()'.

At first, apply below patch on 'localrepository.status()' to extend
bad file examination.

    ========================================
    @@ -1350,10 +1350,11 @@
                 ctx2.manifest()
     
             if not parentworking:
    +            orgbad = match.bad
                 def bad(f, msg):
                     # 'f' may be a directory pattern from 'match.files()',
                     # so 'f not in ctx1' is not enough
    -                if f not in ctx1 and f not in ctx1.dirs():
    +                if f not in ctx1 and f not in ctx1.dirs() and not orgbad(f, msg):
                         self.ui.warn('%s: %s\n' % (self.dirstate.pathto(f), msg))
                 match.bad = bad
    ========================================
 
Then, all ambiguous 'directory pattern' are stored into 'ambiguous
list' at match object conversion in 'lfiles_repo.status()', as like:

    ========================================
                ambigpat = set() # <<<<
                def filefn(files):
                    if not working:
                        return # 'match.files()' is never used in this case
                    for f in files:
                        if lfutil.isstandin(f) or finctx(f):
                            yield f # STANDIN or exact name of normal file
                            continue
                        sf = lfutil.standin(f)
                        if finctx(sf):
                            yield sf # exact name of large file
                            continue
                        if dinctx(sf):
                            yield sf # directory pattern for large file
                            ambigpat.add(f) # <<<<
                        yield f
    ========================================

Finally, replace 'bad()' of converted match object by function like
below:

    ========================================
                def badfn(f, msg):
                    if f in ambigpat:
                        return True # suppress warning
                m = match.convert(filefn, matchfn)
                m.bad = badfn
    ========================================

Now, we can suppress warning message for ambiguous 'directory
pattern'.

In this way, examination of directory existance can be limited into
usual process of 'dirstate.walk()'.

----------------------------------------------------------------------
[FUJIWARA Katsunori]                             foozy at lares.dti.ne.jp


More information about the Mercurial-devel mailing list