improve some edge cases around partial initialization

* 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.
This commit is contained in:
Joey Hess 2020-12-14 13:17:43 -04:00
parent 230e1c88a9
commit 75acf5f440
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
3 changed files with 49 additions and 3 deletions

View file

@ -159,6 +159,29 @@ uninitialize = do
removeRepoUUID removeRepoUUID
removeVersion 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 {- Will automatically initialize if there is already a git-annex
- branch from somewhere. Otherwise, require a manual init - branch from somewhere. Otherwise, require a manual init
- to avoid git-annex accidentally being run in git - to avoid git-annex accidentally being run in git
@ -167,7 +190,7 @@ uninitialize = do
- Checks repository version and handles upgrades too. - Checks repository version and handles upgrades too.
-} -}
ensureInitialized :: Annex () ensureInitialized :: Annex ()
ensureInitialized = getVersion >>= maybe needsinit checkUpgrade ensureInitialized = getInitializedVersion >>= maybe needsinit checkUpgrade
where where
needsinit = ifM autoInitializeAllowed needsinit = ifM autoInitializeAllowed
( do ( do
@ -178,14 +201,30 @@ ensureInitialized = getVersion >>= maybe needsinit checkUpgrade
{- Check if auto-initialize is allowed. -} {- Check if auto-initialize is allowed. -}
autoInitializeAllowed :: Annex Bool 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. {- Initialize if it can do so automatically. Avoids failing if it cannot.
- -
- Checks repository version and handles upgrades too. - Checks repository version and handles upgrades too.
-} -}
autoInitialize :: Annex () autoInitialize :: Annex ()
autoInitialize = getVersion >>= maybe needsinit checkUpgrade autoInitialize = getInitializedVersion >>= maybe needsinit checkUpgrade
where where
needsinit = needsinit =
whenM (initializeAllowed <&&> autoInitializeAllowed) $ do whenM (initializeAllowed <&&> autoInitializeAllowed) $ do

View file

@ -12,6 +12,11 @@ git-annex (8.20201128) UNRELEASED; urgency=medium
having a copy of the content. having a copy of the content.
* Support special remotes that are configured with importtree=yes but * Support special remotes that are configured with importtree=yes but
without exporttree=yes. 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 -- Joey Hess <id@joeyh.name> Mon, 30 Nov 2020 12:55:49 -0400

View 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 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 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]] not to special case it, and only look for the annex/index file? --[[Joey]]
> [[done]] --[[Joey]]