summaryrefslogtreecommitdiff
path: root/Command/Unused.hs
diff options
context:
space:
mode:
Diffstat (limited to 'Command/Unused.hs')
-rw-r--r--Command/Unused.hs71
1 files changed, 36 insertions, 35 deletions
diff --git a/Command/Unused.hs b/Command/Unused.hs
index 0a060aae6..844cdb19b 100644
--- a/Command/Unused.hs
+++ b/Command/Unused.hs
@@ -21,21 +21,22 @@ import Common.Annex
import Command
import Logs.Unused
import Annex.Content
-import Utility.FileMode
import Logs.Location
import Logs.Transfer
import qualified Annex
import qualified Git
import qualified Git.Command
import qualified Git.Ref
+import qualified Git.Branch
import qualified Git.LsFiles as LsFiles
-import qualified Git.LsTree as LsTree
+import qualified Git.DiffTree as DiffTree
import qualified Backend
import qualified Remote
import qualified Annex.Branch
import qualified Option
import Annex.CatFile
import Types.Key
+import Git.FilePath
def :: [Command]
def = [withOptions [fromOption] $ command "unused" paramNothing seek
@@ -241,7 +242,7 @@ withKeysReferenced' mdir initial a = do
( return ([], return True)
, do
top <- fromRepo Git.repoPath
- inRepo $ LsFiles.inRepo [top]
+ inRepo $ LsFiles.allFiles [top]
)
Just dir -> inRepo $ LsFiles.inRepo [dir]
go v [] = return v
@@ -255,35 +256,47 @@ withKeysReferenced' mdir initial a = do
withKeysReferencedInGit :: (Key -> Annex ()) -> Annex ()
withKeysReferencedInGit a = do
- rs <- relevantrefs <$> showref
- forM_ rs (withKeysReferencedInGitRef a)
+ current <- inRepo Git.Branch.currentUnsafe
+ shaHead <- maybe (return Nothing) (inRepo . Git.Ref.sha) current
+ showref >>= mapM_ (withKeysReferencedInGitRef a) .
+ relevantrefs (shaHead, current)
where
showref = inRepo $ Git.Command.pipeReadStrict [Param "show-ref"]
- relevantrefs = map (Git.Ref . snd) .
- nubBy uniqref .
+ relevantrefs headRef = addHead headRef .
filter ourbranches .
- map (separate (== ' ')) . lines
- uniqref (x, _) (y, _) = x == y
+ map (separate (== ' ')) .
+ lines
+ nubRefs = map (Git.Ref . snd) . nubBy (\(x, _) (y, _) -> x == y)
ourbranchend = '/' : show Annex.Branch.name
ourbranches (_, b) = not (ourbranchend `isSuffixOf` b)
&& not ("refs/synced/" `isPrefixOf` b)
-
+ addHead headRef refs = case headRef of
+ -- if HEAD diverges from all branches (except the branch it
+ -- points to), run the actions on staged keys (and keys
+ -- that are only present in the work tree if the repo is
+ -- non bare)
+ (Just (Git.Ref x), Just (Git.Ref b))
+ | all (\(x',b') -> x /= x' || b == b') refs ->
+ Git.Ref.headRef
+ : nubRefs (filter ((/= x) . fst) refs)
+ _ -> nubRefs refs
+
+{- Runs an action on keys referenced in the given Git reference which
+ - differ from those referenced in the index. -}
withKeysReferencedInGitRef :: (Key -> Annex ()) -> Git.Ref -> Annex ()
withKeysReferencedInGitRef a ref = do
showAction $ "checking " ++ Git.Ref.describe ref
- go <=< inRepo $ LsTree.lsTree ref
+ bare <- isBareRepo
+ (ts,clean) <- inRepo $ if bare
+ then DiffTree.diffIndex ref
+ else DiffTree.diffWorkTree ref
+ let lookAtWorkingTree = not bare && ref == Git.Ref.headRef
+ forM_ ts $ tKey lookAtWorkingTree >=> maybe noop a
+ liftIO $ void clean
where
- go [] = noop
- go (l:ls)
- | isSymLink (LsTree.mode l) = do
- content <- encodeW8 . L.unpack
- <$> catFile ref (LsTree.file l)
- case fileKey (takeFileName content) of
- Nothing -> go ls
- Just k -> do
- a k
- go ls
- | otherwise = go ls
+ tKey True = fmap fst <$$> Backend.lookupFile . getTopFilePath . DiffTree.file
+ tKey False = fileKey . takeFileName . encodeW8 . L.unpack <$$>
+ catFile ref . getTopFilePath . DiffTree.file
{- Looks in the specified directory for bad/tmp keys, and returns a list
- of those that might still have value, or might be stale and removable.
@@ -292,7 +305,7 @@ withKeysReferencedInGitRef a ref = do
-}
staleKeysPrune :: (Git.Repo -> FilePath) -> Bool -> Annex [Key]
staleKeysPrune dirspec nottransferred = do
- contents <- staleKeys dirspec
+ contents <- dirKeys dirspec
dups <- filterM inAnnex contents
let stale = contents `exclude` dups
@@ -307,18 +320,6 @@ staleKeysPrune dirspec nottransferred = do
return $ filter (`S.notMember` inprogress) stale
else return stale
-staleKeys :: (Git.Repo -> FilePath) -> Annex [Key]
-staleKeys dirspec = do
- dir <- fromRepo dirspec
- ifM (liftIO $ doesDirectoryExist dir)
- ( do
- contents <- liftIO $ getDirectoryContents dir
- files <- liftIO $ filterM doesFileExist $
- map (dir </>) contents
- return $ mapMaybe (fileKey . takeFileName) files
- , return []
- )
-
data UnusedMaps = UnusedMaps
{ unusedMap :: UnusedMap
, unusedBadMap :: UnusedMap