reinject: Added new mode which can reinject known files into the annex.

For example: git-annex reinject --known /mnt/backup/*
This commit is contained in:
Joey Hess 2016-04-22 13:49:32 -04:00
parent f9f2576203
commit 8ab27235ea
Failed to extract signature
5 changed files with 101 additions and 26 deletions

View file

@ -104,3 +104,5 @@ paramOptional :: String -> String
paramOptional s = s paramOptional s = s
paramPair :: String -> String -> String paramPair :: String -> String -> String
paramPair a b = a ++ " " ++ b paramPair a b = a ++ " " ++ b
paramOr :: String -> String -> String
paramOr a b = a ++ " | " ++ b

View file

@ -1,6 +1,6 @@
{- git-annex command {- 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. - Licensed under the GNU GPL version 3 or higher.
-} -}
@ -10,30 +10,63 @@ module Command.Reinject where
import Command import Command
import Logs.Location import Logs.Location
import Annex.Content import Annex.Content
import Backend
import Types.KeySource
cmd :: Command cmd :: Command
cmd = command "reinject" SectionUtility cmd = command "reinject" SectionUtility
"sets content of annexed file" "inject content of file back into annex"
(paramPair "SRC" "DEST") (withParams seek) (paramRepeating (paramPair "SRC" "DEST")
`paramOr` "--known " ++ paramRepeating "SRC")
(seek <$$> optParser)
seek :: CmdParams -> CommandSeek data ReinjectOptions = ReinjectOptions
seek = withWords start { params :: CmdParams
, knownOpt :: Bool
}
start :: [FilePath] -> CommandStart optParser :: CmdParamsDesc -> Parser ReinjectOptions
start (src:dest:[]) 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 | src == dest = stop
| otherwise = | otherwise = notAnnexed src $ do
ifAnnexed src
(error $ "cannot used annexed file as src: " ++ src)
go
where
go = do
showStart "reinject" dest showStart "reinject" dest
next $ whenAnnexed (perform src) dest next $ ifAnnexed dest
start _ = error "specify a src file and a dest file" (perform src)
stop
startSrcDest _ = error "specify a src file and a dest file"
perform :: FilePath -> FilePath -> Key -> CommandPerform startKnown :: FilePath -> CommandStart
perform src _dest key = ifM move 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 -> Key -> CommandPerform
perform src key = ifM move
( next $ cleanup key ( next $ cleanup key
, error "failed" , error "failed"
) )

View file

@ -19,6 +19,7 @@ module Logs.Location (
logChange, logChange,
loggedLocations, loggedLocations,
loggedLocationsHistorical, loggedLocationsHistorical,
isKnownKey,
checkDead, checkDead,
setDead, setDead,
loggedKeys, loggedKeys,
@ -65,6 +66,13 @@ getLoggedLocations getter key = do
config <- Annex.getGitConfig config <- Annex.getGitConfig
map toUUID <$> getter (locationLogFile config key) 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 {- For a key to be dead, all locations that have location status for the key
- must have InfoDead set. -} - must have InfoDead set. -}
checkDead :: Key -> Annex Bool checkDead :: Key -> Annex Bool

View file

@ -1,32 +1,62 @@
# NAME # NAME
git-annex reinject - sets content of annexed file git-annex reinject - inject content of file back into annex
# SYNOPSIS # SYNOPSIS
git annex reinject `src dest` git annex reinject `[src dest]`
git annex reinject --known `[src]`
# DESCRIPTION # DESCRIPTION
Moves the src file into the annex as the content of the dest file, Moves the content of the src file or files into the annex.
which should be an already annexed file whose content is not present. 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 This can be useful if you have obtained the content of a file from
elsewhere and want to put it in the local annex. 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.
Verifies that the src file's content matches with the content that the dest There are two ways to use this command. Specifying a src file and the name
file is expected to have, and refuses to reinject it otherwise. of a dest file (located inside the repository's working tree)
injects the src file as the content of the dest file.
Example:
git annex reinject /tmp/foo.iso foo.iso 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 # SEE ALSO
[[git-annex]](1) [[git-annex]](1)
[[git-annex-add]](1) [[git-annex-add]](1)
[[git-annex-unused]](1)
[[git-annex-fsck]](1) [[git-annex-fsck]](1)
# AUTHOR # AUTHOR

View file

@ -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.) 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. 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]]