From 586db7f06dd81ab35cba331396d6014bd15f104e Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Mon, 26 Aug 2019 16:34:07 -0400 Subject: [PATCH] Avoid making a commit when upgrading from direct mode to v7 Three reasons: * Committing as part of an upgrade is very unusual and unexpected. * The commit was failing with a weird error message when done during an automatic upgrade. * Let me remove more of that sweet^Whorrible direct mode code. --- Annex/Direct.hs | 102 ------------------------------------------------ CHANGELOG | 1 + Upgrade/V5.hs | 27 +++---------- 3 files changed, 7 insertions(+), 123 deletions(-) diff --git a/Annex/Direct.hs b/Annex/Direct.hs index 7b02dd1f26..c61ae856cb 100644 --- a/Annex/Direct.hs +++ b/Annex/Direct.hs @@ -9,118 +9,16 @@ module Annex.Direct ( switchHEADBack, - stageDirect, setIndirect, ) where import Annex.Common import qualified Annex -import qualified Git -import qualified Git.LsFiles import qualified Git.Config import qualified Git.Ref import qualified Git.Branch import Git.Types import Config -import Annex.CatFile -import qualified Annex.Queue -import Logs.Location -import Backend -import Types.KeySource -import Annex.Content.Direct -import Annex.Link -import Utility.InodeCache -import Annex.InodeSentinal -import Utility.Metered - -{- Uses git ls-files to find files that need to be committed, and stages - - them into the index. Returns True if some changes were staged. -} -stageDirect :: Annex Bool -stageDirect = do - Annex.Queue.flush - top <- fromRepo Git.repoPath - (l, cleanup) <- inRepo $ Git.LsFiles.stagedOthersDetails [top] - forM_ l go - void $ liftIO cleanup - staged <- Annex.Queue.size - Annex.Queue.flush - return $ staged /= 0 - where - {- Determine what kind of modified or deleted file this is, as - - efficiently as we can, by getting any key that's associated - - with it in git, as well as its stat info. -} - go (file, Just sha, Just _mode) = withTSDelta $ \delta -> do - shakey <- catKey sha - mstat <- liftIO $ catchMaybeIO $ getSymbolicLinkStatus file - mcache <- liftIO $ maybe (pure Nothing) (toInodeCache delta file) mstat - filekey <- isAnnexLink file >>= \case - Just k -> return (Just k) - -- v7 unlocked pointer file - Nothing -> liftIO (isPointerFile file) - case (shakey, filekey, mstat, mcache) of - (_, Just key, _, _) - | shakey == filekey -> noop - {- A changed symlink. -} - | otherwise -> stageannexlink file key - (Just key, _, _, Just cache) -> do - {- All direct mode files will show as - - modified, so compare the cache to see if - - it really was. -} - oldcache <- recordedInodeCache key - case oldcache of - [] -> modifiedannexed file key cache - _ -> unlessM (elemInodeCaches cache oldcache) $ - modifiedannexed file key cache - (Just key, _, Nothing, _) -> deletedannexed file key - (Nothing, _, Nothing, _) -> deletegit file - (_, _, Just _, _) -> addgit file - go _ = noop - - modifiedannexed file oldkey cache = do - void $ removeAssociatedFile oldkey file - void $ addDirect file cache - - deletedannexed file key = do - void $ removeAssociatedFile key file - deletegit file - - stageannexlink file key = do - l <- calcRepo $ gitAnnexLink file key - stageSymlink file =<< hashSymlink l - void $ addAssociatedFile key file - - addgit file = Annex.Queue.addCommand "add" [Param "-f"] [file] - - deletegit file = Annex.Queue.addCommand "rm" [Param "-qf"] [file] - -{- 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 -addDirect file cache = do - showStart "add" file - let source = KeySource - { keyFilename = file - , contentLocation = file - , inodeCache = Just cache - } - got =<< genKey source nullMeterUpdate=<< chooseBackend file - where - got Nothing = do - showEndFail - return False - got (Just (key, _)) = ifM (sameInodeCache file [cache]) - ( do - l <- calcRepo $ gitAnnexLink file key - stageSymlink file =<< hashSymlink l - addInodeCache key cache - void $ addAssociatedFile key file - logStatus key InfoPresent - showEndOk - return True - , do - showEndFail - return False - ) setIndirect :: Annex () setIndirect = do diff --git a/CHANGELOG b/CHANGELOG index 3c46f2ce51..59867528d6 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -17,6 +17,7 @@ git-annex (7.20190826) UNRELEASED; urgency=medium * When upgrading a direct mode repo to v7 with adjusted unlocked branches, fix a bug that prevented annex.thin from taking effect for the files in working tree. + * Avoid making a commit when upgrading from direct mode to v7. -- Joey Hess Sat, 24 Aug 2019 12:54:35 -0400 diff --git a/Upgrade/V5.hs b/Upgrade/V5.hs index 859e605b54..fbeb34a438 100644 --- a/Upgrade/V5.hs +++ b/Upgrade/V5.hs @@ -59,14 +59,6 @@ convertDirect automatic = do - as does annex.thin. -} setConfig (annexConfig "thin") (boolConfig True) Annex.changeGitConfig $ \c -> c { annexThin = True } - {- 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 Direct.stageDirect $ do - unless automatic $ - showAction "committing first" - upgradeDirectCommit automatic - "commit before upgrade to annex.version 6" Direct.setIndirect cur <- fromMaybe (error "Somehow no branch is checked out") <$> inRepo Git.Branch.current @@ -82,18 +74,11 @@ convertDirect automatic = do - adjust branch. Instead, update HEAD manually. -} inRepo $ setHeadRef b -upgradeDirectCommit :: Bool -> String -> Annex () -upgradeDirectCommit automatic msg = - void $ inRepo $ Git.Branch.commitCommand commitmode - [ Param "-m" - , Param msg - ] - where - commitmode = if automatic then Git.Branch.AutomaticCommit else Git.Branch.ManualCommit - {- Walk work tree from top and convert all annex symlinks to pointer files, - staging them in the index, and updating the work tree files with - - either the content of the object, or the pointer file content. -} + - either the content of the object, or the pointer file content. + - Modified work tree files are left as-is, and deleted work tree files are + - skipped. -} upgradeDirectWorkTree :: Annex () upgradeDirectWorkTree = do top <- fromRepo Git.repoPath @@ -108,17 +93,16 @@ upgradeDirectWorkTree = do case mk of Nothing -> noop Just k -> do + stagePointerFile f Nothing =<< hashPointerFile k ifM (isJust <$> getAnnexLinkTarget f) ( writepointer f k , fromdirect f k ) - stagePointerFile f Nothing =<< hashPointerFile k Database.Keys.addAssociatedFile k =<< inRepo (toTopFilePath f) - return () go _ = noop - fromdirect f k = do + fromdirect f k = whenM (Direct.goodContent k f) $ do -- If linkToAnnex fails for some reason, the work tree file -- still has the content; the annex object file is just -- not populated with it. Since the work tree file @@ -126,6 +110,7 @@ upgradeDirectWorkTree = do -- work that way, it's just not ideal. ic <- withTSDelta (liftIO . genInodeCache f) void $ linkToAnnex k f ic + writepointer f k = liftIO $ do nukeFile f S.writeFile f (formatPointer k)