bugfixes
This commit is contained in:
		
					parent
					
						
							
								476f66abb9
							
						
					
				
			
			
				commit
				
					
						b7858ada03
					
				
			
		
					 6 changed files with 93 additions and 78 deletions
				
			
		
							
								
								
									
										51
									
								
								Annex.hs
									
										
									
									
									
								
							
							
						
						
									
										51
									
								
								Annex.hs
									
										
									
									
									
								
							|  | @ -24,15 +24,6 @@ import UUID | ||||||
| import LocationLog | import LocationLog | ||||||
| import Types | import Types | ||||||
| 
 | 
 | ||||||
| {- An annexed file's content is stored somewhere under .git/annex/, |  | ||||||
|  - based on the key. Since the symlink is user-visible, the filename |  | ||||||
|  - used should be as close to the key as possible, in case the key is a |  | ||||||
|  - filename or url. Just escape "/" in the key name, to keep a flat |  | ||||||
|  - tree of files and avoid issues with files ending with "/" etc. -} |  | ||||||
| annexLocation :: State -> Key -> FilePath |  | ||||||
| annexLocation state key = gitDir (repo state) ++ "/annex/" ++ (transform key) |  | ||||||
| 	where transform s = replace "/" "%" $ replace "%" "%%" s |  | ||||||
| 
 |  | ||||||
| {- Checks if a given key is currently present in the annexLocation -} | {- Checks if a given key is currently present in the annexLocation -} | ||||||
| inAnnex :: State -> Key -> IO Bool | inAnnex :: State -> Key -> IO Bool | ||||||
| inAnnex state key = doesFileExist $ annexLocation state key | inAnnex state key = doesFileExist $ annexLocation state key | ||||||
|  | @ -62,15 +53,18 @@ annexFile state file = do | ||||||
| 			stored <- storeFile state file | 			stored <- storeFile state file | ||||||
| 			case (stored) of | 			case (stored) of | ||||||
| 				Nothing -> error $ "no backend could store: " ++ file | 				Nothing -> error $ "no backend could store: " ++ file | ||||||
| 				Just key -> symlink key | 				Just (key, backend) -> setup key backend | ||||||
| 	where | 	where | ||||||
| 		symlink key = do | 		setup key backend = do | ||||||
| 			let dest = annexLocation state key | 			let dest = annexLocation state key | ||||||
| 			createDirectoryIfMissing True (parentDir dest) | 			createDirectoryIfMissing True (parentDir dest) | ||||||
| 			renameFile file dest | 			renameFile file dest | ||||||
| 			logChange (repo state) file (getUUID (repo state)) FilePresent |  | ||||||
| 			createSymbolicLink dest file | 			createSymbolicLink dest file | ||||||
| 			gitAdd (repo state) file | 			gitRun (repo state) ["add", file, bfile] | ||||||
|  | 			gitRun (repo state) ["commit", "-m",  | ||||||
|  | 				("git-annex annexed " ++ file), file, bfile] | ||||||
|  | 			logStatus state key ValuePresent | ||||||
|  | 				where bfile = backendFile state backend file | ||||||
| 		checkLegal file = do | 		checkLegal file = do | ||||||
| 			s <- getSymbolicLinkStatus file | 			s <- getSymbolicLinkStatus file | ||||||
| 			if ((isSymbolicLink s) || (not $ isRegularFile s)) | 			if ((isSymbolicLink s) || (not $ isRegularFile s)) | ||||||
|  | @ -87,11 +81,17 @@ unannexFile state file = do | ||||||
| 			mkey <- dropFile state file | 			mkey <- dropFile state file | ||||||
| 			case (mkey) of | 			case (mkey) of | ||||||
| 				Nothing -> return () | 				Nothing -> return () | ||||||
| 				Just key -> do | 				Just (key, backend) -> do | ||||||
| 					let src = annexLocation state key | 					let src = annexLocation state key | ||||||
| 					removeFile file | 					removeFile file | ||||||
|  | 					gitRun (repo state) ["rm", file, bfile] | ||||||
|  | 					gitRun (repo state) ["commit", "-m", | ||||||
|  | 						("git-annex unannexed " ++ file), | ||||||
|  | 						file, bfile] | ||||||
| 					renameFile src file | 					renameFile src file | ||||||
|  | 					logStatus state key ValueMissing | ||||||
| 					return () | 					return () | ||||||
|  | 						where bfile = backendFile state backend file | ||||||
| 
 | 
 | ||||||
| {- Transfers the file from a remote. -} | {- Transfers the file from a remote. -} | ||||||
| annexGetFile :: State -> FilePath -> IO () | annexGetFile :: State -> FilePath -> IO () | ||||||
|  | @ -109,7 +109,9 @@ annexGetFile state file = do | ||||||
| 					createDirectoryIfMissing True (parentDir dest) | 					createDirectoryIfMissing True (parentDir dest) | ||||||
| 					success <- retrieveFile state file dest | 					success <- retrieveFile state file dest | ||||||
| 					if (success) | 					if (success) | ||||||
| 						then return () | 						then do | ||||||
|  | 							logStatus state key ValuePresent | ||||||
|  | 							return () | ||||||
| 						else error $ "failed to get " ++ file | 						else error $ "failed to get " ++ file | ||||||
| 
 | 
 | ||||||
| {- Indicates a file is wanted. -} | {- Indicates a file is wanted. -} | ||||||
|  | @ -132,17 +134,28 @@ annexPullRepo state reponame = do error "not implemented" -- TODO | ||||||
| gitPrep :: GitRepo -> IO () | gitPrep :: GitRepo -> IO () | ||||||
| gitPrep repo = do | gitPrep repo = do | ||||||
| 	-- configure git to use union merge driver on state files | 	-- configure git to use union merge driver on state files | ||||||
| 	let attrLine = stateLoc ++ "/*.log merge=union" |  | ||||||
| 	let attributes = gitAttributes repo |  | ||||||
| 	exists <- doesFileExist attributes | 	exists <- doesFileExist attributes | ||||||
| 	if (not exists) | 	if (not exists) | ||||||
| 		then do | 		then do | ||||||
| 			writeFile attributes $ attrLine ++ "\n" | 			writeFile attributes $ attrLine ++ "\n" | ||||||
| 			gitAdd repo attributes | 			commit | ||||||
| 		else do | 		else do | ||||||
| 			content <- readFile attributes | 			content <- readFile attributes | ||||||
| 			if (all (/= attrLine) (lines content)) | 			if (all (/= attrLine) (lines content)) | ||||||
| 				then do | 				then do | ||||||
| 					appendFile attributes $ attrLine ++ "\n" | 					appendFile attributes $ attrLine ++ "\n" | ||||||
| 					gitAdd repo attributes | 					commit | ||||||
| 				else return () | 				else return () | ||||||
|  | 	where | ||||||
|  | 		attrLine = stateLoc ++ "/*.log merge=union" | ||||||
|  | 		attributes = gitAttributes repo | ||||||
|  | 		commit = do | ||||||
|  | 			gitRun repo ["add", attributes] | ||||||
|  | 			gitRun repo ["commit", "-m", "git-annex setup",  | ||||||
|  | 					attributes] | ||||||
|  | 
 | ||||||
