From 9f6bd6cc052c1d42157f48cfe55e714c5263c825 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Wed, 8 Jul 2020 15:36:35 -0400 Subject: [PATCH] add inRepoDetails planned to use for an optimisation most things using stagedDetails were not expecting to get dup files in a conflicted merge and deal with them, so converted them to use inRepoDetails. --- Annex/View.hs | 4 +-- Git/LsFiles.hs | 25 ++++++++++++++----- Logs/Web.hs | 4 +-- Upgrade/V5.hs | 4 +-- ...logs_for_speed_with_cat-file_--buffer.mdwn | 7 ++---- 5 files changed, 27 insertions(+), 17 deletions(-) diff --git a/Annex/View.hs b/Annex/View.hs index 19c593858e..fecee7395f 100644 --- a/Annex/View.hs +++ b/Annex/View.hs @@ -345,11 +345,11 @@ narrowView = applyView' viewedFileReuse getViewedFileMetaData applyView' :: MkViewedFile -> (FilePath -> MetaData) -> View -> Annex Git.Branch applyView' mkviewedfile getfilemetadata view = do top <- fromRepo Git.repoPath - (l, clean) <- inRepo $ Git.LsFiles.stagedDetails [top] + (l, clean) <- inRepo $ Git.LsFiles.inRepoDetails [] [top] liftIO . nukeFile =<< fromRepo gitAnnexViewIndex viewg <- withViewIndex gitRepo withUpdateIndex viewg $ \uh -> do - forM_ l $ \(f, sha, mode, _) -> do + forM_ l $ \(f, sha, mode) -> do topf <- inRepo (toTopFilePath f) go uh topf sha (toTreeItemType mode) =<< lookupFile f liftIO $ void clean diff --git a/Git/LsFiles.hs b/Git/LsFiles.hs index d74c00121f..d0c79d6a94 100644 --- a/Git/LsFiles.hs +++ b/Git/LsFiles.hs @@ -8,6 +8,7 @@ module Git.LsFiles ( Options(..), inRepo, + inRepoDetails, inRepoOrBranch, notInRepo, notInRepoIncludingEmptyDirectories, @@ -67,6 +68,9 @@ guardSafeForLsFiles r a data Options = ErrorUnmatch +opParam :: Options -> CommandParam +opParam ErrorUnmatch = Param "--error-unmatch" + {- Lists files that are checked into git's index at the specified paths. - With no paths, all files are listed. -} @@ -79,9 +83,18 @@ inRepo' ps os l repo = guardSafeForLsFiles repo $ pipeNullSplit' params repo params = Param "ls-files" : Param "-z" : - map op os ++ ps ++ + map opParam os ++ ps ++ (Param "--" : map (File . fromRawFilePath) l) - op ErrorUnmatch = Param "--error-unmatch" + +{- Lists the same files inRepo does, but with sha and mode. -} +inRepoDetails :: [Options] -> [RawFilePath] -> Repo -> IO ([(RawFilePath, Sha, FileMode)], IO Bool) +inRepoDetails = stagedDetails' parser . map opParam + where + parser s = case parseStagedDetails s of + Just (file, sha, mode, stagenum) + | stagenum == usualStageNum || stagenum == mergeConflictHeadStageNum -> + Just (file, sha, mode) + _ -> Nothing {- Files that are checked into the index or have been committed to a - branch. -} @@ -158,12 +171,12 @@ mergeConflictHeadStageNum = 2 - more than once with different stage numbers. -} stagedDetails :: [RawFilePath] -> Repo -> IO ([StagedDetails], IO Bool) -stagedDetails = stagedDetails' [] +stagedDetails = stagedDetails' parseStagedDetails [] -stagedDetails' :: [CommandParam] -> [RawFilePath] -> Repo -> IO ([StagedDetails], IO Bool) -stagedDetails' ps l repo = guardSafeForLsFiles repo $ do +stagedDetails' :: (S.ByteString -> Maybe t) -> [CommandParam] -> [RawFilePath] -> Repo -> IO ([t], IO Bool) +stagedDetails' parser ps l repo = guardSafeForLsFiles repo $ do (ls, cleanup) <- pipeNullSplit' params repo - return (mapMaybe parseStagedDetails ls, cleanup) + return (mapMaybe parser ls, cleanup) where params = Param "ls-files" : Param "--stage" : Param "-z" : ps ++ Param "--" : map (File . fromRawFilePath) l diff --git a/Logs/Web.hs b/Logs/Web.hs index 77edc43358..5c0ee9a269 100644 --- a/Logs/Web.hs +++ b/Logs/Web.hs @@ -94,12 +94,12 @@ knownUrls = do Annex.Branch.commit =<< Annex.Branch.commitMessage Annex.Branch.withIndex $ do top <- fromRepo Git.repoPath - (l, cleanup) <- inRepo $ Git.LsFiles.stagedDetails [top] + (l, cleanup) <- inRepo $ Git.LsFiles.inRepoDetails [] [top] r <- mapM getkeyurls l void $ liftIO cleanup return $ concat r where - getkeyurls (f, s, _, _) = case urlLogFileKey f of + getkeyurls (f, s, _) = case urlLogFileKey f of Just k -> zip (repeat k) <$> geturls s Nothing -> return [] geturls logsha = diff --git a/Upgrade/V5.hs b/Upgrade/V5.hs index 31463d187e..45351d4f4d 100644 --- a/Upgrade/V5.hs +++ b/Upgrade/V5.hs @@ -110,11 +110,11 @@ convertDirect = do upgradeDirectWorkTree :: Annex () upgradeDirectWorkTree = do top <- fromRepo Git.repoPath - (l, clean) <- inRepo $ Git.LsFiles.stagedDetails [top] + (l, clean) <- inRepo $ Git.LsFiles.inRepoDetails [] [top] forM_ l go void $ liftIO clean where - go (f, _sha, mode, _stagenum) | isSymLink mode = do + go (f, _sha, mode) | isSymLink mode = do -- Cannot use lookupFile here, as we're in between direct -- mode and v6. mk <- catKeyFile f diff --git a/doc/todo/precache_logs_for_speed_with_cat-file_--buffer.mdwn b/doc/todo/precache_logs_for_speed_with_cat-file_--buffer.mdwn index 7eb402e641..5030991172 100644 --- a/doc/todo/precache_logs_for_speed_with_cat-file_--buffer.mdwn +++ b/doc/todo/precache_logs_for_speed_with_cat-file_--buffer.mdwn @@ -13,10 +13,7 @@ Probably that extra round trip means the performance improvement will not be as good as --all's was, but it could still be significant. > Actually, the key lookup could use the same --buffer trick! -> Although this would need a way to use git ls-files to get the sha of each -> file, and the only way I can find is --stage, which lists the file -> repeatedly when there's a merge conflict. If that can be finessed somehow, -> pass the file sha through cat-file to get key, and then pass the location -> log for the key through cat-file to precache logs. +> Use inRepoDetails to list files and shas, pass through cat-file to get keys, +> and then pass the location log for each key through cat-file to precache logs. --[[Joey]]