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
|
||||
-
|
||||
- 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.
|
||||
-}
|
||||
|
@ -11,14 +11,17 @@ module Annex.Ingest (
|
|||
LockedDown(..),
|
||||
LockDownConfig(..),
|
||||
lockDown,
|
||||
ingestAdd,
|
||||
ingest,
|
||||
finishIngestDirect,
|
||||
finishIngestUnlocked,
|
||||
cleanOldKeys,
|
||||
addLink,
|
||||
makeLink,
|
||||
addUnlocked,
|
||||
restoreFile,
|
||||
forceParams,
|
||||
addAnnexedFile,
|
||||
) where
|
||||
|
||||
import Annex.Common
|
||||
|
@ -29,6 +32,7 @@ import Annex.Content.Direct
|
|||
import Annex.Perms
|
||||
import Annex.Link
|
||||
import Annex.MetaData
|
||||
import Annex.Version
|
||||
import Logs.Location
|
||||
import qualified Annex
|
||||
import qualified Annex.Queue
|
||||
|
@ -111,11 +115,30 @@ lockDown' cfg file = ifM (pure (not (hardlinkFileTmp cfg)) <||> crippledFileSyst
|
|||
, inodeCache = cache
|
||||
}
|
||||
|
||||
{- Ingests a locked down file into the annex.
|
||||
-
|
||||
- The file may be added to the git repository as a locked or an unlocked
|
||||
- file. When unlocked, the work tree file is left alone. When locked,
|
||||
- the work tree file is deleted, in preparation for adding the symlink.
|
||||
{- Ingests a locked down file into the annex. Updates the work tree and
|
||||
- index. -}
|
||||
ingestAdd :: Maybe LockedDown -> Annex (Maybe Key)
|
||||
ingestAdd Nothing = return Nothing
|
||||
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 Nothing = return (Nothing, Nothing)
|
||||
|
@ -141,7 +164,6 @@ ingest (Just (LockedDown cfg source)) = withTSDelta $ \delta -> do
|
|||
golocked key mcache s = do
|
||||
catchNonAsync (moveAnnex key $ contentLocation source)
|
||||
(restoreFile (keyFilename source) key)
|
||||
liftIO $ nukeFile $ keyFilename source
|
||||
populateAssociatedFiles key source
|
||||
success key mcache s
|
||||
|
||||
|
@ -295,3 +317,50 @@ forceParams = ifM (Annex.getState Annex.force)
|
|||
( return [Param "-f"]
|
||||
, 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 Annex.Content
|
||||
import Annex.Content.Direct
|
||||
import Annex.Link
|
||||
import qualified Annex
|
||||
import qualified Annex.Queue
|
||||
import qualified Database.Keys
|
||||
import Config
|
||||
import Utility.InodeCache
|
||||
import Annex.FileMatcher
|
||||
import Annex.Version
|
||||
|
||||
|
@ -99,48 +97,42 @@ start file = ifAnnexed file addpresent add
|
|||
( do
|
||||
ms <- liftIO $ catchMaybeIO $ getSymbolicLinkStatus file
|
||||
case ms of
|
||||
Just s | isSymbolicLink s -> fixup key
|
||||
Just s | isSymbolicLink s -> fixuplink key
|
||||
_ -> ifM (sameInodeCache file =<< Database.Keys.getInodeCaches key)
|
||||
( stop, add )
|
||||
, ifM isDirect
|
||||
( do
|
||||
ms <- liftIO $ catchMaybeIO $ getSymbolicLinkStatus file
|
||||
case ms of
|
||||
Just s | isSymbolicLink s -> fixup key
|
||||
Just s | isSymbolicLink s -> fixuplink key
|
||||
_ -> ifM (goodContent key file)
|
||||
( stop , add )
|
||||
, fixup key
|
||||
, fixuplink key
|
||||
)
|
||||
)
|
||||
fixup key = do
|
||||
fixuplink key = do
|
||||
-- the annexed symlink is present but not yet added to git
|
||||
showStart "add" file
|
||||
liftIO $ removeFile file
|
||||
whenM isDirect $
|
||||
void $ addAssociatedFile key file
|
||||
next $ next $ cleanup file key Nothing =<< inAnnex key
|
||||
next $ next $ do
|
||||
addLink file key Nothing
|
||||
cleanup key =<< inAnnex key
|
||||
|
||||
perform :: FilePath -> CommandPerform
|
||||
perform file = do
|
||||
lockingfile <- not <$> isDirect
|
||||
lockingfile <- not <$> addUnlocked
|
||||
let cfg = LockDownConfig
|
||||
{ lockingFile = lockingfile
|
||||
, hardlinkFileTmp = True
|
||||
}
|
||||
lockDown cfg file >>= ingest >>= go
|
||||
lockDown cfg file >>= ingestAdd >>= finish
|
||||
where
|
||||
go (Just key, cache) = next $ cleanup file key cache True
|
||||
go (Nothing, _) = stop
|
||||
finish (Just key) = next $ cleanup key True
|
||||
finish Nothing = stop
|
||||
|
||||
cleanup :: FilePath -> Key -> Maybe InodeCache -> Bool -> CommandCleanup
|
||||
cleanup file key mcache hascontent = do
|
||||
cleanup :: Key -> Bool -> CommandCleanup
|
||||
cleanup key hascontent = do
|
||||
maybeShowJSON [("key", key2file key)]
|
||||
ifM (isDirect <&&> pure hascontent)
|
||||
( do
|
||||
l <- calcRepo $ gitAnnexLink file key
|
||||
stageSymlink file =<< hashSymlink l
|
||||
, addLink file key mcache
|
||||
)
|
||||
when hascontent $
|
||||
logStatus key InfoPresent
|
||||
return True
|
||||
|
|
|
@ -12,7 +12,6 @@ import Network.URI
|
|||
import Command
|
||||
import Backend
|
||||
import qualified Annex
|
||||
import qualified Annex.Queue
|
||||
import qualified Annex.Url as Url
|
||||
import qualified Backend.URL
|
||||
import qualified Remote
|
||||
|
@ -24,8 +23,6 @@ import Annex.UUID
|
|||
import Logs.Web
|
||||
import Types.KeySource
|
||||
import Types.UrlContents
|
||||
import Config
|
||||
import Annex.Content.Direct
|
||||
import Annex.FileMatcher
|
||||
import Logs.Location
|
||||
import Utility.Metered
|
||||
|
@ -363,13 +360,7 @@ cleanup u url file key mtmp = case mtmp of
|
|||
when (isJust mtmp) $
|
||||
logStatus key InfoPresent
|
||||
setUrlPresent u key url
|
||||
addLink file key Nothing
|
||||
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
|
||||
addAnnexedFile file key mtmp
|
||||
|
||||
nodownload :: URLString -> Url.UrlInfo -> FilePath -> Annex (Maybe Key)
|
||||
nodownload url urlinfo file
|
||||
|
|
|
@ -69,6 +69,7 @@ data GitConfig = GitConfig
|
|||
, annexVerify :: Bool
|
||||
, annexPidLock :: Bool
|
||||
, annexPidLockTimeout :: Seconds
|
||||
, annexAddUnlocked :: Bool
|
||||
, coreSymlinks :: Bool
|
||||
, coreSharedRepository :: SharedRepository
|
||||
, gcryptId :: Maybe String
|
||||
|
@ -118,6 +119,7 @@ extractGitConfig r = GitConfig
|
|||
, annexPidLock = getbool (annex "pidlock") False
|
||||
, annexPidLockTimeout = Seconds $ fromMaybe 300 $
|
||||
getmayberead (annex "pidlocktimeout")
|
||||
, annexAddUnlocked = getbool (annex "addunlocked") False
|
||||
, coreSymlinks = getbool "core.symlinks" True
|
||||
, coreSharedRepository = getSharedRepository r
|
||||
, 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
|
||||
into direct mode.
|
||||
* 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
|
||||
|
||||
|
|
|
@ -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
|
||||
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
|
||||
(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;
|
||||
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`
|
||||
|
||||
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
|
||||
(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 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
|
||||
|
|
Loading…
Add table
Reference in a new issue