|  | {- Updates the LocationLog when a key's presence changes. -} | ||||||
|  | logStatus state key status = do | ||||||
|  | 	f <- logChange (repo state) key (getUUID (repo state)) status | ||||||
|  | 	gitRun (repo state) ["add", f] | ||||||
|  | 	gitRun (repo state) ["commit", "-m", "git-annex log update", f] | ||||||
|  |  | ||||||
							
								
								
									
										20
									
								
								Backend.hs
									
										
									
									
									
								
							
							
						
						
									
										20
									
								
								Backend.hs
									
										
									
									
									
								
							|  | @ -31,9 +31,8 @@ import GitRepo | ||||||
| import Utility | import Utility | ||||||
| import Types | import Types | ||||||
| 
 | 
 | ||||||
| {- Attempts to store a file in one of the backends, and returns | {- Attempts to store a file in one of the backends. -} | ||||||
|  - its key. -} | storeFile :: State -> FilePath -> IO (Maybe (Key, Backend)) | ||||||
| storeFile :: State -> FilePath -> IO (Maybe Key) |  | ||||||
| storeFile state file = storeFile' (backends state) state file | storeFile state file = storeFile' (backends state) state file | ||||||
| storeFile' [] _ _ = return Nothing | storeFile' [] _ _ = return Nothing | ||||||
| storeFile' (b:bs) state file = do | storeFile' (b:bs) state file = do | ||||||
|  | @ -46,7 +45,7 @@ storeFile' (b:bs) state file = do | ||||||
| 				then nextbackend | 				then nextbackend | ||||||
| 				else do | 				else do | ||||||
| 					recordKey state b file key | 					recordKey state b file key | ||||||
| 					return $ Just key | 					return $ Just (key, b) | ||||||
| 	where | 	where | ||||||
| 		nextbackend = storeFile' bs state file | 		nextbackend = storeFile' bs state file | ||||||
| 
 | 
 | ||||||
|  | @ -62,7 +61,7 @@ retrieveFile state file dest = do | ||||||
| 			(retrieveKeyFile b) state key dest | 			(retrieveKeyFile b) state key dest | ||||||
| 
 | 
 | ||||||
| {- Drops the key for a file from the backend that has it. -} | {- Drops the key for a file from the backend that has it. -} | ||||||
| dropFile :: State -> FilePath -> IO (Maybe Key) | dropFile :: State -> FilePath -> IO (Maybe (Key, Backend)) | ||||||
| dropFile state file = do | dropFile state file = do | ||||||
| 	result <- lookupBackend state file | 	result <- lookupBackend state file | ||||||
| 	case (result) of | 	case (result) of | ||||||
|  | @ -71,7 +70,7 @@ dropFile state file = do | ||||||
| 			key <- lookupKey state b file | 			key <- lookupKey state b file | ||||||
| 			(removeKey b) state key | 			(removeKey b) state key | ||||||
| 			removeFile $ backendFile state b file | 			removeFile $ backendFile state b file | ||||||
| 			return $ Just key | 			return $ Just (key, b) | ||||||
| 
 | 
 | ||||||
| {- Looks up the backend used for an already annexed file. -} | {- Looks up the backend used for an already annexed file. -} | ||||||
| lookupBackend :: State -> FilePath -> IO (Maybe Backend) | lookupBackend :: State -> FilePath -> IO (Maybe Backend) | ||||||
|  | @ -85,13 +84,6 @@ lookupBackend' (b:bs) state file = do | ||||||
| 		else | 		else | ||||||
| 			lookupBackend' bs state file | 			lookupBackend' bs state file | ||||||
| 
 | 
 | ||||||
| {- Name of state file that holds the key for an annexed file, |  | ||||||
|  - using a given backend. -} |  | ||||||
| backendFile :: State -> Backend -> FilePath -> String |  | ||||||
| backendFile state backend file = |  | ||||||
| 	gitStateDir (repo state) ++ (gitRelative (repo state) file) ++  |  | ||||||
| 		"." ++ (name backend) |  | ||||||
| 
 |  | ||||||
| {- Checks if a file is available via a given backend. -} | {- Checks if a file is available via a given backend. -} | ||||||
| checkBackend :: Backend -> State -> FilePath -> IO (Bool) | checkBackend :: Backend -> State -> FilePath -> IO (Bool) | ||||||
| checkBackend backend state file = doesFileExist $ backendFile state backend file | checkBackend backend state file = doesFileExist $ backendFile state backend file | ||||||
|  | @ -106,7 +98,7 @@ lookupKey state backend file = do | ||||||
| 				then (reverse . (drop 1) . reverse) s | 				then (reverse . (drop 1) . reverse) s | ||||||
| 				else s | 				else s | ||||||
| 
 | 
 | ||||||
| {- Records the key a backend uses for an annexed file. -} | {- Records the key used for an annexed file. -} | ||||||
| recordKey :: State -> Backend -> FilePath -> Key -> IO () | recordKey :: State -> Backend -> FilePath -> Key -> IO () | ||||||
| recordKey state backend file key = do | recordKey state backend file key = do | ||||||
| 	createDirectoryIfMissing True (parentDir record) | 	createDirectoryIfMissing True (parentDir record) | ||||||
|  |  | ||||||
							
								
								
									
										10
									
								
								GitRepo.hs
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								GitRepo.hs
									
										
									
									
									
								
							|  | @ -15,8 +15,6 @@ module GitRepo ( | ||||||
| 	gitRelative, | 	gitRelative, | ||||||
| 	gitConfig, | 	gitConfig, | ||||||
| 	gitConfigRead, | 	gitConfigRead, | ||||||
| 	gitAdd, |  | ||||||
| 	gitRm, |  | ||||||
| 	gitRun, | 	gitRun, | ||||||
| 	gitAttributes | 	gitAttributes | ||||||
| ) where | ) where | ||||||
|  | @ -128,14 +126,6 @@ gitRelative repo file = drop (length absrepo) absfile | ||||||
| 			Just f -> f | 			Just f -> f | ||||||
| 			Nothing -> error $ file ++ " is not located inside git repository " ++ absrepo | 			Nothing -> error $ file ++ " is not located inside git repository " ++ absrepo | ||||||
| 
 | 
 | ||||||
