Windows: include= and exclude= containing '/' will also match filenames that are written using '\'
And vice-versa, but it's better to use '/' for portability. Notably, standardPreferredContent contains "archive/*" and that might not match if the filename ends up coming in with the slashes the other way around.
This commit is contained in:
parent
e914cb0777
commit
6b13574827
7 changed files with 49 additions and 17 deletions
|
@ -107,7 +107,7 @@ parseMetaDataMatcher p = (,)
|
|||
('>':v) -> checkcmp (>) v
|
||||
_ -> checkglob ""
|
||||
checkglob v =
|
||||
let cglob = compileGlob v CaseInsensative
|
||||
let cglob = compileGlob v CaseInsensative (GlobFilePath False)
|
||||
in matchGlob cglob . decodeBS . fromMetaValue
|
||||
checkcmp cmp v v' = case (doubleval v, doubleval (decodeBS (fromMetaValue v'))) of
|
||||
(Just d, Just d') -> d' `cmp` d
|
||||
|
|
|
@ -163,11 +163,11 @@ combineViewFilter old@(ExcludeValues olds) (ExcludeValues news)
|
|||
combineViewFilter (FilterValues _) newglob@(FilterGlob _) =
|
||||
(newglob, Widening)
|
||||
combineViewFilter (FilterGlob oldglob) new@(FilterValues s)
|
||||
| all (matchGlob (compileGlob oldglob CaseInsensative) . decodeBS . fromMetaValue) (S.toList s) = (new, Narrowing)
|
||||
| all (matchGlob (compileGlob oldglob CaseInsensative (GlobFilePath False)) . decodeBS . fromMetaValue) (S.toList s) = (new, Narrowing)
|
||||
| otherwise = (new, Widening)
|
||||
combineViewFilter (FilterGlob old) newglob@(FilterGlob new)
|
||||
| old == new = (newglob, Unchanged)
|
||||
| matchGlob (compileGlob old CaseInsensative) new = (newglob, Narrowing)
|
||||
| matchGlob (compileGlob old CaseInsensative (GlobFilePath False)) new = (newglob, Narrowing)
|
||||
| otherwise = (newglob, Widening)
|
||||
combineViewFilter (FilterGlob _) new@(ExcludeValues _) = (new, Narrowing)
|
||||
combineViewFilter (ExcludeValues _) new@(FilterGlob _) = (new, Widening)
|
||||
|
@ -216,7 +216,7 @@ viewComponentMatcher viewcomponent = \metadata ->
|
|||
FilterValues s -> \values -> setmatches $
|
||||
S.intersection s values
|
||||
FilterGlob glob ->
|
||||
let cglob = compileGlob glob CaseInsensative
|
||||
let cglob = compileGlob glob CaseInsensative (GlobFilePath False)
|
||||
in \values -> setmatches $
|
||||
S.filter (matchGlob cglob . decodeBS . fromMetaValue) values
|
||||
ExcludeValues excludes -> \values ->
|
||||
|
|
|
@ -26,6 +26,9 @@ git-annex (8.20201128) UNRELEASED; urgency=medium
|
|||
enclosure, but only a link to an url which youtube-dl does not support.
|
||||
* initremote: Prevent enabling encryption with exporttree=yes or
|
||||
importtree=yes.
|
||||
* Windows: include= and exclude= containing '/' will also match filenames
|
||||
that are written using '\'. (And vice-versa, but it's better to use '/'
|
||||
for portability.)
|
||||
|
||||
-- Joey Hess <id@joeyh.name> Mon, 30 Nov 2020 12:55:49 -0400
|
||||
|
||||
|
|
4
Limit.hs
4
Limit.hs
|
@ -115,7 +115,7 @@ limitExclude glob = Right $ MatchFiles
|
|||
matchGlobFile :: String -> MatchInfo -> Annex Bool
|
||||
matchGlobFile glob = go
|
||||
where
|
||||
cglob = compileGlob glob CaseSensative -- memoized
|
||||
cglob = compileGlob glob CaseSensative (GlobFilePath True) -- memoized
|
||||
go (MatchingFile fi) = pure $ matchGlob cglob (fromRawFilePath (matchFile fi))
|
||||
go (MatchingInfo p) = pure $ matchGlob cglob (fromRawFilePath (providedFilePath p))
|
||||
go (MatchingUserInfo p) = matchGlob cglob <$> getUserInfo (userProvidedFilePath p)
|
||||
|
@ -166,7 +166,7 @@ matchMagic _limitname querymagic selectprovidedinfo selectuserprovidedinfo (Just
|
|||
, matchNeedsLocationLog = False
|
||||
}
|
||||
where
|
||||
cglob = compileGlob glob CaseSensative -- memoized
|
||||
cglob = compileGlob glob CaseSensative (GlobFilePath False) -- memoized
|
||||
go (MatchingKey _ _) = pure False
|
||||
go (MatchingFile fi) = case contentFile fi of
|
||||
Just f -> catchBoolIO $
|
||||
|
|
|
@ -22,7 +22,7 @@ data RefSpecPart
|
|||
| RemoveMatching Glob
|
||||
|
||||
allRefSpec :: RefSpec
|
||||
allRefSpec = [AddMatching $ compileGlob "*" CaseSensative]
|
||||
allRefSpec = [AddMatching $ compileGlob "*" CaseSensative (GlobFilePath False)]
|
||||
|
||||
parseRefSpec :: String -> Either String RefSpec
|
||||
parseRefSpec v = case partitionEithers (map mk $ splitc ':' v) of
|
||||
|
@ -31,9 +31,9 @@ parseRefSpec v = case partitionEithers (map mk $ splitc ':' v) of
|
|||
where
|
||||
mk ('+':s)
|
||||
| any (`elem` s) "*?" =
|
||||
Right $ AddMatching $ compileGlob s CaseSensative
|
||||
Right $ AddMatching $ compileGlob s CaseSensative (GlobFilePath False)
|
||||
| otherwise = Right $ AddRef $ Ref $ encodeBS s
|
||||
mk ('-':s) = Right $ RemoveMatching $ compileGlob s CaseSensative
|
||||
mk ('-':s) = Right $ RemoveMatching $ compileGlob s CaseSensative (GlobFilePath False)
|
||||
mk "reflog" = Right AddRefLog
|
||||
mk s = Left $ "bad refspec item \"" ++ s ++ "\" (expected + or - prefix)"
|
||||
|
||||
|
|
|
@ -1,15 +1,17 @@
|
|||
{-# LANGUAGE PackageImports #-}
|
||||
|
||||
{- file globbing
|
||||
-
|
||||
- Copyright 2014 Joey Hess <id@joeyh.name>
|
||||
- Copyright 2014-2020 Joey Hess <id@joeyh.name>
|
||||
-
|
||||
- License: BSD-2-clause
|
||||
-}
|
||||
|
||||
{-# LANGUAGE CPP #-}
|
||||
{-# LANGUAGE PackageImports #-}
|
||||
|
||||
module Utility.Glob (
|
||||
Glob,
|
||||
GlobCase(..),
|
||||
GlobFilePath(..),
|
||||
compileGlob,
|
||||
matchGlob
|
||||
) where
|
||||
|
@ -24,26 +26,42 @@ newtype Glob = Glob Regex
|
|||
|
||||
data GlobCase = CaseSensative | CaseInsensative
|
||||
|
||||
-- Is the glob being used to match filenames?
|
||||
--
|
||||
-- When matching filenames,
|
||||
-- a single path separator (eg /) in the glob will match any
|
||||
-- number of path separators in the filename.
|
||||
-- And on Windows, both / and \ are used as path separators, so compile
|
||||
-- the glob to a regexp that matches either path separator.
|
||||
newtype GlobFilePath = GlobFilePath Bool
|
||||
|
||||
{- Compiles a glob to a regex, that can be repeatedly used. -}
|
||||
compileGlob :: String -> GlobCase -> Glob
|
||||
compileGlob glob globcase = Glob $
|
||||
compileGlob :: String -> GlobCase -> GlobFilePath -> Glob
|
||||
compileGlob glob globcase globfilepath = Glob $
|
||||
case compile (defaultCompOpt {caseSensitive = casesentitive}) defaultExecOpt regex of
|
||||
Right r -> r
|
||||
Left _ -> giveup $ "failed to compile regex: " ++ regex
|
||||
where
|
||||
regex = '^' : wildToRegex glob ++ "$"
|
||||
regex = '^' : wildToRegex globfilepath glob ++ "$"
|
||||
casesentitive = case globcase of
|
||||
CaseSensative -> True
|
||||
CaseInsensative -> False
|
||||
|
||||
wildToRegex :: String -> String
|
||||
wildToRegex = concat . go
|
||||
wildToRegex :: GlobFilePath -> String -> String
|
||||
wildToRegex (GlobFilePath globfile) = concat . go
|
||||
where
|
||||
go [] = []
|
||||
go ('*':xs) = ".*" : go xs
|
||||
go ('?':xs) = "." : go xs
|
||||
go ('[':'!':xs) = "[^" : inpat xs
|
||||
go ('[':xs) = "[" : inpat xs
|
||||
#ifdef mingw32_HOST_OS
|
||||
go ('/':xs) | globfile = "[/\\]+" : go xs
|
||||
go ('\\':xs) | globfile = "[/\\]+" : go xs
|
||||
#else
|
||||
go ('/':xs) | globfile = "[/]+" : go xs
|
||||
go ('\\':xs) | globfile = "[\\]+" : go xs
|
||||
#endif
|
||||
go (x:xs)
|
||||
| isDigit x || isAlpha x = [x] : go xs
|
||||
| otherwise = esc x : go xs
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
[[!comment format=mdwn
|
||||
username="joey"
|
||||
subject="""comment 3"""
|
||||
date="2020-12-15T16:16:21Z"
|
||||
content="""
|
||||
Hmm, yes preferred content expressions on windows ought
|
||||
to let `/` be used and still match on `\`. (And vice-versa, although then
|
||||
the preferred content expression is windows-specific.)
|
||||
|
||||
I've implemented that now.
|
||||
"""]]
|
Loading…
Reference in a new issue