remove most remnants of direct mode

A few remain, as needed for upgrades, and for accessing objects from
remotes that are direct mode repos that have not been converted yet.
This commit is contained in:
Joey Hess 2019-08-26 15:52:19 -04:00
parent adb89ee71b
commit 689d1fcc92
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
37 changed files with 193 additions and 799 deletions

View file

@ -13,7 +13,6 @@ module Annex.AutoMerge
import Annex.Common
import qualified Annex.Queue
import Annex.Direct
import Annex.CatFile
import Annex.Link
import Annex.Content
@ -50,9 +49,7 @@ autoMergeFrom branch currbranch mergeconfig canresolvemerge commitmode = do
Nothing -> go Nothing
Just b -> go =<< inRepo (Git.Ref.sha b)
where
go old = ifM isDirect
( mergeDirect currbranch old branch resolvemerge mergeconfig commitmode
, do
go old = do
r <- inRepo (Git.Merge.merge branch mergeconfig commitmode)
<||> (resolvemerge <&&> commitResolvedMerge commitmode)
-- Merging can cause new associated files to appear
@ -61,7 +58,6 @@ autoMergeFrom branch currbranch mergeconfig canresolvemerge commitmode = do
-- close the database if it was open.
Database.Keys.closeDb
return r
)
where
resolvemerge = ifM canresolvemerge
( resolveMerge old branch False
@ -88,13 +84,9 @@ autoMergeFrom branch currbranch mergeconfig canresolvemerge commitmode = do
- the other as a directory or non-annexed file. The annexed file
- is renamed to resolve the merge, and the other object is preserved as-is.
-
- In indirect mode, the merge is resolved in the work tree and files
- The merge is resolved in the work tree and files
- staged, to clean up from a conflicted merge that was run in the work
- tree.
-
- In direct mode, the work tree is not touched here; files are staged to
- the index, and written to the gitAnnexMergeDir, for later handling by
- the direct mode merge code.
-
- This is complicated by needing to support merges run in an overlay
- work tree, in which case the CWD won't be within the work tree.
@ -126,7 +118,7 @@ resolveMerge us them inoverlay = do
let merged = not (null mergedfs')
void $ liftIO cleanup
unlessM (pure inoverlay <||> isDirect) $ do
unless inoverlay $ do
(deleted, cleanup2) <- inRepo (LsFiles.deleted [top])
unless (null deleted) $
Annex.Queue.addCommand "rm"
@ -136,7 +128,7 @@ resolveMerge us them inoverlay = do
when merged $ do
Annex.Queue.flush
unlessM (pure inoverlay <||> isDirect) $ do
unless inoverlay $ do
unstagedmap <- inodeMap $ inRepo $ LsFiles.notInRepo False [top]
cleanConflictCruft mergedks' mergedfs' unstagedmap
showLongNote "Merge conflict was automatically resolved; you may want to examine the result."
@ -230,12 +222,7 @@ resolveMerge' unstagedmap (Just us) them inoverlay u = do
Database.Keys.addAssociatedFile key
=<< inRepo (toTopFilePath dest)
withworktree f a = ifM isDirect
( do
d <- fromRepo gitAnnexMergeDir
a (d </> f)
, a f
)
withworktree f a = a f
{- Stage a graft of a directory or file from a branch
- and update the work tree. -}

View file

@ -1,7 +1,4 @@
{- git-annex file content managing for direct mode
-
- This is deprecated, and will be removed when direct mode gets removed
- from git-annex.
{- git-annex file content managing for old direct mode repositories
-
- Copyright 2012-2014 Joey Hess <id@joeyh.name>
-
@ -10,22 +7,15 @@
module Annex.Content.Direct (
associatedFiles,
associatedFilesRelative,
removeAssociatedFile,
removeAssociatedFileUnchecked,
removeAssociatedFiles,
addAssociatedFile,
goodContent,
recordedInodeCache,
updateInodeCache,
addInodeCache,
writeInodeCache,
compareInodeCaches,
sameInodeCache,
elemInodeCaches,
sameFileStatus,
removeInodeCache,
toInodeCache,
addContentWhenNotPresent,
) where

View file

@ -1,26 +1,25 @@
{- git-annex direct mode
-
- This is deprecated, and will be removed when direct mode gets removed
- from git-annex.
- This only contains some remnants needed to convert away from direct mode.
-
- Copyright 2012-2014 Joey Hess <id@joeyh.name>
-
- Licensed under the GNU AGPL version 3 or higher.
-}
module Annex.Direct where
module Annex.Direct (
switchHEADBack,
stageDirect,
setIndirect,
) where
import Annex.Common
import qualified Annex
import qualified Git
import qualified Git.LsFiles
import qualified Git.Merge
import qualified Git.DiffTree as DiffTree
import qualified Git.Config
import qualified Git.Ref
import qualified Git.Branch
import Git.Sha
import Git.FilePath
import Git.Types
import Config
import Annex.CatFile
@ -28,17 +27,9 @@ import qualified Annex.Queue
import Logs.Location
import Backend
import Types.KeySource
import Annex.Content
import Annex.Content.Direct
import Annex.Link
import Utility.InodeCache
import Utility.CopyFile
import Annex.Perms
import Annex.ReplaceFile
import Annex.VariantFile
import Git.Index
import Annex.GitOverlay
import Annex.LockFile
import Annex.InodeSentinal
import Utility.Metered
@ -102,25 +93,6 @@ stageDirect = do
deletegit file = Annex.Queue.addCommand "rm" [Param "-qf"] [file]
{- Run before a commit to update direct mode bookeeping to reflect the
- staged changes being committed. -}
preCommitDirect :: Annex Bool
preCommitDirect = do
(diffs, clean) <- inRepo $ DiffTree.diffIndex Git.Ref.headRef
makeabs <- flip fromTopFilePath <$> gitRepo
forM_ diffs (go makeabs)
liftIO clean
where
go makeabs diff = do
withkey (DiffTree.srcsha diff) (DiffTree.srcmode diff) removeAssociatedFile
withkey (DiffTree.dstsha diff) (DiffTree.dstmode diff) addAssociatedFile
where
withkey sha _mode a = when (sha /= nullSha) $
catKey sha >>= \case
Nothing -> noop
Just key -> void $ a key $
makeabs $ DiffTree.file diff
{- Adds a file to the annex in direct mode. Can fail, if the file is
- modified or deleted while it's being added. -}
addDirect :: FilePath -> InodeCache -> Annex Bool
@ -150,275 +122,14 @@ addDirect file cache = do
return False
)
{- In direct mode, git merge would usually refuse to do anything, since it
- sees present direct mode files as type changed files.
-
- So, to handle a merge, it's run with the work tree set to a temp
- directory, and the merge is staged into a copy of the index.
- Then the work tree is updated to reflect the merge, and
- finally, the merge is committed and the real index updated.
-
- A lock file is used to avoid races with any other caller of mergeDirect.
-
- To avoid other git processes from making changes to the index while our
- merge is in progress, the index lock file is used as the temp index
- file. This is the same as what git does when updating the index
- normally.
-}
mergeDirect :: Maybe Git.Ref -> Maybe Git.Ref -> Git.Branch -> Annex Bool -> [Git.Merge.MergeConfig] -> Git.Branch.CommitMode -> Annex Bool
mergeDirect startbranch oldref branch resolvemerge mergeconfig commitmode = exclusively $ do
reali <- liftIO . absPath =<< fromRepo indexFile
tmpi <- liftIO . absPath =<< fromRepo (indexFileLock . indexFile)
liftIO $ whenM (doesFileExist reali) $
copyFile reali tmpi
d <- fromRepo gitAnnexMergeDir
liftIO $ do
whenM (doesDirectoryExist d) $
removeDirectoryRecursive d
createDirectoryIfMissing True d
withIndexFile tmpi $ do
merged <- stageMerge d branch mergeconfig commitmode
ok <- if merged
then return True
else resolvemerge
if ok
then do
mergeDirectCleanup d (fromMaybe Git.Sha.emptyTree oldref)
mergeDirectCommit merged startbranch branch commitmode
liftIO $ whenM (doesFileExist tmpi) $
rename tmpi reali
else do
liftIO $ nukeFile tmpi
liftIO $ removeDirectoryRecursive d
return ok
where
exclusively = withExclusiveLock gitAnnexMergeLock
{- Stage a merge into the index, avoiding changing HEAD or the current
- branch. -}
stageMerge :: FilePath -> Git.Branch -> [Git.Merge.MergeConfig] -> Git.Branch.CommitMode -> Annex Bool
stageMerge d branch mergeconfig commitmode = do
-- XXX A bug in git makes stageMerge unsafe to use if the git repo
-- is configured with core.symlinks=false
-- Using merge is not ideal though, since it will
-- update the current branch immediately, before the work tree
-- has been updated, which would leave things in an inconsistent
-- state if mergeDirectCleanup is interrupted.
-- <http://marc.info/?l=git&m=140262402204212&w=2>
merger <- ifM (coreSymlinks <$> Annex.getGitConfig)
( return $ \ref -> Git.Merge.stageMerge ref mergeconfig
, return $ \ref -> Git.Merge.merge ref mergeconfig commitmode
)
inRepo $ \g -> do
wd <- liftIO $ absPath d
gd <- liftIO $ absPath $ Git.localGitDir g
merger branch $
g { location = Local { gitdir = gd, worktree = Just (addTrailingPathSeparator wd) } }
{- Commits after a direct mode merge is complete, and after the work
- tree has been updated by mergeDirectCleanup.
-}
mergeDirectCommit :: Bool -> Maybe Git.Ref -> Git.Branch -> Git.Branch.CommitMode -> Annex ()
mergeDirectCommit allowff old branch commitmode = do
void preCommitDirect
d <- fromRepo Git.localGitDir
let merge_head = d </> "MERGE_HEAD"
let merge_msg = d </> "MERGE_MSG"
let merge_mode = d </> "MERGE_MODE"
ifM (pure allowff <&&> canff)
( inRepo $ Git.Branch.update "merge" Git.Ref.headRef branch -- fast forward
, do
msg <- liftIO $
catchDefaultIO ("merge " ++ fromRef branch) $
readFile merge_msg
void $ inRepo $ Git.Branch.commit commitmode False msg
Git.Ref.headRef [Git.Ref.headRef, branch]
)
liftIO $ mapM_ nukeFile [merge_head, merge_msg, merge_mode]
where
canff = maybe (return False) (\o -> inRepo $ Git.Branch.fastForwardable o branch) old
mergeDirectCleanup :: FilePath -> Git.Ref -> Annex ()
mergeDirectCleanup d oldref = updateWorkTree d oldref False
{- Updates the direct mode work tree to reflect the changes staged in the
- index by a git command, that was run in a temporary work tree.
-
- Uses diff-index to compare the staged changes with provided ref
- which should be the tree before the merge, and applies those
- changes to the work tree.
-
- There are really only two types of changes: An old item can be deleted,
- or a new item added. Two passes are made, first deleting and then
- adding. This is to handle cases where eg, a file is deleted and a
- directory is added. (The diff-tree output may list these in the opposite
- order, but we cannot add the directory until the file with the
- same name is removed.)
-}
updateWorkTree :: FilePath -> Git.Ref -> Bool -> Annex ()
updateWorkTree d oldref force = do
(items, cleanup) <- inRepo $ DiffTree.diffIndex oldref
makeabs <- flip fromTopFilePath <$> gitRepo
let fsitems = zip (map (makeabs . DiffTree.file) items) items
forM_ fsitems $
go makeabs DiffTree.srcsha moveout moveout_raw
forM_ fsitems $
go makeabs DiffTree.dstsha movein movein_raw
void $ liftIO cleanup
where
go makeabs getsha a araw (f, item)
| getsha item == nullSha = noop
| otherwise = void $
tryNonAsync . maybe (araw item makeabs f) (\k -> void $ a item makeabs k f)
=<< catKey (getsha item)
moveout _ _ = removeDirect
{- Files deleted by the merge are removed from the work tree.
- Empty work tree directories are removed, per git behavior. -}
moveout_raw _ _ f = liftIO $ do
nukeFile f
void $ tryIO $ removeDirectory $ parentDir f
{- If the file is already present, with the right content for the
- key, it's left alone.
-
- If the file is already present, and does not exist in the
- oldref, preserve this local file.
-
- Otherwise, create the symlink and then if possible, replace it
- with the content. -}
movein item makeabs k f = unlessM (goodContent k f) $ do
unless force $ preserveUnannexed item makeabs f oldref
l <- calcRepo $ gitAnnexLink f k
replaceFile f $ makeAnnexLink l
toDirect k f
{- Any new, modified, or renamed files were written to the temp
- directory by the merge, and are moved to the real work tree. -}
movein_raw item makeabs f = do
unless force $ preserveUnannexed item makeabs f oldref
liftIO $ do
createDirectoryIfMissing True $ parentDir f
void $ tryIO $ rename (d </> getTopFilePath (DiffTree.file item)) f
{- If the file that's being moved in is already present in the work
- tree, but did not exist in the oldref, preserve this
- local, unannexed file (or directory), as "variant-local".
-
- It's also possible that the file that's being moved in
- is in a directory that collides with an exsting, non-annexed
- file (not a directory), which should be preserved.
-}
preserveUnannexed :: DiffTree.DiffTreeItem -> (TopFilePath -> FilePath) -> FilePath -> Ref -> Annex ()
preserveUnannexed item makeabs absf oldref = do
whenM (liftIO (collidingitem absf) <&&> unannexed absf) $
liftIO $ findnewname absf 0
checkdirs (DiffTree.file item)
where
checkdirs from = case upFrom (getTopFilePath from) of
Nothing -> noop
Just p -> do
let d = asTopFilePath p
let absd = makeabs d
whenM (liftIO (colliding_nondir absd) <&&> unannexed absd) $
liftIO $ findnewname absd 0
checkdirs d
collidingitem f = isJust
<$> catchMaybeIO (getSymbolicLinkStatus f)
colliding_nondir f = maybe False (not . isDirectory)
<$> catchMaybeIO (getSymbolicLinkStatus f)
unannexed f = (isNothing <$> isAnnexLink f)
<&&> (isNothing <$> catFileDetails oldref f)
findnewname :: FilePath -> Int -> IO ()
findnewname f n = do
let localf = mkVariant f
("local" ++ if n > 0 then show n else "")
ifM (collidingitem localf)
( findnewname f (n+1)
, rename f localf
`catchIO` const (findnewname f (n+1))
)
{- If possible, converts a symlink in the working tree into a direct
- mode file. If the content is not available, leaves the symlink
- unchanged. -}
toDirect :: Key -> FilePath -> Annex ()
toDirect k f = fromMaybe noop =<< toDirectGen k f
toDirectGen :: Key -> FilePath -> Annex (Maybe (Annex ()))
toDirectGen k f = do
loc <- calcRepo $ gitAnnexLocation k
ifM (liftIO $ doesFileExist loc)
( return $ Just $ fromindirect loc
, do
{- Copy content from another direct file. -}
absf <- liftIO $ absPath f
dlocs <- filterM (goodContent k) =<<
filterM (\l -> isNothing <$> getAnnexLinkTarget l) =<<
(filter (/= absf) <$> addAssociatedFile k f)
case dlocs of
[] -> return Nothing
(dloc:_) -> return $ Just $ fromdirect dloc
)
where
fromindirect loc = do
{- Move content from annex to direct file. -}
updateInodeCache k loc
void $ addAssociatedFile k f
modifyContent loc $ do
thawContent loc
liftIO (replaceFileFrom loc f)
`catchIO` (\_ -> freezeContent loc)
fromdirect loc = do
replaceFile f $
liftIO . void . copyFileExternal CopyAllMetaData loc
updateInodeCache k f
{- Removes a direct mode file, while retaining its content in the annex
- (unless its content has already been changed). -}
removeDirect :: Key -> FilePath -> Annex ()
removeDirect k f = do
void $ removeAssociatedFileUnchecked k f
unlessM (inAnnex k) $
-- If moveAnnex rejects the content of the key,
-- treat that the same as its content having changed.
ifM (goodContent k f)
( unlessM (moveAnnex k f) $
logStatus k InfoMissing
, logStatus k InfoMissing
)
liftIO $ do
nukeFile f
void $ tryIO $ removeDirectory $ parentDir f
{- Called when a direct mode file has been changed. Its old content may be
- lost. -}
changedDirect :: Key -> FilePath -> Annex ()
changedDirect oldk f = do
locs <- removeAssociatedFile oldk f
whenM (pure (null locs) <&&> not <$> inAnnex oldk) $
logStatus oldk InfoMissing
{- Git config settings to enable/disable direct mode. -}
setDirect :: Bool -> Annex ()
setDirect wantdirect = do
if wantdirect
then do
switchHEAD
setbare
else do
setbare
switchHEADBack
setIndirect :: Annex ()
setIndirect = do
setbare
switchHEADBack
setConfig (annexConfig "direct") val
Annex.changeGitConfig $ \c -> c { annexDirect = wantdirect }
Annex.changeGitConfig $ \c -> c { annexDirect = False }
where
val = Git.Config.boolConfig wantdirect
val = Git.Config.boolConfig False
coreworktree = ConfigKey "core.worktree"
indirectworktree = ConfigKey "core.indirect-worktree"
setbare = do
@ -426,9 +137,7 @@ setDirect wantdirect = do
-- core.bare; git does not allow both to be set, so
-- unset it when enabling direct mode, caching in
-- core.indirect-worktree
if wantdirect
then moveconfig coreworktree indirectworktree
else moveconfig indirectworktree coreworktree
moveconfig indirectworktree coreworktree
setConfig (ConfigKey Git.Config.coreBare) val
moveconfig src dest = getConfigMaybe src >>= \case
Nothing -> noop
@ -437,20 +146,6 @@ setDirect wantdirect = do
setConfig dest wt
reloadConfig
{- Since direct mode sets core.bare=true, incoming pushes could change
- the currently checked out branch. To avoid this problem, HEAD
- is changed to a internal ref that nothing is going to push to.
-
- For refs/heads/master, use refs/heads/annex/direct/master;
- this way things that show HEAD (eg shell prompts) will
- hopefully show just "master". -}
directBranch :: Ref -> Ref
directBranch orighead = case splitc '/' $ fromRef orighead of
("refs":"heads":"annex":"direct":_) -> orighead
("refs":"heads":rest) ->
Ref $ "refs/heads/annex/direct/" ++ intercalate "/" rest
_ -> Ref $ "refs/heads/" ++ fromRef (Git.Ref.base orighead)
{- Converts a directBranch back to the original branch.
-
- Any other ref is left unchanged.
@ -461,15 +156,6 @@ fromDirectBranch directhead = case splitc '/' $ fromRef directhead of
Ref $ "refs/heads/" ++ intercalate "/" rest
_ -> directhead
switchHEAD :: Annex ()
switchHEAD = maybe noop switch =<< inRepo Git.Branch.currentUnsafe
where
switch orighead = do
let newhead = directBranch orighead
maybe noop (inRepo . Git.Branch.update "entering direct mode" newhead)
=<< inRepo (Git.Ref.sha orighead)
inRepo $ Git.Branch.checkout newhead
switchHEADBack :: Annex ()
switchHEADBack = maybe noop switch =<< inRepo Git.Branch.currentUnsafe
where

View file

@ -17,7 +17,6 @@ import qualified Command.Drop
import Command
import Annex.Wanted
import Config
import Annex.Content.Direct
import qualified Database.Keys
import Git.FilePath
@ -44,20 +43,13 @@ type Reason = String
- A VerifiedCopy can be provided as an optimisation when eg, a key
- has just been uploaded to a remote.
-
- In direct mode, all associated files are checked, and only if all
- of them are unwanted are they dropped.
-
- The runner is used to run CommandStart sequentially, it's typically
- callCommandAction.
-}
handleDropsFrom :: [UUID] -> [Remote] -> Reason -> Bool -> Key -> AssociatedFile -> [VerifiedCopy] -> (CommandStart -> CommandCleanup) -> Annex ()
handleDropsFrom locs rs reason fromhere key afile preverified runner = do
l <- ifM isDirect
( associatedFilesRelative key
, do
g <- Annex.gitRepo
map (`fromTopFilePath` g) <$> Database.Keys.getAssociatedFiles key
)
g <- Annex.gitRepo
l <- map (`fromTopFilePath` g) <$> Database.Keys.getAssociatedFiles key
let fs = case afile of
AssociatedFile (Just f) -> nub (f : l)
AssociatedFile Nothing -> l

View file

@ -13,7 +13,6 @@ module Annex.Ingest (
ingestAdd',
ingest,
ingest',
finishIngestDirect,
finishIngestUnlocked,
cleanOldKeys,
addLink,
@ -28,7 +27,6 @@ import Annex.Common
import Types.KeySource
import Backend
import Annex.Content
import Annex.Content.Direct
import Annex.Perms
import Annex.Link
import Annex.MetaData
@ -137,14 +135,9 @@ ingestAdd' meterupdate ld@(Just (LockedDown cfg source)) mk = do
let f = keyFilename source
if lockingFile cfg
then addLink f k mic
else ifM isDirect
( do
l <- calcRepo $ gitAnnexLink f k
stageSymlink f =<< hashSymlink l
, do
mode <- liftIO $ catchMaybeIO $ fileMode <$> getFileStatus (contentLocation source)
stagePointerFile f mode =<< hashPointerFile k
)
else do
mode <- liftIO $ catchMaybeIO $ fileMode <$> getFileStatus (contentLocation source)
stagePointerFile f mode =<< hashPointerFile k
return (Just k)
{- Ingests a locked down file into the annex. Does not update the working
@ -170,10 +163,7 @@ ingest' preferredbackend meterupdate (Just (LockedDown cfg source)) mk restage =
where
go (Just key) mcache (Just s)
| lockingFile cfg = golocked key mcache s
| otherwise = ifM isDirect
( godirect key mcache s
, gounlocked key mcache s
)
| otherwise = gounlocked key mcache s
go _ _ _ = failure "failed to generate a key"
golocked key mcache s =
@ -197,12 +187,6 @@ ingest' preferredbackend meterupdate (Just (LockedDown cfg source)) mk restage =
success key (Just cache) s
gounlocked _ _ _ = failure "failed statting file"
godirect key (Just cache) s = do
addInodeCache key cache
finishIngestDirect key source
success key (Just cache) s
godirect _ _ _ = failure "failed statting file"
success k mcache s = do
genMetaData k (keyFilename source) s
return (Just k, mcache)
@ -212,16 +196,6 @@ ingest' preferredbackend meterupdate (Just (LockedDown cfg source)) mk restage =
cleanCruft source
return (Nothing, Nothing)
finishIngestDirect :: Key -> KeySource -> Annex ()
finishIngestDirect key source = do
void $ addAssociatedFile key $ keyFilename source
cleanCruft source
{- Copy to any other locations using the same key. -}
otherfs <- filter (/= keyFilename source) <$> associatedFiles key
forM_ otherfs $
addContentWhenNotPresent key (keyFilename source)
finishIngestUnlocked :: Key -> KeySource -> Annex ()
finishIngestUnlocked key source = do
cleanCruft source
@ -333,7 +307,7 @@ forceParams = ifM (Annex.getState Annex.force)
- Also, when in an adjusted unlocked branch, always add files unlocked.
-}
addUnlocked :: Annex Bool
addUnlocked = isDirect <||>
addUnlocked =
(versionSupportsUnlockedPointers <&&>
((not . coreSymlinks <$> Annex.getGitConfig) <||>
(annexAddUnlocked <$> Annex.getGitConfig) <||>
@ -352,7 +326,7 @@ addUnlocked = isDirect <||>
- When the content of the key is not accepted into the annex, returns False.
-}
addAnnexedFile :: FilePath -> Key -> Maybe FilePath -> Annex Bool
addAnnexedFile file key mtmp = ifM (addUnlocked <&&> not <$> isDirect)
addAnnexedFile file key mtmp = ifM addUnlocked
( do
mode <- maybe
(pure Nothing)
@ -371,15 +345,8 @@ addAnnexedFile file key mtmp = ifM (addUnlocked <&&> not <$> isDirect)
)
, 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
Just tmp -> moveAnnex key tmp
Nothing -> return True
)
where

View file

@ -35,7 +35,7 @@ import Annex.WorkTree
import Config
import Config.Files
import Config.Smudge
import Annex.Direct
import qualified Annex.Direct as Direct
import qualified Annex.AdjustedBranch as AdjustedBranch
import Annex.Environment
import Annex.Hook
@ -126,7 +126,7 @@ initialize' mversion = checkCanInitialize $ do
-- Handle case where this repo was cloned from a
-- direct mode repo
, unlessM isBareRepo
switchHEADBack
Direct.switchHEADBack
)
propigateSecureHashesOnly
createInodeSentinalFile False

View file

@ -9,17 +9,15 @@ module Annex.UpdateInstead where
import qualified Annex
import Annex.Common
import Config
import Annex.Version
import Annex.AdjustedBranch
import Git.Branch
import Git.ConfigTypes
{- receive.denyCurrentBranch=updateInstead does not work in direct mode
- repositories or when an adjusted branch is checked out, so must be
- emulated. -}
{- receive.denyCurrentBranch=updateInstead does not work
- when an adjusted branch is checked out, so must be emulated. -}
needUpdateInsteadEmulation :: Annex Bool
needUpdateInsteadEmulation = updateinsteadset <&&> (isDirect <||> isadjusted)
needUpdateInsteadEmulation = updateinsteadset <&&> isadjusted
where
updateinsteadset = (== UpdateInstead) . receiveDenyCurrentBranch
<$> Annex.getGitConfig

View file

@ -36,7 +36,6 @@ import Annex.Version
import Annex.CurrentBranch
import qualified Annex
import Utility.InodeCache
import Annex.Content.Direct
import qualified Database.Keys
import qualified Command.Sync
import qualified Git.Branch
@ -245,7 +244,7 @@ commitStaged msg = do
- access the file after closing it. -}
delayaddDefault :: Annex (Maybe Seconds)
#ifdef darwin_HOST_OS
delayaddDefault = ifM (isDirect <||> versionSupportsUnlockedPointers)
delayaddDefault = ifM versionSupportsUnlockedPointers
( return Nothing
, return $ Just $ Seconds 1
)
@ -275,14 +274,13 @@ delayaddDefault = return Nothing
handleAdds :: FilePath -> Bool -> Maybe Seconds -> [Change] -> Assistant [Change]
handleAdds lockdowndir havelsof delayadd cs = returnWhen (null incomplete) $ do
let (pending, inprocess) = partition isPendingAddChange incomplete
direct <- liftAnnex isDirect
unlocked <- liftAnnex versionSupportsUnlockedPointers
let lockingfiles = not (unlocked || direct)
let lockingfiles = not unlocked
let lockdownconfig = LockDownConfig
{ lockingFile = lockingfiles
, hardlinkFileTmpDir = Just lockdowndir
}
(pending', cleanup) <- if unlocked || direct
(pending', cleanup) <- if unlocked
then return (pending, noop)
else findnew pending
(postponed, toadd) <- partitionEithers
@ -296,9 +294,9 @@ handleAdds lockdowndir havelsof delayadd cs = returnWhen (null incomplete) $ do
added <- addaction toadd $
catMaybes <$>
if not lockingfiles
then addunlocked direct toadd
then addunlocked toadd
else forM toadd (add lockdownconfig)
if DirWatcher.eventsCoalesce || null added || unlocked || direct
if DirWatcher.eventsCoalesce || null added || unlocked
then return $ added ++ otherchanges
else do
r <- handleAdds lockdowndir havelsof delayadd =<< getChanges
@ -341,10 +339,10 @@ handleAdds lockdowndir havelsof delayadd cs = returnWhen (null incomplete) $ do
- same InodeCache as the new file. If so, we can just update
- bookkeeping, and stage the file in git.
-}
addunlocked :: Bool -> [Change] -> Assistant [Maybe Change]
addunlocked isdirect toadd = do
addunlocked :: [Change] -> Assistant [Maybe Change]
addunlocked toadd = do
ct <- liftAnnex compareInodeCachesWith
m <- liftAnnex $ removedKeysMap isdirect ct cs
m <- liftAnnex $ removedKeysMap ct cs
delta <- liftAnnex getTSDelta
let cfg = LockDownConfig
{ lockingFile = False
@ -359,26 +357,22 @@ handleAdds lockdowndir havelsof delayadd cs = returnWhen (null incomplete) $ do
Just cache ->
case M.lookup (inodeCacheToKey ct cache) m of
Nothing -> add cfg c
Just k -> fastadd isdirect c k
Just k -> fastadd c k
fastadd :: Bool -> Change -> Key -> Assistant (Maybe Change)
fastadd isdirect change key = do
fastadd :: Change -> Key -> Assistant (Maybe Change)
fastadd change key = do
let source = keySource $ lockedDown change
liftAnnex $ if isdirect
then finishIngestDirect key source
else finishIngestUnlocked key source
liftAnnex $ finishIngestUnlocked key source
done change Nothing (keyFilename source) key
removedKeysMap :: Bool -> InodeComparisonType -> [Change] -> Annex (M.Map InodeCacheKey Key)
removedKeysMap isdirect ct l = do
removedKeysMap :: InodeComparisonType -> [Change] -> Annex (M.Map InodeCacheKey Key)
removedKeysMap ct l = do
mks <- forM (filter isRmChange l) $ \c ->
catKeyFile $ changeFile c
M.fromList . concat <$> mapM mkpairs (catMaybes mks)
where
mkpairs k = map (\c -> (inodeCacheToKey ct c, k)) <$>
if isdirect
then recordedInodeCache k
else Database.Keys.getInodeCaches k
Database.Keys.getInodeCaches k
failedingest change = do
refill [retryChange change]
@ -392,11 +386,8 @@ handleAdds lockdowndir havelsof delayadd cs = returnWhen (null incomplete) $ do
mode <- liftIO $ catchMaybeIO $ fileMode <$> getFileStatus file
stagePointerFile file mode =<< hashPointerFile key
, do
link <- ifM isDirect
( calcRepo $ gitAnnexLink file key
, makeLink file key mcache
)
whenM (pure DirWatcher.eventsCoalesce <||> isDirect) $
link <- makeLink file key mcache
when DirWatcher.eventsCoalesce $
stageSymlink file =<< hashSymlink link
)
showEndOk

View file

@ -32,7 +32,6 @@ import Utility.ThreadScheduler
import qualified Assistant.Threads.Watcher as Watcher
import Utility.Batch
import Utility.NotificationBroadcaster
import Config
import Utility.HumanTime
import Utility.Tense
import Git.Repair
@ -200,8 +199,7 @@ dailyCheck urlrenderer = do
liftAnnex $ warning msg
void $ addAlert $ sanityCheckFixAlert msg
addsymlink file s = do
isdirect <- liftAnnex isDirect
Watcher.runHandler (Watcher.onAddSymlink isdirect) file s
Watcher.runHandler Watcher.onAddSymlink file s
insanity $ "found unstaged symlink: " ++ file
hourlyCheck :: Assistant ()

View file

@ -23,14 +23,13 @@ import Assistant.Types.Changes
import Assistant.Alert
import Utility.DirWatcher
import Utility.DirWatcher.Types
import Utility.InodeCache
import qualified Annex
import qualified Annex.Queue
import qualified Git
import qualified Git.UpdateIndex
import qualified Git.LsFiles as LsFiles
import Annex.WorkTree
import Annex.Direct
import Annex.Content.Direct
import Annex.CatFile
import Annex.CheckIgnore
import Annex.Link
@ -41,7 +40,6 @@ import Annex.Version
import Annex.InodeSentinal
import Git.Types
import Git.FilePath
import Config
import Config.GitConfig
import Utility.ThreadScheduler
import Logs.Location
@ -92,16 +90,13 @@ runWatcher :: Assistant ()
runWatcher = do
startup <- asIO1 startupScan
matcher <- liftAnnex largeFilesMatcher
direct <- liftAnnex isDirect
unlocked <- liftAnnex versionSupportsUnlockedPointers
symlinkssupported <- liftAnnex $ coreSymlinks <$> Annex.getGitConfig
addhook <- hook $ if unlocked
then onAddUnlocked symlinkssupported matcher
else if direct
then onAddDirect symlinkssupported matcher
else onAdd matcher
else onAdd matcher
delhook <- hook onDel
addsymlinkhook <- hook $ onAddSymlink direct
addsymlinkhook <- hook onAddSymlink
deldirhook <- hook onDelDir
errhook <- hook onErr
let hooks = mkWatchHooks
@ -224,7 +219,7 @@ onAddUnlocked :: Bool -> GetFileMatcher -> Handler
onAddUnlocked symlinkssupported matcher f fs = do
mk <- liftIO $ isPointerFile f
case mk of
Nothing -> onAddUnlocked' False contentchanged addassociatedfile addlink samefilestatus symlinkssupported matcher f fs
Nothing -> onAddUnlocked' contentchanged addassociatedfile addlink samefilestatus symlinkssupported matcher f fs
Just k -> addlink f k
where
addassociatedfile key file =
@ -247,27 +242,15 @@ onAddUnlocked symlinkssupported matcher f fs = do
liftAnnex $ stagePointerFile file mode =<< hashPointerFile key
madeChange file $ LinkChange (Just key)
{- In direct mode, add events are received for both new files, and
- modified existing files.
-}
onAddDirect :: Bool -> GetFileMatcher -> Handler
onAddDirect = onAddUnlocked' True changedDirect addassociatedfile addlink sameFileStatus
where
addassociatedfile key file = void $ addAssociatedFile key file
addlink file key = do
link <- liftAnnex $ calcRepo $ gitAnnexLink file key
addLink file link (Just key)
onAddUnlocked'
:: Bool
-> (Key -> FilePath -> Annex ())
:: (Key -> FilePath -> Annex ())
-> (Key -> FilePath -> Annex ())
-> (FilePath -> Key -> Assistant (Maybe Change))
-> (Key -> FilePath -> FileStatus -> Annex Bool)
-> Bool
-> GetFileMatcher
-> Handler
onAddUnlocked' isdirect contentchanged addassociatedfile addlink samefilestatus symlinkssupported matcher file fs = do
onAddUnlocked' contentchanged addassociatedfile addlink samefilestatus symlinkssupported matcher file fs = do
v <- liftAnnex $ catKeyFile file
case (v, fs) of
(Just key, Just filestatus) ->
@ -306,31 +289,28 @@ onAddUnlocked' isdirect contentchanged addassociatedfile addlink samefilestatus
Nothing -> noop
Just key -> liftAnnex $
addassociatedfile key file
onAddSymlink' (Just $ fromRawFilePath lt) mk isdirect file fs
onAddSymlink' (Just $ fromRawFilePath lt) mk file fs
{- A symlink might be an arbitrary symlink, which is just added.
- Or, if it is a git-annex symlink, ensure it points to the content
- before adding it.
-}
onAddSymlink :: Bool -> Handler
onAddSymlink isdirect file filestatus = unlessIgnored file $ do
onAddSymlink :: Handler
onAddSymlink file filestatus = unlessIgnored file $ do
linktarget <- liftIO (catchMaybeIO $ readSymbolicLink file)
kv <- liftAnnex (lookupFile file)
onAddSymlink' linktarget kv isdirect file filestatus
onAddSymlink' linktarget kv file filestatus
onAddSymlink' :: Maybe String -> Maybe Key -> Bool -> Handler
onAddSymlink' linktarget mk isdirect file filestatus = go mk
onAddSymlink' :: Maybe String -> Maybe Key -> Handler
onAddSymlink' linktarget mk file filestatus = go mk
where
go (Just key) = do
when isdirect $
liftAnnex $ void $ addAssociatedFile key file
link <- liftAnnex $ calcRepo $ gitAnnexLink file key
if linktarget == Just link
then ensurestaged (Just link) =<< getDaemonStatus
else do
unless isdirect $
liftAnnex $ replaceFile file $
makeAnnexLink link
liftAnnex $ replaceFile file $
makeAnnexLink link
addLink file link (Just key)
-- other symlink, not git-annex
go Nothing = ensurestaged linktarget =<< getDaemonStatus
@ -376,11 +356,8 @@ onDel file _ = do
onDel' :: FilePath -> Annex ()
onDel' file = do
topfile <- inRepo (toTopFilePath file)
ifM versionSupportsUnlockedPointers
( withkey $ flip Database.Keys.removeAssociatedFile topfile
, whenM isDirect $
withkey $ \key -> void $ removeAssociatedFile key file
)
whenM versionSupportsUnlockedPointers $
withkey $ flip Database.Keys.removeAssociatedFile topfile
Annex.Queue.addUpdateIndex =<<
inRepo (Git.UpdateIndex.unstageFile file)
where

View file

@ -24,7 +24,6 @@ import CmdLine.Batch as ReExported
import Options.Applicative as ReExported hiding (command)
import qualified Git
import Annex.Init
import Config
import Utility.Daemon
import Types.Transfer
import Types.ActionItem
@ -120,10 +119,6 @@ commonChecks = [repoExists]
repoExists :: CommandCheck
repoExists = CommandCheck 0 ensureInitialized
notDirect :: Command -> Command
notDirect = addCheck $ whenM isDirect $
giveup "You cannot run this command in a direct mode repository."
notBareRepo :: Command -> Command
notBareRepo = addCheck $ whenM (fromRepo Git.repoIsLocalBare) $
giveup "You cannot run this command in a bare repository."

View file

@ -11,7 +11,6 @@ import Command
import Annex.Ingest
import Logs.Location
import Annex.Content
import Annex.Content.Direct
import qualified Annex
import qualified Annex.Queue
import qualified Database.Keys
@ -73,8 +72,7 @@ seek o = startConcurrency commandStages $ do
go withFilesMaybeModified
ifM versionSupportsUnlockedPointers
( go withUnmodifiedUnlockedPointers
, unlessM isDirect $
go withFilesOldUnlocked
, go withFilesOldUnlocked
)
{- Pass file off to git-add. -}
@ -116,13 +114,7 @@ start file = do
( liftIO (catchMaybeIO $ getSymbolicLinkStatus file) >>= \case
Just s | isSymbolicLink s -> fixuplink key
_ -> add
, ifM isDirect
( liftIO (catchMaybeIO $ getSymbolicLinkStatus file) >>= \case
Just s | isSymbolicLink s -> fixuplink key
_ -> ifM (goodContent key file)
( stop , add )
, fixuplink key
)
, fixuplink key
)
fixuplink key = starting "add" (ActionItemWorkTreeFile file) $ do
-- the annexed symlink is present but not yet added to git

View file

@ -13,10 +13,9 @@ import Annex.Ingest
import Command.Unused (withUnusedMaps, UnusedMaps(..), startUnused)
cmd :: Command
cmd = notDirect $
command "addunused" SectionMaintenance
"add back unused files"
(paramRepeating paramNumRange) (withParams seek)
cmd = command "addunused" SectionMaintenance
"add back unused files"
(paramRepeating paramNumRange) (withParams seek)
seek :: CmdParams -> CommandSeek
seek = withUnusedMaps start

View file

@ -11,7 +11,7 @@ import Command
import Annex.AdjustedBranch
cmd :: Command
cmd = notBareRepo $ notDirect $ noDaemonRunning $
cmd = notBareRepo $ noDaemonRunning $
command "adjust" SectionSetup "enter adjusted branch"
paramNothing (seek <$$> optParser)

View file

@ -25,7 +25,7 @@ import System.Posix.Files
#endif
cmd :: Command
cmd = notDirect $ noCommit $ withGlobalOptions [annexedMatchingOptions] $
cmd = noCommit $ withGlobalOptions [annexedMatchingOptions] $
command "fix" SectionMaintenance
"fix up links to annexed content"
paramPaths (withParams seek)

View file

@ -19,7 +19,7 @@ import qualified Backend.URL
import Network.URI
cmd :: Command
cmd = notDirect $ notBareRepo $ withGlobalOptions [jsonOptions] $
cmd = notBareRepo $ withGlobalOptions [jsonOptions] $
command "fromkey" SectionPlumbing "adds a file using a specific key"
(paramRepeating (paramPair paramKey paramPath))
(seek <$$> optParser)

View file

@ -15,8 +15,6 @@ import qualified Remote
import qualified Types.Backend
import qualified Backend
import Annex.Content
import qualified Annex.Content.Direct as Direct
import Annex.Direct
import Annex.Perms
import Annex.Link
import Logs.Location
@ -28,7 +26,6 @@ import Annex.NumCopies
import Annex.UUID
import Annex.ReplaceFile
import Utility.DataUnits
import Config
import Utility.HumanTime
import Utility.CopyFile
import Git.FilePath
@ -225,16 +222,15 @@ fixLink key file = do
- in this repository only. -}
verifyLocationLog :: Key -> KeyStatus -> ActionItem -> Annex Bool
verifyLocationLog key keystatus ai = do
direct <- isDirect
obj <- calcRepo $ gitAnnexLocation key
present <- if not direct && isKeyUnlockedThin keystatus
present <- if isKeyUnlockedThin keystatus
then liftIO (doesFileExist obj)
else inAnnex key
u <- getUUID
{- Since we're checking that a key's object file is present, throw
- in a permission fixup here too. -}
when (present && not direct) $ do
when present $ do
void $ tryIO $ case keystatus of
KeyUnlockedThin -> thawContent obj
KeyLockedThin -> thawContent obj
@ -252,9 +248,7 @@ verifyLocationLog key keystatus ai = do
whenM (annexSecureHashesOnly <$> Annex.getGitConfig) $
warning $ "** Despite annex.securehashesonly being set, " ++ obj ++ " has content present in the annex using an insecure " ++ decodeBS (formatKeyVariety (keyVariety key)) ++ " key"
{- In direct mode, modified files will show up as not present,
- but that is expected and not something to do anything about. -}
if direct && not present
if not present
then return True
else verifyLocationLog' key ai present u (logChange key u)
@ -319,56 +313,38 @@ verifyRequiredContent _ _ = return True
{- Verifies the associated file records. -}
verifyAssociatedFiles :: Key -> KeyStatus -> FilePath -> Annex Bool
verifyAssociatedFiles key keystatus file = do
ifM isDirect (godirect, goindirect)
return True
where
godirect = do
fs <- Direct.addAssociatedFile key file
forM_ fs $ \f ->
unlessM (liftIO $ doesFileExist f) $
void $ Direct.removeAssociatedFile key f
goindirect = when (isKeyUnlockedThin keystatus) $ do
when (isKeyUnlockedThin keystatus) $ do
f <- inRepo $ toTopFilePath file
afs <- Database.Keys.getAssociatedFiles key
unless (getTopFilePath f `elem` map getTopFilePath afs) $
Database.Keys.addAssociatedFile key f
return True
verifyWorkTree :: Key -> FilePath -> Annex Bool
verifyWorkTree key file = do
ifM isDirect ( godirect, goindirect )
return True
where
{- Ensures that files whose content is available are in direct mode. -}
godirect = whenM (isJust <$> isAnnexLink file) $ do
v <- toDirectGen key file
case v of
Nothing -> noop
Just a -> do
showNote "fixing direct mode"
a
{- Make sure that a pointer file is replaced with its content,
- when the content is available. -}
goindirect = do
mk <- liftIO $ isPointerFile file
case mk of
Just k | k == key -> whenM (inAnnex key) $ do
showNote "fixing worktree content"
replaceFile file $ \tmp -> do
mode <- liftIO $ catchMaybeIO $ fileMode <$> getFileStatus file
ifM (annexThin <$> Annex.getGitConfig)
( void $ linkFromAnnex key tmp mode
, do
obj <- calcRepo $ gitAnnexLocation key
void $ checkedCopyFile key obj tmp mode
thawContent tmp
)
Database.Keys.storeInodeCaches key [file]
_ -> return ()
mk <- liftIO $ isPointerFile file
case mk of
Just k | k == key -> whenM (inAnnex key) $ do
showNote "fixing worktree content"
replaceFile file $ \tmp -> do
mode <- liftIO $ catchMaybeIO $ fileMode <$> getFileStatus file
ifM (annexThin <$> Annex.getGitConfig)
( void $ linkFromAnnex key tmp mode
, do
obj <- calcRepo $ gitAnnexLocation key
void $ checkedCopyFile key obj tmp mode
thawContent tmp
)
Database.Keys.storeInodeCaches key [file]
_ -> return ()
return True
{- The size of the data for a key is checked against the size encoded in
- the key's metadata, if available.
-
- Not checked when a file is unlocked, or in direct mode.
- Not checked when a file is unlocked.
-}
checkKeySize :: Key -> KeyStatus -> ActionItem -> Annex Bool
checkKeySize _ KeyUnlockedThin _ = return True
@ -439,28 +415,15 @@ checkKeyUpgrade _ _ _ (AssociatedFile Nothing) =
- thus when the user modifies the file, the object will be modified and
- not pass the check, and we don't want to find an error in this case.
- So, skip the check if the key is unlocked and modified.
-
- In direct mode this is not done if the file has clearly been modified,
- because modification of direct mode files is allowed. It's still done
- if the file does not appear modified, to catch disk corruption, etc.
-}
checkBackend :: Backend -> Key -> KeyStatus -> AssociatedFile -> Annex Bool
checkBackend backend key keystatus afile = go =<< isDirect
where
go False = do
content <- calcRepo $ gitAnnexLocation key
ifM (pure (isKeyUnlockedThin keystatus) <&&> (not <$> isUnmodified key content))
( nocheck
, checkBackendOr badContent backend key content ai
)
go True = case afile of
AssociatedFile Nothing -> nocheck
AssociatedFile (Just f) -> checkdirect f
checkdirect file = ifM (Direct.goodContent key file)
( checkBackendOr' (badContentDirect file) backend key file ai
(Direct.goodContent key file)
, nocheck
checkBackend backend key keystatus afile = do
content <- calcRepo $ gitAnnexLocation key
ifM (pure (isKeyUnlockedThin keystatus) <&&> (not <$> isUnmodified key content))
( nocheck
, checkBackendOr badContent backend key content ai
)
where
nocheck = return True
ai = mkActionItem (key, afile)
@ -475,7 +438,7 @@ checkBackendOr bad backend key file ai =
-- The postcheck action is run after the content is verified,
-- in order to detect situations where the file is changed while being
-- verified (particularly in direct mode).
-- verified.
checkBackendOr' :: (Key -> Annex String) -> Backend -> Key -> FilePath -> ActionItem -> Annex Bool -> Annex Bool
checkBackendOr' bad backend key file ai postcheck =
case Types.Backend.verifyKeyContent backend of
@ -546,14 +509,6 @@ badContent key = do
dest <- moveBad key
return $ "moved to " ++ dest
{- Bad content is left where it is, but we touch the file, so it'll be
- committed to a new key. -}
badContentDirect :: FilePath -> Key -> Annex String
badContentDirect file key = do
void $ liftIO $ catchMaybeIO $ touchFile file
logStatus key InfoMissing
return "left in place for you to examine"
{- Bad content is dropped from the remote. We have downloaded a copy
- from the remote to a temp file already (in some cases, it's just a
- symlink to a file in the remote). To avoid any further data loss,
@ -714,16 +669,13 @@ isKeyUnlockedThin KeyPresent = False
isKeyUnlockedThin KeyMissing = False
getKeyStatus :: Key -> Annex KeyStatus
getKeyStatus key = ifM isDirect
( return KeyUnlockedThin
, catchDefaultIO KeyMissing $ do
afs <- not . null <$> Database.Keys.getAssociatedFiles key
obj <- calcRepo $ gitAnnexLocation key
multilink <- ((> 1) . linkCount <$> liftIO (getFileStatus obj))
return $ if multilink && afs
then KeyUnlockedThin
else KeyPresent
)
getKeyStatus key = catchDefaultIO KeyMissing $ do
afs <- not . null <$> Database.Keys.getAssociatedFiles key
obj <- calcRepo $ gitAnnexLocation key
multilink <- ((> 1) . linkCount <$> liftIO (getFileStatus obj))
return $ if multilink && afs
then KeyUnlockedThin
else KeyPresent
getKeyFileStatus :: Key -> FilePath -> Annex KeyStatus
getKeyFileStatus key file = do

View file

@ -155,7 +155,6 @@ data FuzzAction
= FuzzAdd FuzzFile
| FuzzDelete FuzzFile
| FuzzMove FuzzFile FuzzFile
| FuzzModify FuzzFile
| FuzzDeleteDir FuzzDir
| FuzzMoveDir FuzzDir FuzzDir
| FuzzPause Delay
@ -166,7 +165,6 @@ instance Arbitrary FuzzAction where
[ (50, FuzzAdd <$> arbitrary)
, (50, FuzzDelete <$> arbitrary)
, (10, FuzzMove <$> arbitrary <*> arbitrary)
, (10, FuzzModify <$> arbitrary)
, (10, FuzzDeleteDir <$> arbitrary)
, (10, FuzzMoveDir <$> arbitrary <*> arbitrary)
, (10, FuzzPause <$> arbitrary)
@ -180,9 +178,6 @@ runFuzzAction (FuzzAdd (FuzzFile f)) = liftIO $ do
runFuzzAction (FuzzDelete (FuzzFile f)) = liftIO $ nukeFile f
runFuzzAction (FuzzMove (FuzzFile src) (FuzzFile dest)) = liftIO $
rename src dest
runFuzzAction (FuzzModify (FuzzFile f)) = whenM isDirect $ liftIO $ do
n <- getStdRandom random :: IO Int
appendFile f $ show n ++ "\n"
runFuzzAction (FuzzDeleteDir (FuzzDir d)) = liftIO $
removeDirectoryRecursive d
runFuzzAction (FuzzMoveDir (FuzzDir src) (FuzzDir dest)) = liftIO $
@ -216,9 +211,6 @@ genFuzzAction = do
FuzzDeleteDir _ -> do
d <- liftIO existingDir
maybe genFuzzAction (return . FuzzDeleteDir) d
FuzzModify _ -> do
f <- liftIO $ existingFile 0 ""
maybe genFuzzAction (return . FuzzModify) f
FuzzPause _ -> return tmpl
existingFile :: Int -> FilePath -> IO (Maybe FuzzFile)

View file

@ -31,7 +31,6 @@ import Logs.Trust
import Logs.Location
import Annex.NumCopies
import Remote
import Config
import Git.Config (boolConfig)
import qualified Git.LsTree as LsTree
import Utility.Percentage
@ -318,12 +317,9 @@ showStat s = maybe noop calc =<< s
repository_mode :: Stat
repository_mode = simpleStat "repository mode" $ lift $
ifM isDirect
( return "direct"
, ifM (fromRepo Git.repoIsLocalBare)
( return "bare"
, return "indirect"
)
ifM (fromRepo Git.repoIsLocalBare)
( return "bare"
, return "indirect"
)
repo_list :: TrustLevel -> Stat

View file

@ -23,7 +23,7 @@ import Logs.Location
import Git.FilePath
cmd :: Command
cmd = notDirect $ withGlobalOptions [jsonOptions, annexedMatchingOptions] $
cmd = withGlobalOptions [jsonOptions, annexedMatchingOptions] $
command "lock" SectionCommon
"undo unlock command"
paramPaths (withParams seek)

View file

@ -20,7 +20,7 @@ import Logs.Web
import Utility.Metered
cmd :: Command
cmd = notDirect $ withGlobalOptions [annexedMatchingOptions] $
cmd = withGlobalOptions [annexedMatchingOptions] $
command "migrate" SectionUtility
"switch data to different backend"
paramPaths (withParams seek)

View file

@ -27,7 +27,6 @@ import Utility.Hash
import Utility.Tmp
import Utility.Tmp.Dir
import Utility.Process.Transcript
import Config
import Data.Char
import qualified Data.ByteString.Lazy.UTF8 as B8
@ -128,8 +127,6 @@ send ups fs = do
-- In a direct mode repository, the annex objects do not have
-- the names of keys, and would have to be copied, which is too
-- expensive.
whenM isDirect $
giveup "Sorry, multicast send cannot be done from a direct mode repository."
starting "sending files" (ActionItemOther Nothing) $
withTmpFile "send" $ \t h -> do
fs' <- seekHelper LsFiles.inRepo =<< workTreeItems fs

View file

@ -10,11 +10,9 @@
module Command.PreCommit where
import Command
import Config
import qualified Command.Add
import qualified Command.Fix
import qualified Command.Smudge
import Annex.Direct
import Annex.Hook
import Annex.Link
import Annex.View
@ -38,50 +36,45 @@ cmd = command "pre-commit" SectionPlumbing
(withParams seek)
seek :: CmdParams -> CommandSeek
seek ps = lockPreCommitHook $ ifM isDirect
( do
-- update direct mode mappings for committed files
withWords (commandAction . startDirect) ps
runAnnexHook preCommitAnnexHook
, do
ifM (not <$> versionSupportsUnlockedPointers <&&> liftIO Git.haveFalseIndex)
( do
(fs, cleanup) <- inRepo $ Git.typeChangedStaged ps
whenM (anyM isOldUnlocked fs) $
giveup "Cannot make a partial commit with unlocked annexed files. You should `git annex add` the files you want to commit, and then run git commit."
void $ liftIO cleanup
, do
l <- workTreeItems ps
-- fix symlinks to files being committed
flip withFilesToBeCommitted l $ \f -> commandAction $
maybe stop (Command.Fix.start Command.Fix.FixSymlinks f)
=<< isAnnexLink f
ifM versionSupportsUnlockedPointers
-- after a merge conflict or git
-- cherry-pick or stash, pointer
-- files in the worktree won't
-- be populated, so populate them
-- here
( Command.Smudge.updateSmudged
-- When there's a false index,
-- restaging the files won't work.
. Restage =<< liftIO Git.haveFalseIndex
-- inject unlocked files into the annex
-- (not needed when repo version uses
-- unlocked pointer files)
, withFilesOldUnlockedToBeCommitted (commandAction . startInjectUnlocked) l
)
)
runAnnexHook preCommitAnnexHook
-- committing changes to a view updates metadata
mv <- currentView
case mv of
Nothing -> noop
Just v -> withViewChanges
(addViewMetaData v)
(removeViewMetaData v)
)
seek ps = lockPreCommitHook $ do
ifM (not <$> versionSupportsUnlockedPointers <&&> liftIO Git.haveFalseIndex)
( do
(fs, cleanup) <- inRepo $ Git.typeChangedStaged ps
whenM (anyM isOldUnlocked fs) $
giveup "Cannot make a partial commit with unlocked annexed files. You should `git annex add` the files you want to commit, and then run git commit."
void $ liftIO cleanup
, do
l <- workTreeItems ps
-- fix symlinks to files being committed
flip withFilesToBeCommitted l $ \f -> commandAction $
maybe stop (Command.Fix.start Command.Fix.FixSymlinks f)
=<< isAnnexLink f
ifM versionSupportsUnlockedPointers
-- after a merge conflict or git
-- cherry-pick or stash, pointer
-- files in the worktree won't
-- be populated, so populate them
-- here
( Command.Smudge.updateSmudged
-- When there's a false index,
-- restaging the files won't work.
. Restage =<< liftIO Git.haveFalseIndex
-- inject unlocked files into the annex
-- (not needed when repo version uses
-- unlocked pointer files)
, withFilesOldUnlockedToBeCommitted (commandAction . startInjectUnlocked) l
)
)
runAnnexHook preCommitAnnexHook
-- committing changes to a view updates metadata
mv <- currentView
case mv of
Nothing -> noop
Just v -> withViewChanges
(addViewMetaData v)
(removeViewMetaData v)
startInjectUnlocked :: FilePath -> CommandStart
startInjectUnlocked f = startingCustomOutput (ActionItemOther Nothing) $ do
@ -89,10 +82,6 @@ startInjectUnlocked f = startingCustomOutput (ActionItemOther Nothing) $ do
error $ "failed to add " ++ f ++ "; canceling commit"
next $ return True
startDirect :: [String] -> CommandStart
startDirect _ = startingCustomOutput (ActionItemOther Nothing) $
next preCommitDirect
addViewMetaData :: View -> ViewedFile -> Key -> CommandStart
addViewMetaData v f k = starting "metadata" (mkActionItem (k, f)) $
next $ changeMetaData k $ fromView v f

View file

@ -21,11 +21,10 @@ import Annex.InodeSentinal
import Utility.InodeCache
cmd :: Command
cmd = notDirect $
command "rekey" SectionPlumbing
"change keys used for files"
(paramRepeating $ paramPair paramPath paramKey)
(seek <$$> optParser)
cmd = command "rekey" SectionPlumbing
"change keys used for files"
(paramRepeating $ paramPair paramPath paramKey)
(seek <$$> optParser)
data ReKeyOptions = ReKeyOptions
{ reKeyThese :: CmdParams

View file

@ -15,7 +15,7 @@ import Command.FromKey (mkKey)
import qualified Remote
cmd :: Command
cmd = notDirect $ notBareRepo $
cmd = notBareRepo $
command "registerurl"
SectionPlumbing "registers an url for a key"
(paramPair paramKey paramUrl)

View file

@ -8,11 +8,7 @@
module Command.Status where
import Command
import Annex.CatFile
import Annex.Content.Direct
import Config
import Git.Status
import qualified Git.Ref
import Git.FilePath
cmd :: Command
@ -42,10 +38,7 @@ seek o = withWords (commandAction . start o) (statusFiles o)
start :: StatusOptions -> [FilePath] -> CommandStart
start o locs = do
(l, cleanup) <- inRepo $ getStatus ps locs
getstatus <- ifM isDirect
( return (maybe (pure Nothing) statusDirect . simplifiedStatus)
, return (pure . simplifiedStatus)
)
let getstatus = pure . simplifiedStatus
forM_ l $ \s -> maybe noop displayStatus =<< getstatus s
ifM (liftIO cleanup)
( stop
@ -71,38 +64,3 @@ displayStatus s = do
f <- liftIO $ relPathCwdToFile absf
unlessM (showFullJSON $ JSONChunk [("status", [c]), ("file", f)]) $
liftIO $ putStrLn $ [c] ++ " " ++ f
-- Git thinks that present direct mode files are typechanged.
-- (On crippled filesystems, git instead thinks they're modified.)
-- Check their content to see if they are modified or not.
statusDirect :: Status -> Annex (Maybe Status)
statusDirect (TypeChanged t) = statusDirect' t
statusDirect s@(Modified t) = ifM crippledFileSystem
( statusDirect' t
, pure (Just s)
)
statusDirect s = pure (Just s)
statusDirect' :: TopFilePath -> Annex (Maybe Status)
statusDirect' t = do
absf <- fromRepo $ fromTopFilePath t
f <- liftIO $ relPathCwdToFile absf
v <- liftIO (catchMaybeIO $ getFileStatus f)
case v of
Nothing -> return $ Just $ Deleted t
Just s
| not (isSymbolicLink s) ->
checkkey f s =<< catKeyFile f
| otherwise -> Just <$> checkNew f t
where
checkkey f s (Just k) = ifM (sameFileStatus k f s)
( return Nothing
, return $ Just $ Modified t
)
checkkey f _ Nothing = Just <$> checkNew f t
checkNew :: FilePath -> TopFilePath -> Annex Status
checkNew f t = ifM (isJust <$> catObjectDetails (Git.Ref.fileRef f))
( return (Modified t)
, return (Untracked t)
)

View file

@ -30,7 +30,6 @@ import qualified Annex
import qualified Annex.Branch
import qualified Remote
import qualified Types.Remote as Remote
import Annex.Direct
import Annex.Hook
import qualified Git.Command
import qualified Git.LsFiles as LsFiles
@ -250,7 +249,7 @@ merge currbranch mergeconfig resolvemergeoverride commitmode tomerge = case curr
ResolveMergeOverride False -> return False
syncBranch :: Git.Branch -> Git.Branch
syncBranch = Git.Ref.underBase "refs/heads/synced" . fromDirectBranch . fromAdjustedBranch
syncBranch = Git.Ref.underBase "refs/heads/synced" . fromAdjustedBranch
remoteBranch :: Remote -> Git.Ref -> Git.Ref
remoteBranch remote = Git.Ref.underBase $ "refs/remotes/" ++ Remote.name remote
@ -286,20 +285,14 @@ commit :: SyncOptions -> CommandStart
commit o = stopUnless shouldcommit $ starting "commit" (ActionItemOther Nothing) $ do
commitmessage <- maybe commitMsg return (messageOption o)
Annex.Branch.commit =<< Annex.Branch.commitMessage
next $ ifM isDirect
( do
void stageDirect
void preCommitDirect
commitStaged Git.Branch.ManualCommit commitmessage
, do
showOutput
void $ inRepo $ Git.Branch.commitCommand Git.Branch.ManualCommit
[ Param "-a"
, Param "-m"
, Param commitmessage
]
return True
)
next $ do
showOutput
void $ inRepo $ Git.Branch.commitCommand Git.Branch.ManualCommit
[ Param "-a"
, Param "-m"
, Param commitmessage
]
return True
where
shouldcommit = pure (commitOption o)
<||> (pure (not (noCommitOption o)) <&&> getGitConfigVal annexAutoCommit)
@ -378,12 +371,6 @@ updateBranches (Just branch, madj) = do
-- Update the sync branch to match the new state of the branch
inRepo $ updateBranch (syncBranch branch) branch
-- In direct mode, we're operating on some special direct mode
-- branch, rather than the intended branch, so update the intended
-- branch.
whenM isDirect $
inRepo $ updateBranch (fromDirectBranch branch) branch
updateBranch :: Git.Branch -> Git.Branch -> Git.Repo -> IO ()
updateBranch syncbranch updateto g =
unlessM go $ giveup $ "failed to update " ++ Git.fromRef syncbranch
@ -449,7 +436,7 @@ mergeRemote remote currbranch mergeconfig resolvemergeoverride = ifM isBareRepo
(mapM (merge currbranch mergeconfig resolvemergeoverride Git.Branch.ManualCommit . remoteBranch remote) =<< getlist)
tomerge = filterM (changed remote)
branchlist Nothing = []
branchlist (Just branch) = [fromDirectBranch (fromAdjustedBranch branch), syncBranch branch]
branchlist (Just branch) = [fromAdjustedBranch branch, syncBranch branch]
pushRemote :: SyncOptions -> Remote -> CurrBranch -> CommandStart
pushRemote _o _remote (Nothing, _) = stop
@ -540,7 +527,7 @@ pushBranch remote branch g = directpush `after` annexpush `after` syncpush
-- receive.denyCurrentBranch=updateInstead -- the user
-- will want to see that one.
let p = flip Git.Command.gitCreateProcess g $ pushparams
[ Git.fromRef $ Git.Ref.base $ fromDirectBranch $ fromAdjustedBranch branch ]
[ Git.fromRef $ Git.Ref.base $ fromAdjustedBranch branch ]
(transcript, ok) <- processTranscript' p Nothing
when (not ok && not ("denyCurrentBranch" `isInfixOf` transcript)) $
hPutStr stderr transcript

View file

@ -8,11 +8,9 @@
module Command.Unannex where
import Command
import Config
import qualified Annex
import Annex.Content
import Annex.Perms
import Annex.Content.Direct
import Annex.Version
import qualified Git.Command
import qualified Git.Branch
@ -34,7 +32,7 @@ seek ps = wrapUnannex $
(withFilesInGit $ commandAction . whenAnnexed start) =<< workTreeItems ps
wrapUnannex :: Annex a -> Annex a
wrapUnannex a = ifM (versionSupportsUnlockedPointers <||> isDirect)
wrapUnannex a = ifM versionSupportsUnlockedPointers
( a
{- Run with the pre-commit hook disabled, to avoid confusing
- behavior if an unannexed file is added back to git as
@ -68,13 +66,10 @@ wrapUnannex a = ifM (versionSupportsUnlockedPointers <||> isDirect)
start :: FilePath -> Key -> CommandStart
start file key = stopUnless (inAnnex key) $
starting "unannex" (mkActionItem (key, file)) $
ifM isDirect
( performDirect file key
, performIndirect file key
)
perform file key
performIndirect :: FilePath -> Key -> CommandPerform
performIndirect file key = do
perform :: FilePath -> Key -> CommandPerform
perform file key = do
liftIO $ removeFile file
inRepo $ Git.Command.run
[ Param "rm"
@ -84,10 +79,10 @@ performIndirect file key = do
, Param "--"
, File file
]
next $ cleanupIndirect file key
next $ cleanup file key
cleanupIndirect :: FilePath -> Key -> CommandCleanup
cleanupIndirect file key = do
cleanup :: FilePath -> Key -> CommandCleanup
cleanup file key = do
Database.Keys.removeAssociatedFile key =<< inRepo (toTopFilePath file)
src <- calcRepo $ gitAnnexLocation key
ifM (Annex.getState Annex.fast)
@ -112,28 +107,3 @@ cleanupIndirect file key = do
( return True
, copyfrom src
)
performDirect :: FilePath -> Key -> CommandPerform
performDirect file key = do
-- --force is needed when the file is not committed
inRepo $ Git.Command.run
[ Param "rm"
, Param "--cached"
, Param "--force"
, Param "--quiet"
, Param "--"
, File file
]
next $ cleanupDirect file key
{- The direct mode file is not touched during unannex, so the content
- is already where it needs to be, so this does not need to do anything
- except remove it from the associated file map (which also updates
- the location log if this was the last copy), and, if this was the last
- associated file, remove the inode cache. -}
cleanupDirect :: FilePath -> Key -> CommandCleanup
cleanupDirect file key = do
fs <- removeAssociatedFile key file
when (null fs) $
removeInodeCache key
return True

View file

@ -9,7 +9,6 @@ module Command.Undo where
import Command
import Config
import Annex.Direct
import Annex.CatFile
import Git.DiffTree
import Git.FilePath
@ -37,9 +36,7 @@ seek ps = do
-- Committing staged changes before undo allows later
-- undoing the undo. It would be nicer to only commit staged
-- changes to the specified files, rather than all staged changes,
-- but that is difficult to do; a partial git-commit can't be done
-- in direct mode.
-- changes to the specified files, rather than all staged changes.
void $ Command.Sync.commitStaged Git.Branch.ManualCommit
"commit before undo"
@ -68,16 +65,10 @@ perform p = do
forM_ removals $ \di -> do
f <- mkrel di
whenM isDirect $
maybe noop (`removeDirect` f)
=<< catKey (srcsha di)
liftIO $ nukeFile f
forM_ adds $ \di -> do
f <- mkrel di
inRepo $ Git.run [Param "checkout", Param "--", File f]
whenM isDirect $
maybe noop (`toDirect` f)
=<< catKey (dstsha di)
next $ liftIO cleanup

View file

@ -25,9 +25,8 @@ editcmd :: Command
editcmd = mkcmd "edit" "same as unlock"
mkcmd :: String -> String -> Command
mkcmd n d = notDirect $
withGlobalOptions [jsonOptions, annexedMatchingOptions] $
command n SectionCommon d paramPaths (withParams seek)
mkcmd n d = withGlobalOptions [jsonOptions, annexedMatchingOptions] $
command n SectionCommon d paramPaths (withParams seek)
seek :: CmdParams -> CommandSeek
seek ps = withFilesInGit (commandAction . whenAnnexed start) =<< workTreeItems ps

View file

@ -12,7 +12,7 @@ import Annex.View
import Command.View (checkoutViewBranch)
cmd :: Command
cmd = notBareRepo $ notDirect $
cmd = notBareRepo $
command "vadd" SectionMetaData
"add subdirs to current view"
(paramRepeating "FIELD=GLOB")

View file

@ -14,7 +14,7 @@ import Logs.View
import Command.View (checkoutViewBranch)
cmd :: Command
cmd = notBareRepo $ notDirect $
cmd = notBareRepo $
command "vcycle" SectionMetaData
"switch view to next layout"
paramNothing (withParams seek)

View file

@ -12,7 +12,7 @@ import Annex.View
import Command.View (paramView, checkoutViewBranch)
cmd :: Command
cmd = notBareRepo $ notDirect $
cmd = notBareRepo $
command "vfilter" SectionMetaData "filter current view"
paramView (withParams seek)

View file

@ -16,7 +16,7 @@ import Logs.View
import Command.View (checkoutViewBranch)
cmd :: Command
cmd = notBareRepo $ notDirect $
cmd = notBareRepo $
command "vpop" SectionMetaData "switch back to previous view"
paramNumber (withParams seek)

View file

@ -20,7 +20,7 @@ import Annex.View
import Logs.View
cmd :: Command
cmd = notBareRepo $ notDirect $
cmd = notBareRepo $
command "view" SectionMetaData "enter a view branch"
paramView (withParams seek)

View file

@ -8,16 +8,8 @@
module Upgrade.V4 where
import Annex.Common
import Config
import Annex.Direct
{- Direct mode only upgrade. v4 to v5 indirect update is a no-op -}
{- Was only used for direct mode upgrade. v4 to v5 indirect update is a no-op,
- and direct mode is no longer supported, so nothing needs to be done. -}
upgrade :: Bool -> Annex Bool
upgrade automatic = ifM isDirect
( do
unless automatic $
showAction "v4 to v5"
setDirect True
return True
, return True
)
upgrade _automatic = return True

View file

@ -13,11 +13,11 @@ import Config
import Config.Smudge
import Annex.InodeSentinal
import Annex.Link
import Annex.Direct
import Annex.Content
import Annex.CatFile
import Annex.WorkTree
import qualified Database.Keys
import qualified Annex.Direct as Direct
import qualified Annex.Content.Direct as Direct
import qualified Git
import qualified Git.LsFiles
@ -48,7 +48,7 @@ upgrade automatic = do
-- locking down files as they were added. In v6, it's used more
-- extensively, so make sure it exists, since old repos that didn't
-- use direct mode may not have created it.
unlessM (isDirect) $
unlessM isDirect $
createInodeSentinalFile True
return True
@ -62,12 +62,12 @@ convertDirect automatic = do
{- Since upgrade from direct mode changes how files
- are represented in git, by checking out an adjusted
- branch, commit any changes in the work tree first. -}
whenM stageDirect $ do
whenM Direct.stageDirect $ do
unless automatic $
showAction "committing first"
upgradeDirectCommit automatic
"commit before upgrade to annex.version 6"
setDirect False
Direct.setIndirect
cur <- fromMaybe (error "Somehow no branch is checked out")
<$> inRepo Git.Branch.current
upgradeDirectWorkTree