diff --git a/Annex.hs b/Annex.hs index 84b2bda0ad..aba23587fb 100644 --- a/Annex.hs +++ b/Annex.hs @@ -12,6 +12,7 @@ module Annex ( AnnexState(..), AnnexRead(..), new, + new', run, eval, makeRunner, @@ -291,10 +292,13 @@ newAnnexState c r = do - Ensures the config is read, if it was not already, and performs - any necessary git repo fixups. -} new :: Git.Repo -> IO (AnnexState, AnnexRead) -new r = do +new = new' fixupRepo + +new' :: (Git.Repo -> GitConfig -> IO Git.Repo) -> Git.Repo -> IO (AnnexState, AnnexRead) +new' f r = do r' <- Git.Config.read r let c = extractGitConfig FromGitConfig r' - st <- newAnnexState c =<< fixupRepo r' c + st <- newAnnexState c =<< f r' c rd <- newAnnexRead c return (st, rd) diff --git a/CHANGELOG b/CHANGELOG index d85abaa2c1..7216b21fbb 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -6,6 +6,8 @@ git-annex (10.20250631) UNRELEASED; urgency=medium symlinks, that caused annexed file content to be stored in the wrong location inside the git directory, and also caused pointer files to not get populated. + * fsck: Fix location of annexed files when run in linked worktrees + that have experienced the above bug. * Fix symlinks generated to annexed content when in adjusted unlocked branch in a linked worktree on a filesystem not supporting symlinks. diff --git a/Command/Fsck.hs b/Command/Fsck.hs index 50c21149b3..cd9dd335e1 100644 --- a/Command/Fsck.hs +++ b/Command/Fsck.hs @@ -1,6 +1,6 @@ {- git-annex command - - - Copyright 2010-2023 Joey Hess + - Copyright 2010-2025 Joey Hess - - Licensed under the GNU AGPL version 3 or higher. -} @@ -15,6 +15,7 @@ import qualified Annex import qualified Remote import qualified Types.Backend import qualified Backend +import qualified Git import Annex.Content import Annex.Verify #ifndef mingw32_HOST_OS @@ -24,6 +25,7 @@ import Annex.Content.Presence import Annex.Content.Presence.LowLevel import Annex.Perms import Annex.Link +import Annex.Fixup import Logs.Location import Logs.Trust import Logs.Activity @@ -102,6 +104,8 @@ seek o = startConcurrency commandStages $ do from <- maybe (pure Nothing) (Just <$$> getParsed) (fsckFromOption o) u <- maybe getUUID (pure . Remote.uuid) from checkDeadRepo u + when (isNothing from) $ + cleanupLinkedWorkTreeBug i <- prepIncremental u (incrementalOpt o) let seeker = AnnexedFileSeeker { startAction = const $ start from i @@ -768,4 +772,38 @@ withFsckDb (ContIncremental h) a = a h withFsckDb (StartIncremental h) a = a h withFsckDb (NonIncremental mh) a = maybe noop a mh withFsckDb (ScheduleIncremental _ _ i) a = withFsckDb i a - + +-- A bug caused linked worktrees on filesystems not supporting symlinks +-- to not use the common annex directory, but one annex directory per +-- linked worktree. Object files could end up stored in those directories. +-- +-- When run in a linked worktree with its own annex directory that is not a +-- symlink, move any object files to the right location, and delete the +-- annex directory. +cleanupLinkedWorkTreeBug :: Annex () +cleanupLinkedWorkTreeBug = + whenM (Annex.inRepo needsGitLinkFixup) $ do + r <- Annex.gitRepo + -- mainWorkTreePath is set by fixupUnusualRepos. + -- Unsetting it makes a version of the Repo that uses + -- the wrong object location. + let r' = r { Git.mainWorkTreePath = Nothing } + let dir = gitAnnexDir r' + whenM (liftIO $ dirnotsymlink dir) $ do + showSideAction $ "Cleaning up directory " + <> QuotedPath dir + <> " created by buggy version of git-annex" + (st, rd) <- liftIO $ Annex.new' (\r'' _c -> pure r'') r' + ks <- liftIO $ Annex.eval (st, rd) $ + listKeys InAnnex + forM_ ks $ \k -> void $ tryNonAsync $ do + loc <- liftIO $ gitAnnexLocation k r' + (Annex.gitconfig st) + moveAnnex k loc + void $ tryNonAsync $ liftIO $ + removeDirectoryRecursive dir + where + dirnotsymlink dir = + tryIO (R.getSymbolicLinkStatus (fromOsPath dir)) >>= \case + Right st -> return $ not (isSymbolicLink st) + Left _ -> return False diff --git a/doc/bugs/Missing_file_content_in_secondary_worktree___40__win__41__.mdwn b/doc/bugs/Missing_file_content_in_secondary_worktree___40__win__41__.mdwn index bbbb8143b3..9aa0d48d6d 100644 --- a/doc/bugs/Missing_file_content_in_secondary_worktree___40__win__41__.mdwn +++ b/doc/bugs/Missing_file_content_in_secondary_worktree___40__win__41__.mdwn @@ -97,3 +97,5 @@ This is on win11. Absolutely! Approaching 15 years of bigger, better, faster, more ;-) [[!tag projects/INM7]] + +> [[fixed|done]] --[[Joey]] diff --git a/doc/bugs/Missing_file_content_in_secondary_worktree___40__win__41__/comment_7_cfb97162cd21818995f9d71a5ce3a0d0._comment b/doc/bugs/Missing_file_content_in_secondary_worktree___40__win__41__/comment_7_cfb97162cd21818995f9d71a5ce3a0d0._comment new file mode 100644 index 0000000000..bb752665bf --- /dev/null +++ b/doc/bugs/Missing_file_content_in_secondary_worktree___40__win__41__/comment_7_cfb97162cd21818995f9d71a5ce3a0d0._comment @@ -0,0 +1,8 @@ +[[!comment format=mdwn + username="joey" + subject="""comment 7""" + date="2025-07-15T17:07:43Z" + content=""" +Running `git-annex fsck` in the affected worktree will clean up from this +bug. +"""]]