diff options
author | Joey Hess <joey@kitenet.net> | 2013-12-02 12:34:16 -0400 |
---|---|---|
committer | Joey Hess <joey@kitenet.net> | 2013-12-02 12:34:16 -0400 |
commit | 7fe47922b8001f8ff775a6feb6595c9f069db2c7 (patch) | |
tree | 34a269b5df48ee0a8177b5108a3bc9d2f8776065 /Init.hs | |
parent | cc733fdf81fdb22625f22e736cff2ad33dda2070 (diff) |
Automatically fix up bad bare repositories created by versions 5.20131118 through 5.20131127.
Diffstat (limited to 'Init.hs')
-rw-r--r-- | Init.hs | 65 |
1 files changed, 64 insertions, 1 deletions
@@ -21,6 +21,8 @@ import qualified Annex import qualified Git import qualified Git.LsFiles import qualified Git.Config +import qualified Git.Construct +import qualified Git.Types as Git import qualified Annex.Branch import Logs.UUID import Annex.Version @@ -36,7 +38,12 @@ import Utility.UserInfo import Utility.FileMode #endif import Annex.Hook +import Git.Hook (hookFile) import Upgrade +import Annex.Content +import Logs.Location + +import System.Log.Logger genDescription :: Maybe String -> Annex String genDescription (Just d) = return d @@ -92,7 +99,9 @@ uninitialize = do - Checks repository version and handles upgrades too. -} ensureInitialized :: Annex () -ensureInitialized = getVersion >>= maybe needsinit checkUpgrade +ensureInitialized = do + getVersion >>= maybe needsinit checkUpgrade + fixBadBare where needsinit = ifM Annex.Branch.hasSibling ( initialize Nothing @@ -176,3 +185,57 @@ enableDirectMode = unlessM isDirect $ do forM_ l $ \f -> maybe noop (`toDirect` f) =<< isAnnexLink f void $ liftIO clean + +{- Work around for git-annex version 5.20131118 - 5.20131127, which + - had a bug that unset core.bare when initializing a bare repository. + - + - This resulted in objects sent to the repository being stored in + - repo/.git/annex/objects, so move them to repo/annex/objects. + - + - This check slows down every git-annex run somewhat (by one file stat), + - so should be removed after a suitable period of time has passed. + - Since the bare repository may be on an offline USB drive, best to + - keep it for a while. However, git-annex was only buggy for a few + - weeks, so not too long. + -} +fixBadBare :: Annex () +fixBadBare = whenM checkBadBare $ do + ks <- getKeysPresent + liftIO $ debugM "Init" $ unwords + [ "Detected bad bare repository with" + , show (length ks) + , "objects; fixing" + ] + g <- Annex.gitRepo + gc <- Annex.getGitConfig + d <- Git.repoPath <$> Annex.gitRepo + void $ liftIO $ boolSystem "git" + [ Param $ "--git-dir=" ++ d + , Param "config" + , Param Git.Config.coreBare + , Param $ Git.Config.boolConfig True + ] + g' <- liftIO $ Git.Construct.fromPath d + s' <- liftIO $ Annex.new $ g' { Git.location = Git.Local { Git.gitdir = d, Git.worktree = Nothing } } + Annex.changeState $ \s -> s + { Annex.repo = Annex.repo s' + , Annex.gitconfig = Annex.gitconfig s' + } + forM_ ks $ \k -> do + oldloc <- liftIO $ gitAnnexLocation k g gc + thawContentDir oldloc + moveAnnex k oldloc + logStatus k InfoPresent + let dotgit = d </> ".git" + liftIO $ removeDirectoryRecursive dotgit + `catchIO` (const $ renameDirectory dotgit (d </> "removeme")) + +{- A repostory with the problem won't know it's a bare repository, but will + - have no pre-commit hook (which is not set up in a bare repository), + - and will not have a HEAD file in its .git directory. -} +checkBadBare :: Annex Bool +checkBadBare = allM (not <$>) + [isBare, hasPreCommitHook, hasDotGitHEAD] + where + hasPreCommitHook = inRepo $ doesFileExist . hookFile preCommitHook + hasDotGitHEAD = inRepo $ \r -> doesFileExist $ Git.localGitDir r </> "HEAD" |