2012-05-31 23:47:18 +00:00
|
|
|
{- git-annex command
|
|
|
|
-
|
2013-08-11 18:31:54 +00:00
|
|
|
- Copyright 2012-2013 Joey Hess <joey@kitenet.net>
|
2012-05-31 23:47:18 +00:00
|
|
|
-
|
|
|
|
- Licensed under the GNU GPL version 3 or higher.
|
|
|
|
-}
|
|
|
|
|
|
|
|
module Command.Import where
|
|
|
|
|
2013-05-11 20:03:00 +00:00
|
|
|
import System.PosixCompat.Files
|
|
|
|
|
2012-05-31 23:47:18 +00:00
|
|
|
import Common.Annex
|
|
|
|
import Command
|
|
|
|
import qualified Annex
|
|
|
|
import qualified Command.Add
|
2013-08-11 18:31:54 +00:00
|
|
|
import qualified Option
|
|
|
|
import Utility.CopyFile
|
2013-08-20 15:00:52 +00:00
|
|
|
import Backend
|
|
|
|
import Remote
|
|
|
|
import Types.KeySource
|
2012-05-31 23:47:18 +00:00
|
|
|
|
|
|
|
def :: [Command]
|
2013-08-11 18:31:54 +00:00
|
|
|
def = [withOptions opts $ notBareRepo $ command "import" paramPaths seek
|
2013-03-24 22:28:21 +00:00
|
|
|
SectionCommon "move and add files from outside git working copy"]
|
2012-05-31 23:47:18 +00:00
|
|
|
|
2013-08-11 18:31:54 +00:00
|
|
|
opts :: [Option]
|
|
|
|
opts =
|
|
|
|
[ duplicateOption
|
|
|
|
, deduplicateOption
|
|
|
|
, cleanDuplicatesOption
|
2013-12-04 17:13:30 +00:00
|
|
|
, skipDuplicatesOption
|
2013-08-11 18:31:54 +00:00
|
|
|
]
|
|
|
|
|
|
|
|
duplicateOption :: Option
|
2013-12-04 17:13:30 +00:00
|
|
|
duplicateOption = Option.flag [] "duplicate" "do not delete source files"
|
2013-08-11 18:31:54 +00:00
|
|
|
|
|
|
|
deduplicateOption :: Option
|
2013-12-04 17:13:30 +00:00
|
|
|
deduplicateOption = Option.flag [] "deduplicate" "delete source files whose content was imported before"
|
2013-08-11 18:31:54 +00:00
|
|
|
|
|
|
|
cleanDuplicatesOption :: Option
|
2013-12-04 17:13:30 +00:00
|
|
|
cleanDuplicatesOption = Option.flag [] "clean-duplicates" "delete duplicate source files (import nothing)"
|
2013-08-11 18:31:54 +00:00
|
|
|
|
2013-12-04 17:13:30 +00:00
|
|
|
skipDuplicatesOption :: Option
|
|
|
|
skipDuplicatesOption = Option.flag [] "skip-duplicates" "import only new files"
|
|
|
|
|
|
|
|
data DuplicateMode = Default | Duplicate | DeDuplicate | CleanDuplicates | SkipDuplicates
|
2013-08-11 18:31:54 +00:00
|
|
|
deriving (Eq)
|
|
|
|
|
|
|
|
getDuplicateMode :: Annex DuplicateMode
|
|
|
|
getDuplicateMode = gen
|
|
|
|
<$> getflag duplicateOption
|
|
|
|
<*> getflag deduplicateOption
|
|
|
|
<*> getflag cleanDuplicatesOption
|
2013-12-04 17:13:30 +00:00
|
|
|
<*> getflag skipDuplicatesOption
|
2013-08-11 18:31:54 +00:00
|
|
|
where
|
|
|
|
getflag = Annex.getFlag . Option.name
|
2013-12-04 17:13:30 +00:00
|
|
|
gen False False False False = Default
|
|
|
|
gen True False False False = Duplicate
|
|
|
|
gen False True False False = DeDuplicate
|
|
|
|
gen False False True False = CleanDuplicates
|
|
|
|
gen False False False True = SkipDuplicates
|
|
|
|
gen _ _ _ _ = error "bad combination of --duplicate, --deduplicate, --clean-duplicates, --skip-duplicates"
|
2013-08-11 18:31:54 +00:00
|
|
|
|
2012-05-31 23:47:18 +00:00
|
|
|
seek :: [CommandSeek]
|
2013-08-11 18:31:54 +00:00
|
|
|
seek = [withValue getDuplicateMode $ \mode -> withPathContents $ start mode]
|
2012-05-31 23:47:18 +00:00
|
|
|
|
2013-08-11 18:31:54 +00:00
|
|
|
start :: DuplicateMode -> (FilePath, FilePath) -> CommandStart
|
|
|
|
start mode (srcfile, destfile) =
|
2012-05-31 23:47:18 +00:00
|
|
|
ifM (liftIO $ isRegularFile <$> getSymbolicLinkStatus srcfile)
|
|
|
|
( do
|
2013-12-04 17:13:30 +00:00
|
|
|
isdup <- do
|
|
|
|
backend <- chooseBackend destfile
|
|
|
|
let ks = KeySource srcfile srcfile Nothing
|
|
|
|
v <- genKey ks backend
|
|
|
|
case v of
|
|
|
|
Just (k, _) -> not . null <$> keyLocations k
|
|
|
|
_ -> return False
|
|
|
|
case pickaction isdup of
|
|
|
|
Nothing -> stop
|
|
|
|
Just a -> do
|
|
|
|
showStart "import" destfile
|
|
|
|
next a
|
2012-05-31 23:47:18 +00:00
|
|
|
, stop
|
|
|
|
)
|
2013-08-20 15:00:52 +00:00
|
|
|
where
|
|
|
|
deletedup = do
|
|
|
|
showNote "duplicate"
|
|
|
|
liftIO $ removeFile srcfile
|
|
|
|
next $ return True
|
2013-12-04 17:13:30 +00:00
|
|
|
importfile = do
|
2013-12-09 17:37:18 +00:00
|
|
|
handleexisting =<< liftIO (catchMaybeIO $ getSymbolicLinkStatus destfile)
|
2013-08-20 15:00:52 +00:00
|
|
|
liftIO $ createDirectoryIfMissing True (parentDir destfile)
|
2013-12-04 17:13:30 +00:00
|
|
|
liftIO $ if mode == Duplicate || mode == SkipDuplicates
|
2013-08-20 15:00:52 +00:00
|
|
|
then void $ copyFileExternal srcfile destfile
|
|
|
|
else moveFile srcfile destfile
|
|
|
|
Command.Add.perform destfile
|
2013-12-09 17:37:18 +00:00
|
|
|
handleexisting Nothing = noop
|
|
|
|
handleexisting (Just s)
|
|
|
|
| isDirectory s = notoverwriting "(is a directory)"
|
|
|
|
| otherwise = ifM (Annex.getState Annex.force) $
|
|
|
|
( liftIO $ nukeFile destfile
|
|
|
|
, notoverwriting "(use --force to override)"
|
|
|
|
)
|
|
|
|
notoverwriting why = error $ "not overwriting existing " ++ destfile ++ " " ++ why
|
2013-12-04 17:13:30 +00:00
|
|
|
pickaction isdup = case mode of
|
|
|
|
DeDuplicate
|
|
|
|
| isdup -> Just deletedup
|
|
|
|
| otherwise -> Just importfile
|
|
|
|
CleanDuplicates
|
|
|
|
| isdup -> Just deletedup
|
|
|
|
| otherwise -> Nothing
|
|
|
|
SkipDuplicates
|
|
|
|
| isdup -> Nothing
|
|
|
|
| otherwise -> Just importfile
|
|
|
|
_ -> Just importfile
|
|
|
|
|