summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Joey Hess <joeyh@joeyh.name>2016-04-22 13:49:32 -0400
committerGravatar Joey Hess <joeyh@joeyh.name>2016-04-22 13:49:32 -0400
commitb48a044d26bb607da9962b9086e9da2db9e11620 (patch)
tree0a5b94be74befcbf51431ea4a0d7da31cbdcf357
parent475f9475f162c1c1f9aee727fa3f3a471ebe2506 (diff)
reinject: Added new mode which can reinject known files into the annex.
For example: git-annex reinject --known /mnt/backup/*
-rw-r--r--CmdLine/Usage.hs2
-rw-r--r--Command/Reinject.hs67
-rw-r--r--Logs/Location.hs8
-rw-r--r--doc/git-annex-reinject.mdwn48
-rw-r--r--doc/todo/import_--reinject.mdwn2
5 files changed, 101 insertions, 26 deletions
diff --git a/CmdLine/Usage.hs b/CmdLine/Usage.hs
index f66eb9153..c4522788f 100644
--- a/CmdLine/Usage.hs
+++ b/CmdLine/Usage.hs
@@ -104,3 +104,5 @@ paramOptional :: String -> String
paramOptional s = s
paramPair :: String -> String -> String
paramPair a b = a ++ " " ++ b
+paramOr :: String -> String -> String
+paramOr a b = a ++ " | " ++ b
diff --git a/Command/Reinject.hs b/Command/Reinject.hs
index 0b1b0e2e2..ce18c7cb6 100644
--- a/Command/Reinject.hs
+++ b/Command/Reinject.hs
@@ -1,6 +1,6 @@
{- git-annex command
-
- - Copyright 2011 Joey Hess <id@joeyh.name>
+ - Copyright 2011-2016 Joey Hess <id@joeyh.name>
-
- Licensed under the GNU GPL version 3 or higher.
-}
@@ -10,30 +10,63 @@ module Command.Reinject where
import Command
import Logs.Location
import Annex.Content
+import Backend
+import Types.KeySource
cmd :: Command
cmd = command "reinject" SectionUtility
- "sets content of annexed file"
- (paramPair "SRC" "DEST") (withParams seek)
+ "inject content of file back into annex"
+ (paramRepeating (paramPair "SRC" "DEST")
+ `paramOr` "--known " ++ paramRepeating "SRC")
+ (seek <$$> optParser)
-seek :: CmdParams -> CommandSeek
-seek = withWords start
+data ReinjectOptions = ReinjectOptions
+ { params :: CmdParams
+ , knownOpt :: Bool
+ }
-start :: [FilePath] -> CommandStart
-start (src:dest:[])
+optParser :: CmdParamsDesc -> Parser ReinjectOptions
+optParser desc = ReinjectOptions
+ <$> cmdParams desc
+ <*> switch
+ ( long "known"
+ <> help "inject all known files"
+ <> hidden
+ )
+
+seek :: ReinjectOptions -> CommandSeek
+seek os
+ | knownOpt os = withStrings startKnown (params os)
+ | otherwise = withWords startSrcDest (params os)
+
+startSrcDest :: [FilePath] -> CommandStart
+startSrcDest (src:dest:[])
| src == dest = stop
- | otherwise =
- ifAnnexed src
- (error $ "cannot used annexed file as src: " ++ src)
- go
- where
- go = do
+ | otherwise = notAnnexed src $ do
showStart "reinject" dest
- next $ whenAnnexed (perform src) dest
-start _ = error "specify a src file and a dest file"
+ next $ ifAnnexed dest
+ (perform src)
+ stop
+startSrcDest _ = error "specify a src file and a dest file"
+
+startKnown :: FilePath -> CommandStart
+startKnown src = notAnnexed src $ do
+ showStart "reinject" src
+ mkb <- genKey (KeySource src src Nothing) Nothing
+ case mkb of
+ Nothing -> error "Failed to generate key"
+ Just (key, _) -> ifM (isKnownKey key)
+ ( next $ perform src key
+ , do
+ warning "Not known content; skipping"
+ next $ next $ return True
+ )
+
+notAnnexed :: FilePath -> CommandStart -> CommandStart
+notAnnexed src = ifAnnexed src (error $ "cannot used annexed file as src: " ++ src)
-perform :: FilePath -> FilePath -> Key -> CommandPerform
-perform src _dest key = ifM move
+perform :: FilePath -> Key -> CommandPerform
+perform src key = ifM move
( next $ cleanup key
, error "failed"
)
diff --git a/Logs/Location.hs b/Logs/Location.hs
index 2698d7f95..ba2aed1b5 100644
--- a/Logs/Location.hs
+++ b/Logs/Location.hs
@@ -19,6 +19,7 @@ module Logs.Location (
logChange,
loggedLocations,
loggedLocationsHistorical,
+ isKnownKey,
checkDead,
setDead,
loggedKeys,
@@ -65,6 +66,13 @@ getLoggedLocations getter key = do
config <- Annex.getGitConfig
map toUUID <$> getter (locationLogFile config key)
+{- Is there a location log for the key? True even for keys with no
+ - remaining locations. -}
+isKnownKey :: Key -> Annex Bool
+isKnownKey key = do
+ config <- Annex.getGitConfig
+ not . null <$> readLog (locationLogFile config key)
+
{- For a key to be dead, all locations that have location status for the key
- must have InfoDead set. -}
checkDead :: Key -> Annex Bool
diff --git a/doc/git-annex-reinject.mdwn b/doc/git-annex-reinject.mdwn
index fb175015b..e280a129b 100644
--- a/doc/git-annex-reinject.mdwn
+++ b/doc/git-annex-reinject.mdwn
@@ -1,32 +1,62 @@
# NAME
-git-annex reinject - sets content of annexed file
+git-annex reinject - inject content of file back into annex
# SYNOPSIS
-git annex reinject `src dest`
+git annex reinject `[src dest]`
+
+git annex reinject --known `[src]`
# DESCRIPTION
-Moves the src file into the annex as the content of the dest file,
-which should be an already annexed file whose content is not present.
+Moves the content of the src file or files into the annex.
+Only known file contents will be reinjected. Any unknown src files will
+be left unchanged.
This can be useful if you have obtained the content of a file from
-elsewhere and want to put it in the local annex.
-
-Verifies that the src file's content matches with the content that the dest
-file is expected to have, and refuses to reinject it otherwise.
+elsewhere and want to put it in the local annex. For example, if a file's
+content has been lost and you have a backup, you can restore the backup and
+reinject it into your local repository.
-Example:
+There are two ways to use this command. Specifying a src file and the name
+of a dest file (located inside the repository's working tree)
+injects the src file as the content of the dest file.
git annex reinject /tmp/foo.iso foo.iso
+Or the `--known` option can be used to reinject all known src files, without
+needing to specify the dest file.
+
+ git annex reinject --known /tmp/*.iso
+
+# OPTIONS
+
+* `--known`
+
+ With this option, each specified src file is hashed using the default
+ key-value backend (or the one specified with `--backend`), and if git-annex
+ has a record of the file having been in the annex before, the content is
+ reinjected.
+
+ Note that this will reinject old versions of files that have been
+ modified or deleted from the current git branch.
+ Use [[git-annex-unused]](1) to detect when such old and potentially
+ unused files have been reinjected.
+
+* `--backend`
+
+ Specify the key-value backend to use when checking if a file is known
+ with the `--known` option.
+
# SEE ALSO
[[git-annex]](1)
[[git-annex-add]](1)
+[[git-annex-unused]](1)
+
[[git-annex-fsck]](1)
# AUTHOR
diff --git a/doc/todo/import_--reinject.mdwn b/doc/todo/import_--reinject.mdwn
index b34a2b1f9..b8f80b402 100644
--- a/doc/todo/import_--reinject.mdwn
+++ b/doc/todo/import_--reinject.mdwn
@@ -3,3 +3,5 @@ There's `git annex reinject <src> <dst>` for re-adding one file's contents to th
None of the `git annex import` modes work properly in this case. By default, importing adds another, unnecessary copy of the imported file (which I have to `rm` after importing). The `--clean-duplicates` mode seems close, but it insists on verifying the content in other repositories rather than just reinjecting it locally. (Let's assume that the main reason I'm trying to reinject is that I cannot access other repos.)
So I'm hoping for something like `git annex import --reinject <src>...`. Or are there other existing ways to achieve the same? I couldn't find any.
+
+> implemented `git annex reinject --known` [[done]] --[[Joey]]