annex.addunlocked
* add, addurl, import, importfeed: When in a v6 repository on a crippled filesystem, add files unlocked. * annex.addunlocked: New configuration setting, makes files always be added unlocked. (v6 only)
This commit is contained in:
parent
adc27f081a
commit
15148ee9eb
8 changed files with 116 additions and 39 deletions
|
@ -1,6 +1,6 @@
|
||||||
{- git-annex content ingestion
|
{- git-annex content ingestion
|
||||||
-
|
-
|
||||||
- Copyright 2010-2015 Joey Hess <id@joeyh.name>
|
- Copyright 2010-2016 Joey Hess <id@joeyh.name>
|
||||||
-
|
-
|
||||||
- Licensed under the GNU GPL version 3 or higher.
|
- Licensed under the GNU GPL version 3 or higher.
|
||||||
-}
|
-}
|
||||||
|
@ -11,14 +11,17 @@ module Annex.Ingest (
|
||||||
LockedDown(..),
|
LockedDown(..),
|
||||||
LockDownConfig(..),
|
LockDownConfig(..),
|
||||||
lockDown,
|
lockDown,
|
||||||
|
ingestAdd,
|
||||||
ingest,
|
ingest,
|
||||||
finishIngestDirect,
|
finishIngestDirect,
|
||||||
finishIngestUnlocked,
|
finishIngestUnlocked,
|
||||||
cleanOldKeys,
|
cleanOldKeys,
|
||||||
addLink,
|
addLink,
|
||||||
makeLink,
|
makeLink,
|
||||||
|
addUnlocked,
|
||||||
restoreFile,
|
restoreFile,
|
||||||
forceParams,
|
forceParams,
|
||||||
|
addAnnexedFile,
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Annex.Common
|
import Annex.Common
|
||||||
|
@ -29,6 +32,7 @@ import Annex.Content.Direct
|
||||||
import Annex.Perms
|
import Annex.Perms
|
||||||
import Annex.Link
|
import Annex.Link
|
||||||
import Annex.MetaData
|
import Annex.MetaData
|
||||||
|
import Annex.Version
|
||||||
import Logs.Location
|
import Logs.Location
|
||||||
import qualified Annex
|
import qualified Annex
|
||||||
import qualified Annex.Queue
|
import qualified Annex.Queue
|
||||||
|
@ -111,11 +115,30 @@ lockDown' cfg file = ifM (pure (not (hardlinkFileTmp cfg)) <||> crippledFileSyst
|
||||||
, inodeCache = cache
|
, inodeCache = cache
|
||||||
}
|
}
|
||||||
|
|
||||||
{- Ingests a locked down file into the annex.
|
{- Ingests a locked down file into the annex. Updates the work tree and
|
||||||
-
|
- index. -}
|
||||||
- The file may be added to the git repository as a locked or an unlocked
|
ingestAdd :: Maybe LockedDown -> Annex (Maybe Key)
|
||||||
- file. When unlocked, the work tree file is left alone. When locked,
|
ingestAdd Nothing = return Nothing
|
||||||
- the work tree file is deleted, in preparation for adding the symlink.
|
ingestAdd ld@(Just (LockedDown cfg source)) = do
|
||||||
|
(mk, mic) <- ingest ld
|
||||||
|
case mk of
|
||||||
|
Nothing -> return Nothing
|
||||||
|
Just k -> do
|
||||||
|
let f = keyFilename source
|
||||||
|
if lockingFile cfg
|
||||||
|
then do
|
||||||
|
liftIO $ nukeFile f
|
||||||
|
addLink f k mic
|
||||||
|
else ifM isDirect
|
||||||
|
( do
|
||||||
|
l <- calcRepo $ gitAnnexLink f k
|
||||||
|
stageSymlink f =<< hashSymlink l
|
||||||
|
, stagePointerFile f =<< hashPointerFile k
|
||||||
|
)
|
||||||
|
return (Just k)
|
||||||
|
|
||||||
|
{- Ingests a locked down file into the annex. Does not update the working
|
||||||
|
- tree or the index.
|
||||||
-}
|
-}
|
||||||
ingest :: Maybe LockedDown -> Annex (Maybe Key, Maybe InodeCache)
|
ingest :: Maybe LockedDown -> Annex (Maybe Key, Maybe InodeCache)
|
||||||
ingest Nothing = return (Nothing, Nothing)
|
ingest Nothing = return (Nothing, Nothing)
|
||||||
|
@ -141,7 +164,6 @@ ingest (Just (LockedDown cfg source)) = withTSDelta $ \delta -> do
|
||||||
golocked key mcache s = do
|
golocked key mcache s = do
|
||||||
catchNonAsync (moveAnnex key $ contentLocation source)
|
catchNonAsync (moveAnnex key $ contentLocation source)
|
||||||
(restoreFile (keyFilename source) key)
|
(restoreFile (keyFilename source) key)
|
||||||
liftIO $ nukeFile $ keyFilename source
|
|
||||||
populateAssociatedFiles key source
|
populateAssociatedFiles key source
|
||||||
success key mcache s
|
success key mcache s
|
||||||
|
|
||||||
|
@ -295,3 +317,50 @@ forceParams = ifM (Annex.getState Annex.force)
|
||||||
( return [Param "-f"]
|
( return [Param "-f"]
|
||||||
, return []
|
, return []
|
||||||
)
|
)
|
||||||
|
|
||||||
|
{- Whether a file should be added unlocked or not. Default is to not,
|
||||||
|
- unless symlinks are not supported. annex.addunlocked can override that. -}
|
||||||
|
addUnlocked :: Annex Bool
|
||||||
|
addUnlocked = isDirect <||>
|
||||||
|
(versionSupportsUnlockedPointers <&&>
|
||||||
|
((not . coreSymlinks <$> Annex.getGitConfig) <||>
|
||||||
|
(annexAddUnlocked <$> Annex.getGitConfig)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
{- Adds a file to the work tree for the key, and stages it in the index.
|
||||||
|
- The content of the key may be provided in a temp file, which will be
|
||||||
|
- moved into place. -}
|
||||||
|
addAnnexedFile :: FilePath -> Key -> Maybe FilePath -> Annex ()
|
||||||
|
addAnnexedFile file key mtmp = ifM (addUnlocked <&&> not <$> isDirect)
|
||||||
|
( do
|
||||||
|
stagePointerFile file =<< hashPointerFile key
|
||||||
|
Database.Keys.addAssociatedFile key =<< inRepo (toTopFilePath file)
|
||||||
|
case mtmp of
|
||||||
|
Just tmp -> do
|
||||||
|
moveAnnex key tmp
|
||||||
|
linkunlocked
|
||||||
|
Nothing -> ifM (inAnnex key)
|
||||||
|
( linkunlocked
|
||||||
|
, writepointer
|
||||||
|
)
|
||||||
|
, do
|
||||||
|
addLink file key Nothing
|
||||||
|
whenM isDirect $ do
|
||||||
|
void $ addAssociatedFile key file
|
||||||
|
case mtmp of
|
||||||
|
Just tmp -> do
|
||||||
|
{- For moveAnnex to work in direct mode, the
|
||||||
|
- symlink must already exist, so flush the queue. -}
|
||||||
|
whenM isDirect $
|
||||||
|
Annex.Queue.flush
|
||||||
|
moveAnnex key tmp
|
||||||
|
Nothing -> return ()
|
||||||
|
)
|
||||||
|
where
|
||||||
|
writepointer = liftIO $ writeFile file (formatPointer key)
|
||||||
|
linkunlocked = do
|
||||||
|
r <- linkFromAnnex key file
|
||||||
|
case r of
|
||||||
|
LinkAnnexFailed -> writepointer
|
||||||
|
_ -> return ()
|
||||||
|
|
|
@ -12,12 +12,10 @@ import Annex.Ingest
|
||||||
import Logs.Location
|
import Logs.Location
|
||||||
import Annex.Content
|
import Annex.Content
|
||||||
import Annex.Content.Direct
|
import Annex.Content.Direct
|
||||||
import Annex.Link
|
|
||||||
import qualified Annex
|
import qualified Annex
|
||||||
import qualified Annex.Queue
|
import qualified Annex.Queue
|
||||||
import qualified Database.Keys
|
import qualified Database.Keys
|
||||||
import Config
|
import Config
|
||||||
import Utility.InodeCache
|
|
||||||
import Annex.FileMatcher
|
import Annex.FileMatcher
|
||||||
import Annex.Version
|
import Annex.Version
|
||||||
|
|
||||||
|
@ -99,48 +97,42 @@ start file = ifAnnexed file addpresent add
|
||||||
( do
|
( do
|
||||||
ms <- liftIO $ catchMaybeIO $ getSymbolicLinkStatus file
|
ms <- liftIO $ catchMaybeIO $ getSymbolicLinkStatus file
|
||||||
case ms of
|
case ms of
|
||||||
Just s | isSymbolicLink s -> fixup key
|
Just s | isSymbolicLink s -> fixuplink key
|
||||||
_ -> ifM (sameInodeCache file =<< Database.Keys.getInodeCaches key)
|
_ -> ifM (sameInodeCache file =<< Database.Keys.getInodeCaches key)
|
||||||
( stop, add )
|
( stop, add )
|
||||||
, ifM isDirect
|
, ifM isDirect
|
||||||
( do
|
( do
|
||||||
ms <- liftIO $ catchMaybeIO $ getSymbolicLinkStatus file
|
ms <- liftIO $ catchMaybeIO $ getSymbolicLinkStatus file
|
||||||
case ms of
|
case ms of
|
||||||
Just s | isSymbolicLink s -> fixup key
|
Just s | isSymbolicLink s -> fixuplink key
|
||||||
_ -> ifM (goodContent key file)
|
_ -> ifM (goodContent key file)
|
||||||
( stop , add )
|
( stop , add )
|
||||||
, fixup key
|
, fixuplink key
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
fixup key = do
|
fixuplink key = do
|
||||||
-- the annexed symlink is present but not yet added to git
|
-- the annexed symlink is present but not yet added to git
|
||||||
showStart "add" file
|
showStart "add" file
|
||||||
liftIO $ removeFile file
|
liftIO $ removeFile file
|
||||||
whenM isDirect $
|
next $ next $ do
|
||||||
void $ addAssociatedFile key file
|
addLink file key Nothing
|
||||||
next $ next $ cleanup file key Nothing =<< inAnnex key
|
cleanup key =<< inAnnex key
|
||||||
|
|
||||||
perform :: FilePath -> CommandPerform
|
perform :: FilePath -> CommandPerform
|
||||||
perform file = do
|
perform file = do
|
||||||
lockingfile <- not <$> isDirect
|
lockingfile <- not <$> addUnlocked
|
||||||
let cfg = LockDownConfig
|
let cfg = LockDownConfig
|
||||||
{ lockingFile = lockingfile
|
{ lockingFile = lockingfile
|
||||||
, hardlinkFileTmp = True
|
, hardlinkFileTmp = True
|
||||||
}
|
}
|
||||||
lockDown cfg file >>= ingest >>= go
|
lockDown cfg file >>= ingestAdd >>= finish
|
||||||
where
|
where
|
||||||
go (Just key, cache) = next $ cleanup file key cache True
|
finish (Just key) = next $ cleanup key True
|
||||||
go (Nothing, _) = stop
|
finish Nothing = stop
|
||||||
|
|
||||||
cleanup :: FilePath -> Key -> Maybe InodeCache -> Bool -> CommandCleanup
|
cleanup :: Key -> Bool -> CommandCleanup
|
||||||
cleanup file key mcache hascontent = do
|
cleanup key hascontent = do
|
||||||
maybeShowJSON [("key", key2file key)]
|
maybeShowJSON [("key", key2file key)]
|
||||||
ifM (isDirect <&&> pure hascontent)
|
|
||||||
( do
|
|
||||||
l <- calcRepo $ gitAnnexLink file key
|
|
||||||
stageSymlink file =<< hashSymlink l
|
|
||||||
, addLink file key mcache
|
|
||||||
)
|
|
||||||
when hascontent $
|
when hascontent $
|
||||||
logStatus key InfoPresent
|
logStatus key InfoPresent
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -12,7 +12,6 @@ import Network.URI
|
||||||
import Command
|
import Command
|
||||||
import Backend
|
import Backend
|
||||||
import qualified Annex
|
import qualified Annex
|
||||||
import qualified Annex.Queue
|
|
||||||
import qualified Annex.Url as Url
|
import qualified Annex.Url as Url
|
||||||
import qualified Backend.URL
|
import qualified Backend.URL
|
||||||
import qualified Remote
|
import qualified Remote
|
||||||
|
@ -24,8 +23,6 @@ import Annex.UUID
|
||||||
import Logs.Web
|
import Logs.Web
|
||||||
import Types.KeySource
|
import Types.KeySource
|
||||||
import Types.UrlContents
|
import Types.UrlContents
|
||||||
import Config
|
|
||||||
import Annex.Content.Direct
|
|
||||||
import Annex.FileMatcher
|
import Annex.FileMatcher
|
||||||
import Logs.Location
|
import Logs.Location
|
||||||
import Utility.Metered
|
import Utility.Metered
|
||||||
|
@ -363,13 +360,7 @@ cleanup u url file key mtmp = case mtmp of
|
||||||
when (isJust mtmp) $
|
when (isJust mtmp) $
|
||||||
logStatus key InfoPresent
|
logStatus key InfoPresent
|
||||||
setUrlPresent u key url
|
setUrlPresent u key url
|
||||||
addLink file key Nothing
|
addAnnexedFile file key mtmp
|
||||||
whenM isDirect $ do
|
|
||||||
void $ addAssociatedFile key file
|
|
||||||
{- For moveAnnex to work in direct mode, the symlink
|
|
||||||
- must already exist, so flush the queue. -}
|
|
||||||
Annex.Queue.flush
|
|
||||||
maybe noop (moveAnnex key) mtmp
|
|
||||||
|
|
||||||
nodownload :: URLString -> Url.UrlInfo -> FilePath -> Annex (Maybe Key)
|
nodownload :: URLString -> Url.UrlInfo -> FilePath -> Annex (Maybe Key)
|
||||||
nodownload url urlinfo file
|
nodownload url urlinfo file
|
||||||
|
|
|
@ -69,6 +69,7 @@ data GitConfig = GitConfig
|
||||||
, annexVerify :: Bool
|
, annexVerify :: Bool
|
||||||
, annexPidLock :: Bool
|
, annexPidLock :: Bool
|
||||||
, annexPidLockTimeout :: Seconds
|
, annexPidLockTimeout :: Seconds
|
||||||
|
, annexAddUnlocked :: Bool
|
||||||
, coreSymlinks :: Bool
|
, coreSymlinks :: Bool
|
||||||
, coreSharedRepository :: SharedRepository
|
, coreSharedRepository :: SharedRepository
|
||||||
, gcryptId :: Maybe String
|
, gcryptId :: Maybe String
|
||||||
|
@ -118,6 +119,7 @@ extractGitConfig r = GitConfig
|
||||||
, annexPidLock = getbool (annex "pidlock") False
|
, annexPidLock = getbool (annex "pidlock") False
|
||||||
, annexPidLockTimeout = Seconds $ fromMaybe 300 $
|
, annexPidLockTimeout = Seconds $ fromMaybe 300 $
|
||||||
getmayberead (annex "pidlocktimeout")
|
getmayberead (annex "pidlocktimeout")
|
||||||
|
, annexAddUnlocked = getbool (annex "addunlocked") False
|
||||||
, coreSymlinks = getbool "core.symlinks" True
|
, coreSymlinks = getbool "core.symlinks" True
|
||||||
, coreSharedRepository = getSharedRepository r
|
, coreSharedRepository = getSharedRepository r
|
||||||
, gcryptId = getmaybe "core.gcrypt-id"
|
, gcryptId = getmaybe "core.gcrypt-id"
|
||||||
|
|
6
debian/changelog
vendored
6
debian/changelog
vendored
|
@ -14,6 +14,12 @@ git-annex (6.20160212) UNRELEASED; urgency=medium
|
||||||
* When initializing a v6 repo on a crippled filesystem, don't force it
|
* When initializing a v6 repo on a crippled filesystem, don't force it
|
||||||
into direct mode.
|
into direct mode.
|
||||||
* Windows: Fix v6 unlocked files to actually work.
|
* Windows: Fix v6 unlocked files to actually work.
|
||||||
|
* add, addurl, import, importfeed: When in a v6 repository on a crippled
|
||||||
|
filesystem, add files unlocked.
|
||||||
|
* annex.addunlocked: New configuration setting, makes files always be
|
||||||
|
added unlocked. (v6 only)
|
||||||
|
* Improve format of v6 unlocked pointer files to support keys containing
|
||||||
|
slashes.
|
||||||
|
|
||||||
-- Joey Hess <id@joeyh.name> Fri, 12 Feb 2016 14:03:46 -0400
|
-- Joey Hess <id@joeyh.name> Fri, 12 Feb 2016 14:03:46 -0400
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,8 @@ to the git repository, instead of to the annex.
|
||||||
|
|
||||||
Large files are added to the annex in locked form, which prevents further
|
Large files are added to the annex in locked form, which prevents further
|
||||||
modification of their content unless unlocked by [[git-annex-unlock]](1).
|
modification of their content unless unlocked by [[git-annex-unlock]](1).
|
||||||
(This is not the case however when a repository is in direct mode.)
|
(This is not the case however when a repository is in a filesystem not
|
||||||
|
supporting symlinks, or is in direct mode.)
|
||||||
To add a file to the annex in unlocked form, `git add` can be used instead
|
To add a file to the annex in unlocked form, `git add` can be used instead
|
||||||
(that only works when the repository has annex.version 6 or higher).
|
(that only works when the repository has annex.version 6 or higher).
|
||||||
|
|
||||||
|
|
|
@ -823,6 +823,15 @@ Here are all the supported configuration settings.
|
||||||
should be checked into git by `git annex add`. Defaults to true;
|
should be checked into git by `git annex add`. Defaults to true;
|
||||||
set to false to instead make small files be skipped.
|
set to false to instead make small files be skipped.
|
||||||
|
|
||||||
|
* `annex.addunlocked`
|
||||||
|
|
||||||
|
Set to true to make commands like `git-annex add` that add files to the
|
||||||
|
repository add them in unlocked form. The default is to add files in
|
||||||
|
locked form. This only has effect in version 6 repositories.
|
||||||
|
|
||||||
|
When a repository has core.symlinks set to false, it implicitly
|
||||||
|
sets annex.addunlocked to true.
|
||||||
|
|
||||||
* `annex.numcopies`
|
* `annex.numcopies`
|
||||||
|
|
||||||
This is a deprecated setting. You should instead use the
|
This is a deprecated setting. You should instead use the
|
||||||
|
|
|
@ -88,6 +88,13 @@ git-annex converts between the content of the big file and a pointer file,
|
||||||
which is what gets committed to git. All the regular git-annex commands
|
which is what gets committed to git. All the regular git-annex commands
|
||||||
(get, drop, etc) can be used on unlocked files too.
|
(get, drop, etc) can be used on unlocked files too.
|
||||||
|
|
||||||
|
[[!template id=note text="""
|
||||||
|
By default, git-annex commands will add files in locked mode,
|
||||||
|
unless used on a filesystem that does not support symlinks, when unlocked
|
||||||
|
mode is used. To make them always use unlocked mode, run:
|
||||||
|
`git config annex.addunlocked true`
|
||||||
|
"""]]
|
||||||
|
|
||||||
A v6 repository can contain both locked and unlocked files. You can switch
|
A v6 repository can contain both locked and unlocked files. You can switch
|
||||||
a file back and forth using the `git annex lock` and `git annex unlock`
|
a file back and forth using the `git annex lock` and `git annex unlock`
|
||||||
commands. This changes what's stored in git between a git-annex symlink
|
commands. This changes what's stored in git between a git-annex symlink
|
||||||
|
|
Loading…
Add table
Reference in a new issue