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:
parent
f9f2576203
commit
8ab27235ea
5 changed files with 101 additions and 26 deletions
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
||||
perform :: FilePath -> FilePath -> Key -> CommandPerform
|
||||
perform src _dest key = ifM move
|
||||
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 -> Key -> CommandPerform
|
||||
perform src key = ifM move
|
||||
( next $ cleanup key
|
||||
, error "failed"
|
||||
)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
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
|
||||
file is expected to have, and refuses to reinject it otherwise.
|
||||
|
||||
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
|
||||
|
|
|
@ -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]]
|
||||
|
|
Loading…
Reference in a new issue