| {- Stages a changed/new file in git's index. -} |  | ||||||
| gitAdd :: GitRepo -> FilePath -> IO () |  | ||||||
| gitAdd repo file = gitRun repo ["add", file] |  | ||||||
| 
 |  | ||||||
| {- Removes a file. -} |  | ||||||
| gitRm :: GitRepo -> FilePath -> IO () |  | ||||||
| gitRm repo file = gitRun repo ["rm", file] |  | ||||||
| 
 |  | ||||||
| {- Constructs a git command line operating on the specified repo. -} | {- Constructs a git command line operating on the specified repo. -} | ||||||
| gitCommandLine :: GitRepo -> [String] -> [String] | gitCommandLine :: GitRepo -> [String] -> [String] | ||||||
| gitCommandLine repo params = assertlocal repo $ | gitCommandLine repo params = assertlocal repo $ | ||||||
|  |  | ||||||
|  | @ -1,13 +1,13 @@ | ||||||
| {- git-annex location log | {- git-annex location log | ||||||
|  - |  - | ||||||
|  - git-annex keeps track of on which repository it last saw a file's content. |  - git-annex keeps track of on which repository it last saw a value. | ||||||
|  - This can be useful when using it for archiving with offline storage. |  - This can be useful when using it for archiving with offline storage. | ||||||
|  - When you indicate you --want a file, git-annex will tell you which |  - When you indicate you --want a file, git-annex will tell you which | ||||||
|  - repositories have the file's content. |  - repositories have the value. | ||||||
|  - |  - | ||||||
|  - Location tracking information is stored in `.git-annex/filename.log`. |  - Location tracking information is stored in `.git-annex/key.log`. | ||||||
|  - Repositories record their UUID and the date when they --get or --drop |  - Repositories record their UUID and the date when they --get or --drop | ||||||
|  - a file's content. |  - a value. | ||||||
|  - |  - | ||||||
|  - A line of the log will look like: "date N UUID" |  - A line of the log will look like: "date N UUID" | ||||||
|  - Where N=1 when the repo has the file, and 0 otherwise. |  - Where N=1 when the repo has the file, and 0 otherwise. | ||||||
|  | @ -31,6 +31,7 @@ import Data.Char | ||||||
| import GitRepo | import GitRepo | ||||||
| import Utility | import Utility | ||||||
| import UUID | import UUID | ||||||
|  | import Types | ||||||
| import Locations | import Locations | ||||||
| 
 | 
 | ||||||
| data LogLine = LogLine { | data LogLine = LogLine { | ||||||
|  | @ -39,17 +40,17 @@ data LogLine = LogLine { | ||||||
| 	uuid :: UUID | 	uuid :: UUID | ||||||
| } deriving (Eq) | } deriving (Eq) | ||||||
| 
 | 
 | ||||||
| data LogStatus = FilePresent | FileMissing | Undefined | data LogStatus = ValuePresent | ValueMissing | Undefined | ||||||
| 	deriving (Eq) | 	deriving (Eq) | ||||||
| 
 | 
 | ||||||
| instance Show LogStatus where | instance Show LogStatus where | ||||||
| 	show FilePresent = "1" | 	show ValuePresent = "1" | ||||||
| 	show FileMissing = "0" | 	show ValueMissing = "0" | ||||||
| 	show Undefined = "undefined" | 	show Undefined = "undefined" | ||||||
| 
 | 
 | ||||||
| instance Read LogStatus where | instance Read LogStatus where | ||||||
| 	readsPrec _ "1" = [(FilePresent, "")] | 	readsPrec _ "1" = [(ValuePresent, "")] | ||||||
| 	readsPrec _ "0" = [(FileMissing, "")] | 	readsPrec _ "0" = [(ValueMissing, "")] | ||||||
| 	readsPrec _ _   = [(Undefined, "")] | 	readsPrec _ _   = [(Undefined, "")] | ||||||
| 
 | 
 | ||||||
| instance Show LogLine where | instance Show LogLine where | ||||||
|  | @ -61,7 +62,7 @@ instance Read LogLine where | ||||||
| 	-- read without an exception being thrown. | 	-- read without an exception being thrown. | ||||||
| 	-- Such lines have a status of Undefined. | 	-- Such lines have a status of Undefined. | ||||||
| 	readsPrec _ string =  | 	readsPrec _ string =  | ||||||
| 		if (length w >= 3) | 		if (length w == 3) | ||||||
| 			then case (pdate) of | 			then case (pdate) of | ||||||
| 				Just v -> good v | 				Just v -> good v | ||||||
| 				Nothing -> undefined | 				Nothing -> undefined | ||||||
|  | @ -70,28 +71,23 @@ instance Read LogLine where | ||||||
| 			w = words string | 			w = words string | ||||||
| 			date = w !! 0 | 			date = w !! 0 | ||||||
| 			status = read $ w !! 1 | 			status = read $ w !! 1 | ||||||
| 			uuid = w !! 3 | 			uuid = w !! 2 | ||||||
| 			pdate = (parseTime defaultTimeLocale "%s%Qs" date) :: Maybe UTCTime | 			pdate = (parseTime defaultTimeLocale "%s%Qs" date) :: Maybe UTCTime | ||||||
| 
 | 
 | ||||||
| 			good v = ret $ LogLine (utcTimeToPOSIXSeconds v) status uuid | 			good v = ret $ LogLine (utcTimeToPOSIXSeconds v) status uuid | ||||||
| 			undefined = ret $ LogLine (0) Undefined "" | 			undefined = ret $ LogLine (0) Undefined "" | ||||||
| 			ret v = [(v, "")] | 			ret v = [(v, "")] | ||||||
| 
 | 
 | ||||||
| {- Log a change in the presence of a file in a repository, | {- Log a change in the presence of a key's value in a repository, | ||||||
|  - and add the log to git so it will propigate to other repos. -} |  - and return the log filename. -} | ||||||
| logChange :: GitRepo -> FilePath -> UUID -> LogStatus -> IO () | logChange :: GitRepo -> Key -> UUID -> LogStatus -> IO FilePath | ||||||
| logChange repo file uuid status = do | logChange repo key uuid status = do | ||||||
| 	log <- logNow status uuid | 	log <- logNow status uuid | ||||||
| 	if (status == FilePresent) | 	ls <- readLog logfile | ||||||
| 		-- file added; just append to log | 	writeLog logfile (compactLog $ log:ls) | ||||||
| 		then appendLog logfile log | 	return logfile | ||||||
| 		-- file removed; compact log |  | ||||||
| 		else do |  | ||||||
| 			ls <- readLog logfile |  | ||||||
| 			writeLog logfile (log:ls) |  | ||||||
| 	gitAdd repo logfile |  | ||||||
| 	where | 	where | ||||||
| 		logfile = logFile repo file | 		logfile = logFile repo key | ||||||
| 
 | 
 | ||||||
| {- Reads a log file. | {- Reads a log file. | ||||||
|  - Note that the LogLines returned may be in any order. -} |  - Note that the LogLines returned may be in any order. -} | ||||||
|  | @ -129,22 +125,22 @@ logNow status uuid = do | ||||||
| 	now <- getPOSIXTime | 	now <- getPOSIXTime | ||||||
| 	return $ LogLine now status uuid | 	return $ LogLine now status uuid | ||||||
| 
 | 
 | ||||||
| {- Returns the filename of the log file for a given annexed file. -} | {- Returns the filename of the log file for a given key. -} | ||||||
| logFile :: GitRepo -> FilePath -> String | logFile :: GitRepo -> Key -> String | ||||||
| logFile repo annexedFile = (gitStateDir repo) ++ | logFile repo key =  | ||||||
| 		(gitRelative repo annexedFile) ++ ".log" | 	(gitStateDir repo) ++ (gitRelative repo (keyFile key)) ++ ".log" | ||||||
| 
 | 
 | ||||||
| {- Returns a list of repository UUIDs that, according to the log, have | {- Returns a list of repository UUIDs that, according to the log, have | ||||||
|  - the content of a file -} |  - the value of a key. -} | ||||||
| fileLocations :: GitRepo -> FilePath -> IO [UUID] | keyLocations :: GitRepo -> Key -> IO [UUID] | ||||||
| fileLocations thisrepo file = do | keyLocations thisrepo key = do | ||||||
| 	lines <- readLog $ logFile thisrepo file | 	lines <- readLog $ logFile thisrepo key | ||||||
| 	return $ map uuid (filterPresent lines) | 	return $ map uuid (filterPresent lines) | ||||||
| 
 | 
 | ||||||
| {- Filters the list of LogLines to find ones where the file | {- Filters the list of LogLines to find ones where the value | ||||||
|  - is (or should still be) present. -} |  - is (or should still be) present. -} | ||||||
| filterPresent :: [LogLine] -> [LogLine] | filterPresent :: [LogLine] -> [LogLine] | ||||||
| filterPresent lines = filter (\l -> FilePresent == status l) $ compactLog lines | filterPresent lines = filter (\l -> ValuePresent == status l) $ compactLog lines | ||||||
| 
 | 
 | ||||||
| {- Compacts a set of logs, returning a subset that contains the current | {- Compacts a set of logs, returning a subset that contains the current | ||||||
|  - status. -} |  - status. -} | ||||||
|  |  | ||||||
							
								
								
									
										25
									
								
								Locations.hs
									
										
									
									
									
								
							
							
						
						
									
										25
									
								
								Locations.hs
									
										
									
									
									
								
							|  | @ -3,9 +3,14 @@ | ||||||
| 
 | 
 | ||||||
| module Locations ( | module Locations ( | ||||||
| 	gitStateDir, | 	gitStateDir, | ||||||
| 	stateLoc | 	stateLoc, | ||||||
|  | 	keyFile, | ||||||
|  | 	annexLocation, | ||||||
|  | 	backendFile | ||||||
| ) where | ) where | ||||||
| 
 | 
 | ||||||
|  | import Data.String.Utils | ||||||
|  | import Types | ||||||
| import GitRepo | import GitRepo | ||||||
| 
 | 
 | ||||||
| {- Long-term, cross-repo state is stored in files inside the .git-annex | {- Long-term, cross-repo state is stored in files inside the .git-annex | ||||||
|  | @ -13,3 +18,21 @@ import GitRepo | ||||||
| stateLoc = ".git-annex" | stateLoc = ".git-annex" | ||||||
| gitStateDir :: GitRepo -> FilePath | gitStateDir :: GitRepo -> FilePath | ||||||
| gitStateDir repo = (gitWorkTree repo) ++ "/" ++ stateLoc ++ "/" | gitStateDir repo = (gitWorkTree repo) ++ "/" ++ stateLoc ++ "/" | ||||||
|  | 
 | ||||||
|  | {- Generates a filename that can be used to record a key somewhere to disk. | ||||||
|  |  - Just escape "/" in the key name, to keep a flat | ||||||
|  |  - tree of files and avoid issues with files ending with "/" etc. -} | ||||||
|  | keyFile :: Key -> FilePath | ||||||
|  | keyFile key = replace "/" "%" $ replace "%" "%%" key | ||||||
|  | 
 | ||||||
|  | {- An annexed file's content is stored somewhere under .git/annex/, | ||||||
|  |  - based on the key. -} | ||||||
|  | annexLocation :: State -> Key -> FilePath | ||||||
|  | annexLocation state key = gitDir (repo state) ++ "/annex/" ++ (keyFile key) | ||||||
|  | 
 | ||||||
|  | {- Name of state file that holds the key for an annexed file, | ||||||
|  |  - using a given backend. -} | ||||||
|  | backendFile :: State -> Backend -> FilePath -> String | ||||||
|  | backendFile state backend file = | ||||||
|  | 	gitStateDir (repo state) ++ (gitRelative (repo state) file) ++  | ||||||
|  | 		"." ++ (name backend) | ||||||
|  |  | ||||||
							
								
								
									
										1
									
								
								Types.hs
									
										
									
									
									
								
							
							
						
						
									
										1
									
								
								Types.hs
									
										
									
									
									
								
							|  | @ -6,6 +6,7 @@ module Types ( | ||||||
| 	Backend(..) | 	Backend(..) | ||||||
| ) where | ) where | ||||||
| 
 | 
 | ||||||
|  | import Data.String.Utils | ||||||
| import GitRepo | import GitRepo | ||||||
| 
 | 
 | ||||||
| -- git-annex's runtime state | -- git-annex's runtime state | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Joey Hess
				Joey Hess