summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--GitAnnex.hs6
-rw-r--r--Limit.hs24
-rw-r--r--Logs/PreferredContent.hs25
-rw-r--r--Types/Group.hs6
-rw-r--r--Usage.hs2
-rw-r--r--debian/changelog9
-rw-r--r--doc/design/assistant/transfer_control.mdwn8
-rw-r--r--doc/git-annex.mdwn5
8 files changed, 65 insertions, 20 deletions
diff --git a/GitAnnex.hs b/GitAnnex.hs
index 80a151136..b05fc3607 100644
--- a/GitAnnex.hs
+++ b/GitAnnex.hs
@@ -147,9 +147,11 @@ options = Option.common ++
"skip files with fewer copies"
, Option ['B'] ["inbackend"] (ReqArg Limit.addInBackend paramName)
"skip files not using a key-value backend"
- , Option [] ["largerthan"] (ReqArg Limit.addLargerThan paramName)
+ , Option [] ["ingroup"] (ReqArg Limit.addInGroup paramGroup)
+ "skip files not present in all remotes in a group"
+ , Option [] ["largerthan"] (ReqArg Limit.addLargerThan paramSize)
"skip files larger than a size"
- , Option [] ["smallerthan"] (ReqArg Limit.addSmallerThan paramName)
+ , Option [] ["smallerthan"] (ReqArg Limit.addSmallerThan paramSize)
"skip files smaller than a size"
, Option ['T'] ["time-limit"] (ReqArg Limit.addTimeLimit paramTime)
"stop after the specified amount of time"
diff --git a/Limit.hs b/Limit.hs
index 54a4bae79..f9e8de270 100644
--- a/Limit.hs
+++ b/Limit.hs
@@ -11,6 +11,7 @@ import Text.Regex.PCRE.Light.Char8
import System.Path.WildMatch
import Data.Time.Clock.POSIX
import qualified Data.Set as S
+import qualified Data.Map as M
import Common.Annex
import qualified Annex
@@ -22,6 +23,7 @@ import Annex.UUID
import Logs.Trust
import Types.TrustLevel
import Types.Key
+import Types.Group
import Logs.Group
import Utility.HumanTime
import Utility.DataUnits
@@ -135,6 +137,28 @@ limitCopies want = case split ":" want of
checktrust t u = (== t) <$> lookupTrust u
checkgroup g u = S.member g <$> lookupGroups u
+{- Adds a limit to skip files not believed to be present in all
+ - repositories in the specified group. -}
+addInGroup :: String -> Annex ()
+addInGroup groupname = do
+ m <- groupMap
+ addLimit $ limitInGroup m groupname
+
+limitInGroup :: GroupMap -> MkLimit
+limitInGroup m groupname
+ | S.null want = Right $ const $ const $ return True
+ | otherwise = Right $ \notpresent ->
+ Backend.lookupFile >=> check notpresent
+ where
+ want = fromMaybe S.empty $ M.lookup groupname $ uuidsByGroup m
+ check _ Nothing = return False
+ check notpresent (Just (key, _))
+ -- optimisation: Check if a wanted uuid is notpresent.
+ | not (S.null (S.intersection want notpresent)) = return False
+ | otherwise = do
+ present <- S.fromList <$> Remote.keyLocations key
+ return $ S.null $ want `S.difference` present
+
{- Adds a limit to skip files not using a specified key-value backend. -}
addInBackend :: String -> Annex ()
addInBackend = addLimit . limitInBackend
diff --git a/Logs/PreferredContent.hs b/Logs/PreferredContent.hs
index 3da5cc329..26e0d7073 100644
--- a/Logs/PreferredContent.hs
+++ b/Logs/PreferredContent.hs
@@ -25,6 +25,8 @@ import Limit
import qualified Utility.Matcher
import Annex.UUID
import Git.FilePath
+import Types.Group
+import Logs.Group
{- Filename of preferred-content.log. -}
preferredContentLog :: FilePath
@@ -54,11 +56,12 @@ isPreferredContent mu notpresent file = do
{- Read the preferredContentLog into a map. The map is cached for speed. -}
preferredContentMap :: Annex Annex.PreferredContentMap
preferredContentMap = do
+ groupmap <- groupMap
cached <- Annex.getState Annex.preferredcontentmap
case cached of
Just m -> return m
Nothing -> do
- m <- simpleMap . parseLog (Just . makeMatcher)
+ m <- simpleMap . parseLog (Just . makeMatcher groupmap)
<$> Annex.Branch.get preferredContentLog
Annex.changeState $ \s -> s { Annex.preferredcontentmap = Just m }
return m
@@ -71,21 +74,22 @@ preferredContentMapRaw = simpleMap . parseLog Just
- because the configuration is shared amoung repositories and newer
- versions of git-annex may add new features. Instead, parse errors
- result in a Matcher that will always succeed. -}
-makeMatcher :: String -> Utility.Matcher.Matcher MatchFiles
-makeMatcher s
+makeMatcher :: GroupMap -> String -> Utility.Matcher.Matcher MatchFiles
+makeMatcher groupmap s
| null (lefts tokens) = Utility.Matcher.generate $ rights tokens
| otherwise = Utility.Matcher.generate []
where
- tokens = map parseToken $ tokenizeMatcher s
+ tokens = map (parseToken groupmap) (tokenizeMatcher s)
{- Checks if an expression can be parsed, if not returns Just error -}
checkPreferredContentExpression :: String -> Maybe String
-checkPreferredContentExpression s = case lefts $ map parseToken $ tokenizeMatcher s of
- [] -> Nothing
- l -> Just $ unwords $ map ("Parse failure: " ++) l
+checkPreferredContentExpression s =
+ case lefts $ map (parseToken emptyGroupMap) (tokenizeMatcher s) of
+ [] -> Nothing
+ l -> Just $ unwords $ map ("Parse failure: " ++) l
-parseToken :: String -> Either String (Utility.Matcher.Token MatchFiles)
-parseToken t
+parseToken :: GroupMap -> String -> Either String (Utility.Matcher.Token MatchFiles)
+parseToken groupmap t
| any (== t) Utility.Matcher.tokens = Right $ Utility.Matcher.token t
| otherwise = maybe (Left $ "near " ++ show t) use $ M.lookup k m
where
@@ -95,9 +99,10 @@ parseToken t
, ("exclude", limitExclude)
, ("in", limitIn)
, ("copies", limitCopies)
- , ("backend", limitInBackend)
+ , ("inbackend", limitInBackend)
, ("largerthan", limitSize (>))
, ("smallerthan", limitSize (<))
+ , ("ingroup", limitInGroup groupmap)
]
use a = Utility.Matcher.Operation <$> a v
diff --git a/Types/Group.hs b/Types/Group.hs
index 564e75d0f..88bc35207 100644
--- a/Types/Group.hs
+++ b/Types/Group.hs
@@ -7,7 +7,8 @@
module Types.Group (
Group,
- GroupMap(..)
+ GroupMap(..),
+ emptyGroupMap
) where
import Types.UUID
@@ -21,3 +22,6 @@ data GroupMap = GroupMap
{ groupsByUUID :: M.Map UUID (S.Set Group)
, uuidsByGroup :: M.Map Group (S.Set UUID)
}
+
+emptyGroupMap :: GroupMap
+emptyGroupMap = GroupMap M.empty M.empty
diff --git a/Usage.hs b/Usage.hs
index e411719b0..66fb55690 100644
--- a/Usage.hs
+++ b/Usage.hs
@@ -85,6 +85,8 @@ paramFile :: String
paramFile = "FILE"
paramGroup :: String
paramGroup = "GROUP"
+paramSize :: String
+paramSize = "SIZE"
paramKeyValue :: String
paramKeyValue = "K=V"
paramNothing :: String
diff --git a/debian/changelog b/debian/changelog
index 8a0bf2ac5..ceff1d5f4 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,11 +1,10 @@
git-annex (3.20121002) UNRELEASED; urgency=low
* group, ungroup: New commands to indicate groups of repositories.
- * --copies=group:number can now be used to match files that are present
- in a specified number of repositories in a group.
* watch, assistant: It's now safe to git annex unlock files while
the watcher is running, as well as modify files checked into git
- as normal files.
+ as normal files. Additionally, .gitignore settings are now honored.
+ Closes: #689979
* vicfg: New command, allows editing (or simply viewing) most
of the repository configuration settings stored in the git-annex branch.
* Added preferred content expressions, configurable using vicfg.
@@ -13,7 +12,9 @@ git-annex (3.20121002) UNRELEASED; urgency=low
configured, only get that content.
* drop --auto: If the local repository has preferred content configured,
drop content that is not preferred, when numcopies allows.
- * Added --smallerthan and --largerthan limits.
+ * --copies=group:number can now be used to match files that are present
+ in a specified number of repositories in a group.
+ * Added --smallerthan, --largerthan, and --inall limits.
* Only build-depend on libghc-clientsession-dev on arches that will have
the webapp.
* uninit: Unset annex.version. Closes: #689852
diff --git a/doc/design/assistant/transfer_control.mdwn b/doc/design/assistant/transfer_control.mdwn
index e38b0ca97..1f53a5603 100644
--- a/doc/design/assistant/transfer_control.mdwn
+++ b/doc/design/assistant/transfer_control.mdwn
@@ -27,7 +27,7 @@ check if preferred content settings rejects the data, and if so, drop it
from the repo. So once all three laptops have the data, it is
pruned from the transfer drive.
-## repo groups
+## repo groups **done**
Seems like git-annex needs a way to know the groups of repos. Some
groups:
@@ -53,14 +53,14 @@ Some examples of using groups:
* Make a cloud repo only hold data until all known clients have a copy:
- `not inall(enduser)`
+ `not ingroup(enduser)`
## configuration
The above is all well and good for those who enjoy boolean algebra, but
how to configure these sorts of expressions in the webapp?
-## the state change problem
+## the state change problem **done**
Imagine that a trusted repo has setting like `not copies=trusted:2`
This means that `git annex get --auto` should get files not in 2 trusted
@@ -77,3 +77,5 @@ Or, perhaps simulation could be used to detect the problem. Before
dropping, check the expression. Then simulate that the drop has happened.
Does the expression now make it want to add it? Then don't drop it!
How to implement this simulation?
+
+> Solved, fwiw..
diff --git a/doc/git-annex.mdwn b/doc/git-annex.mdwn
index 390d19eaf..bfdbbf737 100644
--- a/doc/git-annex.mdwn
+++ b/doc/git-annex.mdwn
@@ -643,6 +643,11 @@ file contents are present at either of two repositories.
Matches only files whose content is stored using the specified key-value
backend.
+* --ingroup=groupname
+
+ Matches only files that git-annex believes are present in all repositories
+ in the specified group.
+
* --smallerthan=size
* --largerthan=size