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:
parent
adb89ee71b
commit
689d1fcc92
37 changed files with 193 additions and 799 deletions
|
@ -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. -}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
340
Annex/Direct.hs
340
Annex/Direct.hs
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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."
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
120
Command/Fsck.hs
120
Command/Fsck.hs
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue