File: RefSpec.hs

package info (click to toggle)
git-annex 10.20250416-2
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 73,572 kB
  • sloc: haskell: 90,656; javascript: 9,103; sh: 1,469; makefile: 211; perl: 137; ansic: 44
file content (52 lines) | stat: -rw-r--r-- 1,469 bytes parent folder | download | duplicates (3)
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 AGPL 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 "*" CaseSensitive (GlobFilePath False)]

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 CaseSensitive (GlobFilePath False)
		| otherwise = Right $ AddRef $ Ref $ encodeBS s
	mk ('-':s) = Right $ RemoveMatching $ compileGlob s CaseSensitive (GlobFilePath False)
	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