aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Joey Hess <joey@kitenet.net>2010-10-25 18:32:29 -0400
committerGravatar Joey Hess <joey@kitenet.net>2010-10-25 18:32:29 -0400
commitd0a9cdadafca1ee0da100a993b23e8a063f86bf8 (patch)
tree46d6955950bafc004fdc47c3db499e5e2a4849fb
parent8beed17168aab12bb4045b6d8635b37503d5099b (diff)
add dropkey subcommand and --quiet
Needed for better git annex move --from
-rw-r--r--Commands.hs51
-rw-r--r--Core.hs14
-rw-r--r--GitRepo.hs2
-rw-r--r--Remotes.hs54
-rw-r--r--TypeInternals.hs9
-rw-r--r--Types.hs1
-rw-r--r--doc/git-annex.mdwn12
7 files changed, 87 insertions, 56 deletions
diff --git a/Commands.hs b/Commands.hs
index cf0516463..2b8da585e 100644
--- a/Commands.hs
+++ b/Commands.hs
@@ -61,7 +61,8 @@ doSubCmd cmdname start param = do
{- A subcommand can broadly want one of several kinds of input parameters.
- This allows a first stage of filtering before starting a subcommand. -}
-data SubCmdWants = FilesInGit | FilesNotInGit | FilesMissing | Description
+data SubCmdWants = FilesInGit | FilesNotInGit | FilesMissing
+ | Description | Keys
data SubCommand = Command {
subcmdname :: String,
@@ -87,6 +88,8 @@ subCmds = [
"fix up files' symlinks to point to annexed content")
, (Command "fromkey" fromKeyStart FilesMissing
"adds a file using a specific key")
+ , (Command "dropkey" fromKeyStart Keys
+ "drops cached content for specified keys")
]
-- Each dashed command-line option results in generation of an action
@@ -95,6 +98,8 @@ options :: [OptDescr (Annex ())]
options = [
Option ['f'] ["force"] (NoArg (storebool "force" True))
"allow actions that may lose annexed data"
+ , Option ['q'] ["quiet"] (NoArg (storebool "quiet" True))
+ "avoid verbose output"
, Option ['b'] ["backend"] (ReqArg (storestring "backend") "NAME")
"specify default key-value backend to use"
, Option ['k'] ["key"] (ReqArg (storestring "key") "KEY")
@@ -127,6 +132,7 @@ usage = usageInfo header options ++ "\nSubcommands:\n" ++ cmddescs
{- Generate descriptions of wanted parameters for subcommands. -}
descWanted :: SubCmdWants -> String
descWanted Description = "DESCRIPTION"
+descWanted Keys = "KEY ..."
descWanted _ = "PATH ..."
{- Finds the type of parameters a subcommand wants, from among the passed
@@ -147,6 +153,7 @@ findWanted FilesMissing params repo = do
if (e) then return False else return True
findWanted Description params _ = do
return $ [unwords params]
+findWanted Keys params _ = return params
{- Parses command line and returns two lists of actions to be
- run in the Annex monad. The first actions configure it
@@ -243,9 +250,9 @@ dropStart file = isAnnexed file $ \(key, backend) -> do
inbackend <- Backend.hasKey key
if (not inbackend)
then return Nothing
- else return $ Just $ dropPerform file key backend
-dropPerform :: FilePath -> Key -> Backend -> Annex (Maybe SubCmdCleanup)
-dropPerform file key backend = do
+ else return $ Just $ dropPerform key backend
+dropPerform :: Key -> Backend -> Annex (Maybe SubCmdCleanup)
+dropPerform key backend = do
success <- Backend.removeKey backend key
if (success)
then return $ Just $ dropCleanup key
@@ -262,6 +269,29 @@ dropCleanup key = do
return True
else return True
+{- Drops cached content for a key. -}
+dropKeyStart :: String -> Annex (Maybe SubCmdPerform)
+dropKeyStart keyname = do
+ backends <- Backend.list
+ let key = genKey (backends !! 0) keyname
+ present <- inAnnex key
+ force <- Annex.flagIsSet "force"
+ if (not present)
+ then return Nothing
+ else if (not force)
+ then error "dropkey is can cause data loss; use --force if you're sure you want to do this"
+ else return $ Just $ dropKeyPerform key
+dropKeyPerform :: Key -> Annex (Maybe SubCmdCleanup)
+dropKeyPerform key = do
+ g <- Annex.gitRepo
+ let loc = annexLocation g key
+ liftIO $ removeFile loc
+ return $ Just $ dropKeyCleanup key
+dropKeyCleanup :: Key -> Annex Bool
+dropKeyCleanup key = do
+ logStatus key ValueMissing
+ return True
+
{- Fixes the symlink to an annexed file. -}
fixStart :: FilePath -> Annex (Maybe SubCmdPerform)
fixStart file = isAnnexed file $ \(key, backend) -> do
@@ -423,11 +453,14 @@ moveFromPerform file key = do
return $ Just $ moveFromCleanup remote key
moveFromCleanup :: Git.Repo -> Key -> Annex Bool
moveFromCleanup remote key = do
- Remotes.removeRemoteFile remote $ annexLocation remote key
- -- Record that the key is not on the remote.
- u <- getUUID remote
- liftIO $ logChange remote key u ValueMissing
- Remotes.updateRemoteLogStatus remote key
+ -- Force drop content from the remote.
+ Remotes.runCmd remote "git-annex" ["dropkey", "--quiet", "--force",
+ "--backend=" ++ (backendName key),
+ keyName key]
+ -- Record locally that the key is not on the remote.
+ remoteuuid <- getUUID remote
+ g <- Annex.gitRepo
+ liftIO $ logChange g key remoteuuid ValueMissing
return True
-- helpers
diff --git a/Core.hs b/Core.hs
index a97bf5090..8717aee81 100644
--- a/Core.hs
+++ b/Core.hs
@@ -115,22 +115,26 @@ getViaTmp key action = do
return False
{- Output logging -}
+verbose :: Annex () -> Annex ()
+verbose a = do
+ q <- Annex.flagIsSet "quiet"
+ if (q) then return () else a
showStart :: String -> String -> Annex ()
-showStart command file = do
+showStart command file = verbose $ do
liftIO $ putStr $ command ++ " " ++ file ++ " "
liftIO $ hFlush stdout
showNote :: String -> Annex ()
-showNote s = do
+showNote s = verbose $ do
liftIO $ putStr $ "(" ++ s ++ ") "
liftIO $ hFlush stdout
showLongNote :: String -> Annex ()
-showLongNote s = do
+showLongNote s = verbose $ do
liftIO $ putStr $ "\n" ++ (indent s)
where
indent s = join "\n" $ map (\l -> " " ++ l) $ lines s
showEndOk :: Annex ()
-showEndOk = do
+showEndOk = verbose $ do
liftIO $ putStrLn "ok"
showEndFail :: Annex ()
-showEndFail = do
+showEndFail = verbose $ do
liftIO $ putStrLn "\nfailed"
diff --git a/GitRepo.hs b/GitRepo.hs
index 553e91fec..ee1bdba34 100644
--- a/GitRepo.hs
+++ b/GitRepo.hs
@@ -156,7 +156,7 @@ workTree repo =
- name to use to refer to the file relative to a git repository's top.
- This is the same form displayed and used by git. -}
relative :: Repo -> String -> String
-relative repo file = drop (length absrepo) absfile
+relative repo file = assertLocal repo $ drop (length absrepo) absfile
where
-- normalize both repo and file, so that repo
-- will be substring of file
diff --git a/Remotes.hs b/Remotes.hs
index c9c65babe..985199e1c 100644
--- a/Remotes.hs
+++ b/Remotes.hs
@@ -8,11 +8,11 @@ module Remotes (
commandLineRemote,
copyFromRemote,
copyToRemote,
- removeRemoteFile,
- updateRemoteLogStatus
+ runCmd
) where
-import Control.Exception
+import IO (bracket_)
+import Control.Exception hiding (bracket_)
import Control.Monad.State (liftIO)
import Control.Monad (filterM)
import qualified Data.Map as Map
@@ -20,9 +20,9 @@ import Data.String.Utils
import Data.Either.Utils
import System.Cmd.Utils
import System.Directory
+import System.Posix.Directory
import List
import Maybe
-import IO (hPutStrLn)
import Types
import qualified GitRepo as Git
@@ -221,39 +221,19 @@ copyToRemote r key = do
sshlocation = (Git.urlHost r) ++ ":" ++ file
file = error "TODO"
-{- Removes a file from a remote. -}
-removeRemoteFile :: Git.Repo -> FilePath -> Annex ()
-removeRemoteFile r file = do
+{- Runs a command in a remote. -}
+runCmd :: Git.Repo -> String -> [String] -> Annex Bool
+runCmd r command params = do
if (not $ Git.repoIsUrl r)
- then liftIO $ removeFile file
+ then do
+ cwd <- liftIO $ getCurrentDirectory
+ liftIO $ bracket_ (changeWorkingDirectory (Git.workTree r))
+ (\_ -> changeWorkingDirectory cwd) $
+ boolSystem command params
else if (Git.repoIsSsh r)
then do
- ok <- liftIO $ boolSystem "ssh"
- [Git.urlHost r, "rm -f " ++
- (shellEscape file)]
- if (ok)
- then return ()
- else error "failed to remove file from remote"
- else error "removing file from non-ssh repo not supported"
-
-{- Update's a remote's location log for a key, by merging the local
- - location log into it. -}
-updateRemoteLogStatus :: Git.Repo -> Key -> Annex ()
-updateRemoteLogStatus r key = do
- -- To merge, just append data to the remote's
- -- log. Since the log is timestamped, the presumably newer
- -- information from the local will superscede the older
- -- information in the remote's log.
- -- TODO: remote log locking
- let mergecmd = "cat >> " ++ (shellEscape $ logFile r key) ++ " && " ++
- "cd " ++ (shellEscape $ Git.workTree r) ++ " && " ++
- "git add " ++ (shellEscape $ stateLoc)
- let shellcmd = if (not $ Git.repoIsUrl r)
- then pOpen WriteToPipe "sh" ["-c", mergecmd]
- else if (Git.repoIsSsh r)
- then pOpen WriteToPipe "ssh" [Git.urlHost r, mergecmd]
- else error "updating non-ssh repo not supported"
- g <- Annex.gitRepo
- liftIO $ shellcmd $ \h -> do
- lines <- readLog $ logFile g key
- hPutStrLn h $ unlines $ map show lines
+ liftIO $ boolSystem "ssh" [Git.urlHost r,
+ "cd " ++ (shellEscape $ Git.workTree r) ++
+ " && " ++ command ++ " " ++
+ unwords params]
+ else error "running command in non-ssh repo not supported"
diff --git a/TypeInternals.hs b/TypeInternals.hs
index 6d1c72d2e..188f5e534 100644
--- a/TypeInternals.hs
+++ b/TypeInternals.hs
@@ -31,12 +31,12 @@ data AnnexState = AnnexState {
type Annex = StateT AnnexState IO
-- annexed filenames are mapped through a backend into keys
-type KeyFrag = String
+type KeyName = String
type BackendName = String
-data Key = Key (BackendName, KeyFrag) deriving (Eq)
+data Key = Key (BackendName, KeyName) deriving (Eq)
-- constructs a key in a backend
-genKey :: Backend -> KeyFrag -> Key
+genKey :: Backend -> KeyName -> Key
genKey b f = Key (name b,f)
-- show a key to convert it to a string; the string includes the
@@ -51,9 +51,10 @@ instance Read Key where
b = l !! 0
k = join ":" $ drop 1 l
--- pulls the backend name out
backendName :: Key -> BackendName
backendName (Key (b,k)) = b
+keyName :: Key -> KeyName
+keyName (Key (b,k)) = k
-- this structure represents a key-value backend
data Backend = Backend {
diff --git a/Types.hs b/Types.hs
index 50597962c..c3d6467a3 100644
--- a/Types.hs
+++ b/Types.hs
@@ -7,6 +7,7 @@ module Types (
Key,
genKey,
backendName,
+ keyName,
FlagName,
Flag(..)
) where
diff --git a/doc/git-annex.mdwn b/doc/git-annex.mdwn
index 522be7570..e7057afee 100644
--- a/doc/git-annex.mdwn
+++ b/doc/git-annex.mdwn
@@ -116,6 +116,13 @@ Many git-annex subcommands will stage changes for later `git commit` by you.
git annex fromkey --backend=URL --key=http://www.archive.org/somefile somefile
+* dropkey [key ...]
+
+ Drops the cached data for the specified keys from this repository.
+
+ This can be used to drop content for arbitrary keys, which do not need
+ to have a file in the git repository pointing at them.
+
# OPTIONS
* --force
@@ -123,6 +130,11 @@ Many git-annex subcommands will stage changes for later `git commit` by you.
Force unsafe actions, such as dropping a file's content when no other
source of it can be verified to still exist. Use with care.
+* --quiet
+
+ Avoid the default verbose logging of what is done; only show errors
+ and progress displays.
+
* --backend=name
Specify the default key-value backend to use, adding it to the front