fix preferred content check for 1 semitrusted or better copy

Let's make semitrusted+:1 mean that, since it cannot be expressed easily
with the current syntax (could use (semitrusted:1 or trusted:1), but that
does not scale to higher values than 2 copy, and also fails if I add more
trust levels).

Thanks to Andy for spotting this bug by just reading my blog.
This commit is contained in:
Joey Hess 2013-04-02 23:40:13 -04:00
parent b19bb77dd1
commit a73de165f4
4 changed files with 16 additions and 10 deletions

View file

@ -145,8 +145,8 @@ addCopies = addLimit . limitCopies
limitCopies :: MkLimit limitCopies :: MkLimit
limitCopies want = case split ":" want of limitCopies want = case split ":" want of
[v, n] -> case readTrustLevel v of [v, n] -> case parsetrustspec v of
Just trust -> go n $ checktrust trust Just pred -> go n $ checktrust pred
Nothing -> go n $ checkgroup v Nothing -> go n $ checkgroup v
[n] -> go n $ const $ return True [n] -> go n $ const $ return True
_ -> Left "bad value for copies" _ -> Left "bad value for copies"
@ -160,8 +160,11 @@ limitCopies want = case split ":" want of
us <- filter (`S.notMember` notpresent) us <- filter (`S.notMember` notpresent)
<$> (filterM good =<< Remote.keyLocations key) <$> (filterM good =<< Remote.keyLocations key)
return $ length us >= n return $ length us >= n
checktrust t u = (== t) <$> lookupTrust u checktrust pred u = pred <$> lookupTrust u
checkgroup g u = S.member g <$> lookupGroups u checkgroup g u = S.member g <$> lookupGroups u
parsetrustspec s
| "+" `isSuffixOf` s = (>=) <$> readTrustLevel (beginning s)
| otherwise = (==) <$> readTrustLevel s
{- Adds a limit to skip files not believed to be present in all {- Adds a limit to skip files not believed to be present in all
- repositories in the specified group. -} - repositories in the specified group. -}

View file

@ -74,4 +74,4 @@ preferredContent UnwantedGroup = "exclude=*"
{- Most repositories want any content that is only on untrusted {- Most repositories want any content that is only on untrusted
- or dead repositories. -} - or dead repositories. -}
lastResort :: String -> String lastResort :: String -> String
lastResort s = "(" ++ s ++ ") or (not copies=semitrusted:1)" lastResort s = "(" ++ s ++ ") or (not copies=semitrusted+:1)"

View file

@ -688,6 +688,9 @@ file contents are present at either of two repositories.
copies, on remotes with the specified trust level. For example, copies, on remotes with the specified trust level. For example,
"--copies=trusted:2" "--copies=trusted:2"
To match any trust level at or higher than a given level, use
'trustlevel+'. For example, "--copies=semitrusted+:2"
* --copies=groupname:number * --copies=groupname:number
Matches only files that git-annex believes have the specified number of Matches only files that git-annex believes have the specified number of

View file

@ -88,7 +88,7 @@ any repository that can will back it up.)
All content is preferred, unless it's in a "archive" directory. All content is preferred, unless it's in a "archive" directory.
`(exclude=*/archive/* and exclude=archive/*) or (not copies=semitrusted:1)` `(exclude=*/archive/* and exclude=archive/*) or (not copies=semitrusted+:1)`
### transfer ### transfer
@ -100,7 +100,7 @@ USB drive used in a sneakernet.
The preferred content expression for these causes them to get and retain The preferred content expression for these causes them to get and retain
data until all clients have a copy. data until all clients have a copy.
`(not (inallgroup=client and copies=client:2) and exclude=*/archive/* and exclude=archive/*) or (not copies=semitrusted:1)` `(not (inallgroup=client and copies=client:2) and exclude=*/archive/* and exclude=archive/*) or (not copies=semitrusted+:1)`
The "copies=client:2" part of the above handles the case where The "copies=client:2" part of the above handles the case where
there is only one client repository. It makes a transfer repository there is only one client repository. It makes a transfer repository
@ -119,20 +119,20 @@ All content is preferred.
Only prefers content that's not already backed up to another backup Only prefers content that's not already backed up to another backup
or incremental backup repository. or incremental backup repository.
`(include=* and (not copies=backup:1) and (not copies=incrementalbackup:1)) or (not copies=semitrusted:1)` `(include=* and (not copies=backup:1) and (not copies=incrementalbackup:1)) or (not copies=semitrusted+:1)`
### small archive ### small archive
Only prefers content that's located in an "archive" directory, and Only prefers content that's located in an "archive" directory, and
only if it's not already been archived somewhere else. only if it's not already been archived somewhere else.
`((include=*/archive/* or include=archive/*) and not (copies=archive:1 or copies=smallarchive:1)) or (not copies=semitrusted:1)` `((include=*/archive/* or include=archive/*) and not (copies=archive:1 or copies=smallarchive:1)) or (not copies=semitrusted+:1)`
### full archive ### full archive
All content is preferred, unless it's already been archived somewhere else. All content is preferred, unless it's already been archived somewhere else.
`(not (copies=archive:1 or copies=smallarchive:1)) or (not copies=semitrusted:1)` `(not (copies=archive:1 or copies=smallarchive:1)) or (not copies=semitrusted+:1)`
Note that if you want to archive multiple copies (not a bad idea!), Note that if you want to archive multiple copies (not a bad idea!),
you should instead configure all your archive repositories with a you should instead configure all your archive repositories with a
@ -160,7 +160,7 @@ local copy of every file. Instead, you can manually run `git annex get`,
Only content that is present is preferred. Content in "archive" Only content that is present is preferred. Content in "archive"
directories is never preferred. directories is never preferred.
`(present and exclude=*/archive/* and exclude=archive/*) or (not copies=semitrusted:1)` `(present and exclude=*/archive/* and exclude=archive/*) or (not copies=semitrusted+:1)`
### unwanted ### unwanted