From 5877a15d7bff2af0e4e832a2ac5b43e4d284093e Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Mon, 26 Aug 2019 13:46:58 -0400 Subject: [PATCH] fix hard links when upgrading from direct mode 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. The hard links used to be ok, but commit 8e22114735 accidentially broke them. It repopulates the worktree file, which is already a hard link, and when it's creating the new file, the link count is already 2, and so it doesn't make a hard link then. --- Annex/Init.hs | 2 +- Annex/WorkTree.hs | 9 ++++--- CHANGELOG | 3 +++ Upgrade/V5.hs | 69 ++++++++++++++++++++++++++--------------------- 4 files changed, 48 insertions(+), 35 deletions(-) diff --git a/Annex/Init.hs b/Annex/Init.hs index 6a49f4ba7a..370345fd07 100644 --- a/Annex/Init.hs +++ b/Annex/Init.hs @@ -113,7 +113,7 @@ initialize' mversion = checkCanInitialize $ do ) whenM versionSupportsUnlockedPointers $ do configureSmudgeFilter - scanUnlockedFiles + scanUnlockedFiles True unlessM isBareRepo $ do hookWrite postCheckoutHook hookWrite postMergeHook diff --git a/Annex/WorkTree.hs b/Annex/WorkTree.hs index 419118f0ed..4e1a029bab 100644 --- a/Annex/WorkTree.hs +++ b/Annex/WorkTree.hs @@ -75,10 +75,11 @@ ifAnnexed file yes no = maybe no yes =<< lookupFile file - when initializing/upgrading a v6+ mode repository. - - Also, the content for the unlocked file may already be present as - - an annex object. If so, make the unlocked file use that content. + - an annex object. If so, make the unlocked file use that content + - when replacefiles is True. -} -scanUnlockedFiles :: Annex () -scanUnlockedFiles = whenM (inRepo Git.Ref.headExists) $ do +scanUnlockedFiles :: Bool -> Annex () +scanUnlockedFiles replacefiles = whenM (inRepo Git.Ref.headExists) $ do showSideAction "scanning for unlocked files" Database.Keys.runWriter $ liftIO . Database.Keys.SQL.dropAllAssociatedFiles @@ -97,7 +98,7 @@ scanUnlockedFiles = whenM (inRepo Git.Ref.headExists) $ do let tf = Git.LsTree.file i Database.Keys.runWriter $ liftIO . Database.Keys.SQL.addAssociatedFileFast (toIKey k) tf - whenM (inAnnex k) $ do + whenM (pure replacefiles <&&> inAnnex k) $ do f <- fromRepo $ fromTopFilePath tf destmode <- liftIO $ catchMaybeIO $ fileMode <$> getFileStatus f ic <- replaceFile f $ \tmp -> diff --git a/CHANGELOG b/CHANGELOG index e6958ccb19..9085c3dca0 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -5,6 +5,9 @@ git-annex (7.20190820) UNRELEASED; urgency=medium so error out to avoid confusion. * assistant: When creating a new repository, no longer use direct mode, instead use v7 adjusted branches with annex.thin. + * 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. -- Joey Hess Sat, 24 Aug 2019 12:54:35 -0400 diff --git a/Upgrade/V5.hs b/Upgrade/V5.hs index cbde00a292..064c9f4652 100644 --- a/Upgrade/V5.hs +++ b/Upgrade/V5.hs @@ -1,6 +1,6 @@ {- git-annex v5 -> v6 upgrade support - - - Copyright 2015-2016 Joey Hess + - Copyright 2015-2019 Joey Hess - - Licensed under the GNU AGPL version 3 or higher. -} @@ -35,35 +35,14 @@ upgrade :: Bool -> Annex Bool upgrade automatic = do unless automatic $ showAction "v5 to v6" - whenM isDirect $ do - {- Direct mode makes the same tradeoff of using less disk - - space, with less preservation of old versions of files - - 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 stageDirect $ do - unless automatic $ - showAction "committing first" - upgradeDirectCommit automatic - "commit before upgrade to annex.version 6" - setDirect False - cur <- fromMaybe (error "Somehow no branch is checked out") - <$> inRepo Git.Branch.current - upgradeDirectWorkTree - removeDirectCruft - {- Create adjusted branch where all files are unlocked. - - This should have the same content for each file as - - have been staged in upgradeDirectWorkTree. -} - AdjBranch b <- adjustBranch (LinkAdjustment UnlockAdjustment) cur - {- Since the work tree was already set up by - - upgradeDirectWorkTree, and contains unlocked file - - contents too, don't use git checkout to check out the - - adjust branch. Instead, update HEAD manually. -} - inRepo $ setHeadRef b - scanUnlockedFiles + ifM isDirect + ( do + convertDirect automatic + -- Worktree files are already populated, so don't + -- have this try to populate them again. + scanUnlockedFiles False + , scanUnlockedFiles True + ) configureSmudgeFilter -- Inode sentinal file was only used in direct mode and when -- locking down files as they were added. In v6, it's used more @@ -73,6 +52,36 @@ upgrade automatic = do createInodeSentinalFile True return True +convertDirect :: Bool -> Annex () +convertDirect automatic = do + {- Direct mode makes the same tradeoff of using less disk + - space, with less preservation of old versions of files + - 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 stageDirect $ do + unless automatic $ + showAction "committing first" + upgradeDirectCommit automatic + "commit before upgrade to annex.version 6" + setDirect False + cur <- fromMaybe (error "Somehow no branch is checked out") + <$> inRepo Git.Branch.current + upgradeDirectWorkTree + removeDirectCruft + {- Create adjusted branch where all files are unlocked. + - This should have the same content for each file as + - have been staged in upgradeDirectWorkTree. -} + AdjBranch b <- adjustBranch (LinkAdjustment UnlockAdjustment) cur + {- Since the work tree was already set up by + - upgradeDirectWorkTree, and contains unlocked file + - contents too, don't use git checkout to check out the + - adjust branch. Instead, update HEAD manually. -} + inRepo $ setHeadRef b + upgradeDirectCommit :: Bool -> String -> Annex () upgradeDirectCommit automatic msg = void $ inRepo $ Git.Branch.commitCommand commitmode