changelog

This commit is contained in:
Joey Hess 2010-10-31 15:09:50 -04:00
parent 40729e4bfd
commit 28b5a9fa20

View file

@ -11,12 +11,9 @@ import System.Console.GetOpt
import Control.Monad.State (liftIO) import Control.Monad.State (liftIO)
import System.Posix.Files import System.Posix.Files
import System.Directory import System.Directory
import System.Path
import Data.String.Utils import Data.String.Utils
import Control.Monad (filterM) import Control.Monad (filterM)
import Monad (when, unless) import Monad (when, unless)
import List
import IO
import qualified GitRepo as Git import qualified GitRepo as Git
import qualified Annex import qualified Annex
@ -50,19 +47,19 @@ type SubCmdCleanup = Annex Bool
{- Runs a subcommand through its three stages. -} {- Runs a subcommand through its three stages. -}
doSubCmd :: String -> SubCmdStart -> String -> Annex Bool doSubCmd :: String -> SubCmdStart -> String -> Annex Bool
doSubCmd cmdname start param = do doSubCmd cmdname start param = do
res <- start param :: Annex (Maybe SubCmdPerform) startres <- start param :: Annex (Maybe SubCmdPerform)
case (res) of case (startres) of
Nothing -> return True Nothing -> return True
Just perform -> do Just perform -> do
showStart cmdname param showStart cmdname param
res <- perform :: Annex (Maybe SubCmdCleanup) performres <- perform :: Annex (Maybe SubCmdCleanup)
case (res) of case (performres) of
Nothing -> do Nothing -> do
showEndFail showEndFail
return False return False
Just cleanup -> do Just cleanup -> do
res <- cleanup cleanupres <- cleanup
if (res) if (cleanupres)
then do then do
showEndOk showEndOk
return True return True
@ -76,7 +73,7 @@ doSubCmd cmdname start param = do
data SubCmdWants = FilesInGit | FilesNotInGit | FilesMissing data SubCmdWants = FilesInGit | FilesNotInGit | FilesMissing
| Description | Keys | Tempfile | FilesToBeCommitted | Description | Keys | Tempfile | FilesToBeCommitted
data SubCommand = Command { data SubCommand = SubCommand {
subcmdname :: String, subcmdname :: String,
subcmdaction :: SubCmdStart, subcmdaction :: SubCmdStart,
subcmdwants :: SubCmdWants, subcmdwants :: SubCmdWants,
@ -84,27 +81,27 @@ data SubCommand = Command {
} }
subCmds :: [SubCommand] subCmds :: [SubCommand]
subCmds = [ subCmds = [
(Command "add" addStart FilesNotInGit (SubCommand "add" addStart FilesNotInGit
"add files to annex") "add files to annex")
, (Command "get" getStart FilesInGit , (SubCommand "get" getStart FilesInGit
"make content of annexed files available") "make content of annexed files available")
, (Command "drop" dropStart FilesInGit , (SubCommand "drop" dropStart FilesInGit
"indicate content of files not currently wanted") "indicate content of files not currently wanted")
, (Command "move" moveStart FilesInGit , (SubCommand "move" moveStart FilesInGit
"transfer content of files to/from another repository") "transfer content of files to/from another repository")
, (Command "init" initStart Description , (SubCommand "init" initStart Description
"initialize git-annex with repository description") "initialize git-annex with repository description")
, (Command "unannex" unannexStart FilesInGit , (SubCommand "unannex" unannexStart FilesInGit
"undo accidential add command") "undo accidential add command")
, (Command "fix" fixStart FilesInGit , (SubCommand "fix" fixStart FilesInGit
"fix up symlinks to point to annexed content") "fix up symlinks to point to annexed content")
, (Command "pre-commit" fixStart FilesToBeCommitted , (SubCommand "pre-commit" fixStart FilesToBeCommitted
"fix up symlinks before they are committed") "fix up symlinks before they are committed")
, (Command "fromkey" fromKeyStart FilesMissing , (SubCommand "fromkey" fromKeyStart FilesMissing
"adds a file using a specific key") "adds a file using a specific key")
, (Command "dropkey" dropKeyStart Keys , (SubCommand "dropkey" dropKeyStart Keys
"drops annexed content for specified keys") "drops annexed content for specified keys")
, (Command "setkey" setKeyStart Tempfile , (SubCommand "setkey" setKeyStart Tempfile
"sets annexed content for a key using a temp file") "sets annexed content for a key using a temp file")
] ]
@ -131,6 +128,7 @@ options = [
storebool n b = Annex.flagChange n $ FlagBool b storebool n b = Annex.flagChange n $ FlagBool b
storestring n s = Annex.flagChange n $ FlagString s storestring n s = Annex.flagChange n $ FlagString s
header :: String
header = "Usage: git-annex " ++ (join "|" $ map subcmdname subCmds) header = "Usage: git-annex " ++ (join "|" $ map subcmdname subCmds)
{- Usage message with lists of options and subcommands. -} {- Usage message with lists of options and subcommands. -}
@ -162,7 +160,7 @@ findWanted FilesNotInGit params repo = do
findWanted FilesInGit params repo = do findWanted FilesInGit params repo = do
files <- mapM (Git.inRepo repo) params files <- mapM (Git.inRepo repo) params
return $ foldl (++) [] files return $ foldl (++) [] files
findWanted FilesMissing params repo = do findWanted FilesMissing params _ = do
files <- liftIO $ filterM missing params files <- liftIO $ filterM missing params
return $ files return $ files
where where
@ -186,15 +184,17 @@ parseCmd argv state = do
when (null params) $ error usage when (null params) $ error usage
case lookupCmd (params !! 0) of case lookupCmd (params !! 0) of
[] -> error usage [] -> error usage
[Command name action want _] -> do [SubCommand { subcmdname = name, subcmdaction = action,
f <- findWanted want (drop 1 params) subcmdwants = want, subcmddesc = _ }] -> do
files <- findWanted want (drop 1 params)
(TypeInternals.repo state) (TypeInternals.repo state)
let actions = map (doSubCmd name action) $ let actions = map (doSubCmd name action) $
filter notstate f filter notstate files
let configactions = map (\f -> do let configactions = map (\flag -> do
f flag
return True) flags return True) flags
return (configactions, actions) return (configactions, actions)
_ -> error "internal error: multiple matching subcommands"
where where
-- never include files from the state directory -- never include files from the state directory
notstate f = stateLoc /= take (length stateLoc) f notstate f = stateLoc /= take (length stateLoc) f
@ -214,11 +214,10 @@ addStart file = notAnnexed file $ do
else return $ Just $ addPerform file else return $ Just $ addPerform file
addPerform :: FilePath -> Annex (Maybe SubCmdCleanup) addPerform :: FilePath -> Annex (Maybe SubCmdCleanup)
addPerform file = do addPerform file = do
g <- Annex.gitRepo
stored <- Backend.storeFileKey file stored <- Backend.storeFileKey file
case (stored) of case (stored) of
Nothing -> return Nothing Nothing -> return Nothing
Just (key, backend) -> return $ Just $ addCleanup file key Just (key, _) -> return $ Just $ addCleanup file key
addCleanup :: FilePath -> Key -> Annex Bool addCleanup :: FilePath -> Key -> Annex Bool
addCleanup file key = do addCleanup file key = do
logStatus key ValuePresent logStatus key ValuePresent
@ -239,8 +238,10 @@ unannexPerform :: FilePath -> Key -> Backend -> Annex (Maybe SubCmdCleanup)
unannexPerform file key backend = do unannexPerform file key backend = do
-- force backend to always remove -- force backend to always remove
Annex.flagChange "force" $ FlagBool True Annex.flagChange "force" $ FlagBool True
Backend.removeKey backend key ok <- Backend.removeKey backend key
return $ Just $ unannexCleanup file key if (ok)
then return $ Just $ unannexCleanup file key
else return Nothing
unannexCleanup :: FilePath -> Key -> Annex Bool unannexCleanup :: FilePath -> Key -> Annex Bool
unannexCleanup file key = do unannexCleanup file key = do
logStatus key ValueMissing logStatus key ValueMissing
@ -259,9 +260,9 @@ getStart file = isAnnexed file $ \(key, backend) -> do
inannex <- inAnnex key inannex <- inAnnex key
if (inannex) if (inannex)
then return Nothing then return Nothing
else return $ Just $ getPerform file key backend else return $ Just $ getPerform key backend
getPerform :: FilePath -> Key -> Backend -> Annex (Maybe SubCmdCleanup) getPerform :: Key -> Backend -> Annex (Maybe SubCmdCleanup)
getPerform file key backend = do getPerform key backend = do
ok <- getViaTmp key (Backend.retrieveKeyFile backend key) ok <- getViaTmp key (Backend.retrieveKeyFile backend key)
if (ok) if (ok)
then return $ Just $ return True -- no cleanup needed then return $ Just $ return True -- no cleanup needed
@ -331,15 +332,15 @@ setKeyPerform tmpfile key = do
ok <- liftIO $ boolSystem "mv" [tmpfile, loc] ok <- liftIO $ boolSystem "mv" [tmpfile, loc]
if (not ok) if (not ok)
then error "mv failed!" then error "mv failed!"
else return $ Just $ setKeyCleanup tmpfile key else return $ Just $ setKeyCleanup key
setKeyCleanup :: FilePath -> Key -> Annex Bool setKeyCleanup :: Key -> Annex Bool
setKeyCleanup tmpfile key = do setKeyCleanup key = do
logStatus key ValuePresent logStatus key ValuePresent
return True return True
{- Fixes the symlink to an annexed file. -} {- Fixes the symlink to an annexed file. -}
fixStart :: FilePath -> Annex (Maybe SubCmdPerform) fixStart :: FilePath -> Annex (Maybe SubCmdPerform)
fixStart file = isAnnexed file $ \(key, backend) -> do fixStart file = isAnnexed file $ \(key, _) -> do
link <- calcGitLink file key link <- calcGitLink file key
l <- liftIO $ readSymbolicLink file l <- liftIO $ readSymbolicLink file
if (link == l) if (link == l)
@ -373,9 +374,9 @@ initPerform description = do
initCleanup :: Annex Bool initCleanup :: Annex Bool
initCleanup = do initCleanup = do
g <- Annex.gitRepo g <- Annex.gitRepo
log <- uuidLog logfile <- uuidLog
liftIO $ Git.run g ["add", log] liftIO $ Git.run g ["add", logfile]
liftIO $ Git.run g ["commit", "-m", "git annex init", log] liftIO $ Git.run g ["commit", "-m", "git annex init", logfile]
return True return True
{- Adds a file pointing at a manually-specified key -} {- Adds a file pointing at a manually-specified key -}
@ -411,9 +412,9 @@ moveStart file = do
toName <- Annex.flagGet "torepository" toName <- Annex.flagGet "torepository"
case (fromName, toName) of case (fromName, toName) of
("", "") -> error "specify either --from or --to" ("", "") -> error "specify either --from or --to"
("", to) -> moveToStart file ("", _) -> moveToStart file
(from, "") -> moveFromStart file (_ , "") -> moveFromStart file
(_, _) -> error "only one of --from or --to can be specified" (_ , _) -> error "only one of --from or --to can be specified"
{- Moves the content of an annexed file to another repository, {- Moves the content of an annexed file to another repository,
- removing it from the current repository, and updates locationlog - removing it from the current repository, and updates locationlog
@ -427,13 +428,13 @@ moveStart file = do
- allow it to be dropped. - allow it to be dropped.
-} -}
moveToStart :: FilePath -> Annex (Maybe SubCmdPerform) moveToStart :: FilePath -> Annex (Maybe SubCmdPerform)
moveToStart file = isAnnexed file $ \(key, backend) -> do moveToStart file = isAnnexed file $ \(key, _) -> do
ishere <- inAnnex key ishere <- inAnnex key
if (not ishere) if (not ishere)
then return Nothing -- not here, so nothing to do then return Nothing -- not here, so nothing to do
else return $ Just $ moveToPerform file key else return $ Just $ moveToPerform key
moveToPerform :: FilePath -> Key -> Annex (Maybe SubCmdCleanup) moveToPerform :: Key -> Annex (Maybe SubCmdCleanup)
moveToPerform file key = do moveToPerform key = do
-- checking the remote is expensive, so not done in the start step -- checking the remote is expensive, so not done in the start step
remote <- Remotes.commandLineRemote remote <- Remotes.commandLineRemote
isthere <- Remotes.inAnnex remote key isthere <- Remotes.inAnnex remote key
@ -452,18 +453,21 @@ moveToPerform file key = do
moveToCleanup :: Git.Repo -> Key -> FilePath -> Annex Bool moveToCleanup :: Git.Repo -> Key -> FilePath -> Annex Bool
moveToCleanup remote key tmpfile = do moveToCleanup remote key tmpfile = do
-- Tell remote to use the transferred content. -- Tell remote to use the transferred content.
Remotes.runCmd remote "git-annex" ["setkey", "--quiet", ok <- Remotes.runCmd remote "git-annex" ["setkey", "--quiet",
"--backend=" ++ (backendName key), "--backend=" ++ (backendName key),
"--key=" ++ keyName key, "--key=" ++ keyName key,
tmpfile] tmpfile]
-- Record that the key is present on the remote. if ok
g <- Annex.gitRepo then do
remoteuuid <- getUUID remote -- Record that the key is present on the remote.
log <- liftIO $ logChange g key remoteuuid ValuePresent g <- Annex.gitRepo
Annex.queue "add" [] log remoteuuid <- getUUID remote
-- Cleanup on the local side is the same as done for the logfile <- liftIO $ logChange g key remoteuuid ValuePresent
-- drop subcommand. Annex.queue "add" [] logfile
dropCleanup key -- Cleanup on the local side is the same as done for the
-- drop subcommand.
dropCleanup key
else return False
{- Moves the content of an annexed file from another repository to the current {- Moves the content of an annexed file from another repository to the current
- repository and updates locationlog information on both. - repository and updates locationlog information on both.
@ -472,15 +476,14 @@ moveToCleanup remote key tmpfile = do
- from the other repository. - from the other repository.
-} -}
moveFromStart :: FilePath -> Annex (Maybe SubCmdPerform) moveFromStart :: FilePath -> Annex (Maybe SubCmdPerform)
moveFromStart file = isAnnexed file $ \(key, backend) -> do moveFromStart file = isAnnexed file $ \(key, _) -> do
g <- Annex.gitRepo
remote <- Remotes.commandLineRemote remote <- Remotes.commandLineRemote
l <- Remotes.keyPossibilities key l <- Remotes.keyPossibilities key
if (elem remote l) if (elem remote l)
then return $ Just $ moveFromPerform file key then return $ Just $ moveFromPerform key
else return Nothing else return Nothing
moveFromPerform :: FilePath -> Key -> Annex (Maybe SubCmdCleanup) moveFromPerform :: Key -> Annex (Maybe SubCmdCleanup)
moveFromPerform file key = do moveFromPerform key = do
remote <- Remotes.commandLineRemote remote <- Remotes.commandLineRemote
ishere <- inAnnex key ishere <- inAnnex key
if (ishere) if (ishere)
@ -493,22 +496,25 @@ moveFromPerform file key = do
else return Nothing -- fail else return Nothing -- fail
moveFromCleanup :: Git.Repo -> Key -> Annex Bool moveFromCleanup :: Git.Repo -> Key -> Annex Bool
moveFromCleanup remote key = do moveFromCleanup remote key = do
Remotes.runCmd remote "git-annex" ["dropkey", "--quiet", "--force", ok <- Remotes.runCmd remote "git-annex" ["dropkey", "--quiet", "--force",
"--backend=" ++ (backendName key), "--backend=" ++ (backendName key),
keyName key] keyName key]
-- Record locally that the key is not on the remote. when ok $ do
remoteuuid <- getUUID remote -- Record locally that the key is not on the remote.
g <- Annex.gitRepo remoteuuid <- getUUID remote
log <- liftIO $ logChange g key remoteuuid ValueMissing g <- Annex.gitRepo
Annex.queue "add" [] log logfile <- liftIO $ logChange g key remoteuuid ValueMissing
return True Annex.queue "add" [] logfile
return ok
-- helpers -- helpers
notAnnexed :: FilePath -> Annex (Maybe a) -> Annex (Maybe a)
notAnnexed file a = do notAnnexed file a = do
r <- Backend.lookupFile file r <- Backend.lookupFile file
case (r) of case (r) of
Just v -> return Nothing Just _ -> return Nothing
Nothing -> a Nothing -> a
isAnnexed :: FilePath -> ((Key, Backend) -> Annex (Maybe a)) -> Annex (Maybe a)
isAnnexed file a = do isAnnexed file a = do
r <- Backend.lookupFile file r <- Backend.lookupFile file
case (r) of case (r) of