improve some edge cases around partial initialization
authorJoey Hess <joeyh@joeyh.name>
Mon, 14 Dec 2020 17:17:43 +0000 (13:17 -0400)
committerJoey Hess <joeyh@joeyh.name>
Mon, 14 Dec 2020 17:17:43 +0000 (13:17 -0400)
* Guard against running in a repo where annex.uuid is set but
  annex.version is set, or vice-versa.
* Avoid autoinit when a repo does not have annex.version or annex.uuid
  set, but has a git-annex objects directory, suggesting it was used
  by git-annex before.

Annex/Init.hs
CHANGELOG
doc/todo/avoid_autoinit_when_git-annex_branch_already_exists.mdwn

index c05263c7df88c441cd22b47b9a3b882e270725fc..3078a6213fcdefb680b169fda53051f19cc71b20 100644 (file)
@@ -159,6 +159,29 @@ uninitialize = do
        removeRepoUUID
        removeVersion
 
+{- Gets the version that the repo is initialized with.
+ -
+ - To make sure the repo is fully initialized, also checks that it has a
+ - uuid configured. In the unusual case where one is set and the other is
+ - not, errors out to avoid running in an inconsistent state.
+ -}
+getInitializedVersion :: Annex (Maybe RepoVersion)
+getInitializedVersion = do
+       um <- (\u -> if u == NoUUID then Nothing else Just u) <$> getUUID
+       vm <- getVersion
+       case (um, vm) of
+               (Just _, Just v) -> return (Just v)
+               (Nothing, Nothing) -> return Nothing
+               (Just _, Nothing) -> onemissing "annex.version" "annex.uuid"
+               (Nothing, Just _) -> onemissing "annex.uuid" "annex.version"
+  where
+       onemissing missing have = giveup $ unwords
+               [ "This repository has " ++ have ++ " set,"
+               , "but " ++ missing ++ " is not set. Perhaps that"
+               , "git config was lost. Cannot use the repository"
+               , "in this state; set back " ++ missing ++ " to fix this."
+               ]
+
 {- Will automatically initialize if there is already a git-annex
  - branch from somewhere. Otherwise, require a manual init
  - to avoid git-annex accidentally being run in git
@@ -167,7 +190,7 @@ uninitialize = do
  - Checks repository version and handles upgrades too.
  -}
 ensureInitialized :: Annex ()
-ensureInitialized = getVersion >>= maybe needsinit checkUpgrade
+ensureInitialized = getInitializedVersion >>= maybe needsinit checkUpgrade
   where
        needsinit = ifM autoInitializeAllowed
                ( do
@@ -178,14 +201,30 @@ ensureInitialized = getVersion >>= maybe needsinit checkUpgrade
 
 {- Check if auto-initialize is allowed. -}
 autoInitializeAllowed :: Annex Bool
-autoInitializeAllowed = Annex.Branch.hasSibling
+autoInitializeAllowed = Annex.Branch.hasSibling <&&> objectDirNotPresent
+
+objectDirNotPresent :: Annex Bool
+objectDirNotPresent = do
+       d <- fromRawFilePath <$> fromRepo gitAnnexObjectDir
+       exists <- liftIO $ doesDirectoryExist d
+       when exists $
+               giveup $ unwords $ 
+                       [ "This repository is not initialized for use"
+                       , "by git-annex, but " ++ d ++ " exists,"
+                       , "which indicates this repository was used by"
+                       , "git-annex before, and may have lost its"
+                       , "annex.uuid and annex.version configs. Either"
+                       , "set back missing configs, or run git-annex init"
+                       , "to initialize with a new uuid."
+                       ]
+       return (not exists)
 
 {- Initialize if it can do so automatically. Avoids failing if it cannot.
  -
  - Checks repository version and handles upgrades too.
  -}
 autoInitialize :: Annex ()
-autoInitialize = getVersion >>= maybe needsinit checkUpgrade
+autoInitialize = getInitializedVersion >>= maybe needsinit checkUpgrade
   where
        needsinit =
                whenM (initializeAllowed <&&> autoInitializeAllowed) $ do
index ef42edcb333657d29b0779695fda4ddfe6ee76db..af80578008d22bb55089b91a2f333e335f5f9360 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -12,6 +12,11 @@ git-annex (8.20201128) UNRELEASED; urgency=medium
     having a copy of the content.
   * Support special remotes that are configured with importtree=yes but
     without exporttree=yes.
+  * Guard against running in a repo where annex.uuid is set but
+    annex.version is set, or vice-versa.
+  * Avoid autoinit when a repo does not have annex.version or annex.uuid
+    set, but has a git-annex objects directory, suggesting it was used
+    by git-annex before.
 
  -- Joey Hess <id@joeyh.name>  Mon, 30 Nov 2020 12:55:49 -0400
 
index 914a74ecc6ad2278c807b2ea3113268da9017dfe..f94a128bf1b13fab7cf6c3c235db34a7d5319811 100644 (file)
@@ -24,3 +24,5 @@ A bare repo that was just cloned will have a git-annex branch
 before it gets initialized. So for bare repos, would need to not consider
 that, but looking if annex/index exists would still do. Or may be better
 not to special case it, and only look for the annex/index file? --[[Joey]]
+
+> [[done]] --[[Joey]]