blob: c71e57d92ea49d365e1b37804bc0ccae7104237e (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
|
{- This is not the same as git's fetch/push refspecs.
-
- Copyright 2015 Joey Hess <id@joeyh.name>
-
- Licensed under the GNU GPL version 3 or higher.
-}
module Types.RefSpec where
import Common
import Utility.Glob
import Git.Types
import Data.Either
type RefSpec = [RefSpecPart]
data RefSpecPart
= AddRef Ref
| AddMatching Glob
| AddRefLog
| RemoveMatching Glob
allRefSpec :: RefSpec
allRefSpec = [AddMatching $ compileGlob "*" CaseSensative]
parseRefSpec :: String -> Either String RefSpec
parseRefSpec v = case partitionEithers (map mk $ splitc ':' v) of
([],refspec) -> Right refspec
(e:_,_) -> Left e
where
mk ('+':s)
| any (`elem` s) "*?" =
Right $ AddMatching $ compileGlob s CaseSensative
| otherwise = Right $ AddRef $ Ref s
mk ('-':s) = Right $ RemoveMatching $ compileGlob s CaseSensative
mk "reflog" = Right AddRefLog
mk s = Left $ "bad refspec item \"" ++ s ++ "\" (expected + or - prefix)"
applyRefSpec :: Monad m => RefSpec -> [Ref] -> m [Sha] -> m [Ref]
applyRefSpec refspec rs getreflog = go [] refspec
where
go c [] = return (reverse c)
go c (AddRef r : rest) = go (r:c) rest
go c (AddMatching g : rest) =
let add = filter (matchGlob g . fromRef) rs
in go (add ++ c) rest
go c (AddRefLog : rest) = do
reflog <- getreflog
go (reflog ++ c) rest
go c (RemoveMatching g : rest) =
go (filter (not . matchGlob g . fromRef) c) rest
|