fix problems with upgrade of local remotes

Upgrade other repos than the current one by running git-annex upgrade
inside them, which avoids problems with upgrade code making assumptions
that the cwd will be inside the repo being upgraded.

In particular, this fixes a problem where upgrading a v7 repo to v8 caused
an ugly git error message.

I actually could not find a way to make Upgrade.V7 work properly
without changing directory to the remote. Once I got git ls-files to work,
the git cat-file failed because :path can only be used in the current git
repo.
This commit is contained in:
Joey Hess 2020-03-09 16:47:57 -04:00
parent 3440b77d1e
commit afe72d04ff
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
5 changed files with 85 additions and 17 deletions

View file

@ -4,6 +4,11 @@ git-annex (8.20200227) UNRELEASED; urgency=medium
GETCONFIG to query values like "name". (Introduced in version 7.20200202.7.) GETCONFIG to query values like "name". (Introduced in version 7.20200202.7.)
* Fix bug that caused unlocked annexed dotfiles to be added to git by the * Fix bug that caused unlocked annexed dotfiles to be added to git by the
smudge filter when annex.dotfiles was not set. smudge filter when annex.dotfiles was not set.
* Upgrade other repos than the current one by running git-annex upgrade
inside them, which avoids problems with upgrade code making assumptions
that the cwd will be inside the repo being upgraded. In particular,
this fixes a problem where upgrading a v7 repo to v8 caused an ugly
git error message.
* Improve behavior when a directory git-annex is writing to gets * Improve behavior when a directory git-annex is writing to gets
unmounted. Previously it could in some cases re-create the mount point unmounted. Previously it could in some cases re-create the mount point
and directory tree, and even write object contents to the wrong disk. and directory tree, and even write object contents to the wrong disk.

View file

@ -1,6 +1,6 @@
{- git-annex command {- git-annex command
- -
- Copyright 2011 Joey Hess <id@joeyh.name> - Copyright 2011-2020 Joey Hess <id@joeyh.name>
- -
- Licensed under the GNU AGPL version 3 or higher. - Licensed under the GNU AGPL version 3 or higher.
-} -}
@ -20,13 +20,28 @@ cmd = dontCheck repoExists $
noDaemonRunning $ noDaemonRunning $
-- ^ avoid upgrading repo out from under daemon -- ^ avoid upgrading repo out from under daemon
command "upgrade" SectionMaintenance "upgrade repository" command "upgrade" SectionMaintenance "upgrade repository"
paramNothing (withParams seek) paramNothing (seek <$$> optParser)
seek :: CmdParams -> CommandSeek data UpgradeOptions = UpgradeOptions
seek = withNothing (commandAction start) { autoOnly :: Bool
}
start :: CommandStart optParser :: CmdParamsDesc -> Parser UpgradeOptions
start = starting "upgrade" (ActionItemOther Nothing) $ do optParser _ = UpgradeOptions
<$> switch
( long "autoonly"
<> help "only do automatic upgrades"
)
seek :: UpgradeOptions -> CommandSeek
seek o = commandAction (start o)
start :: UpgradeOptions -> CommandStart
start (UpgradeOptions { autoOnly = True }) = do
starting "upgrade" (ActionItemOther Nothing) $ do
getVersion >>= maybe noop checkUpgrade
next $ return True
start _ = starting "upgrade" (ActionItemOther Nothing) $ do
whenM (isNothing <$> getVersion) $ do whenM (isNothing <$> getVersion) $ do
initialize Nothing Nothing initialize Nothing Nothing
r <- upgrade False latestVersion r <- upgrade False latestVersion

View file

@ -1,6 +1,6 @@
{- git-annex upgrade support {- git-annex upgrade support
- -
- Copyright 2010-2019 Joey Hess <id@joeyh.name> - Copyright 2010-2020 Joey Hess <id@joeyh.name>
- -
- Licensed under the GNU AGPL version 3 or higher. - Licensed under the GNU AGPL version 3 or higher.
-} -}
@ -12,6 +12,8 @@ module Upgrade where
import Annex.Common import Annex.Common
import qualified Annex import qualified Annex
import qualified Git import qualified Git
import Config
import Config.Files
import Annex.Version import Annex.Version
import Types.RepoVersion import Types.RepoVersion
#ifndef mingw32_HOST_OS #ifndef mingw32_HOST_OS
@ -61,18 +63,26 @@ needsUpgrade v
upgrade :: Bool -> RepoVersion -> Annex Bool upgrade :: Bool -> RepoVersion -> Annex Bool
upgrade automatic destversion = do upgrade automatic destversion = do
upgraded <- go =<< getVersion upgraded <- go =<< getVersion
when upgraded $ when upgraded
setVersion destversion postupgrade
return upgraded return upgraded
where where
go (Just v) go (Just v)
| v >= destversion = return True | v >= destversion = return True
| otherwise = ifM (up v) | otherwise = ifM upgradingRemote
( go (Just (RepoVersion (fromRepoVersion v + 1))) ( upgraderemote
, return False , ifM (up v)
( go (Just (RepoVersion (fromRepoVersion v + 1)))
, return False
)
) )
go _ = return True go _ = return True
postupgrade = ifM upgradingRemote
( reloadConfig
, setVersion destversion
)
#ifndef mingw32_HOST_OS #ifndef mingw32_HOST_OS
up (RepoVersion 0) = Upgrade.V0.upgrade up (RepoVersion 0) = Upgrade.V0.upgrade
up (RepoVersion 1) = Upgrade.V1.upgrade up (RepoVersion 1) = Upgrade.V1.upgrade
@ -87,3 +97,19 @@ upgrade automatic destversion = do
up (RepoVersion 6) = Upgrade.V6.upgrade automatic up (RepoVersion 6) = Upgrade.V6.upgrade automatic
up (RepoVersion 7) = Upgrade.V7.upgrade automatic up (RepoVersion 7) = Upgrade.V7.upgrade automatic
up _ = return True up _ = return True
-- Upgrade local remotes by running git-annex upgrade in them.
-- This avoids complicating the upgrade code by needing to handle
-- upgrading a git repo other than the current repo.
upgraderemote = do
rp <- fromRawFilePath <$> fromRepo Git.repoPath
cmd <- liftIO readProgramFile
liftIO $ boolSystem' cmd
[ Param "upgrade"
, Param "--quiet"
, Param "--autoonly"
]
(\p -> p { cwd = Just rp })
upgradingRemote :: Annex Bool
upgradingRemote = isJust <$> fromRepo Git.remoteName

View file

@ -5,10 +5,17 @@ a repo that has it as a remote, this is displayed:
This happens because git ls-files is run to list the files of the clone. This happens because git ls-files is run to list the files of the clone.
But, it has some strange behavior when relative paths are used. Result is But, it has some strange behavior when relative paths are used. Result is
it always fails. This also causes the keys database of the clone to not get it always fails.
repopulated after being deleted for the upgrade. That's not a fatal problem
because git-annex is always prepared for the keys database being out of This also causes the keys database of the clone to not get
date, but it could result in considerably more work being done later. repopulated after being deleted for the upgrade.
That's not a fatal problem because git-annex is always prepared for the
keys database being out of date, but it could result in considerably more
work being done later.
Also, the associated files does not get repopulated when it fails like
that. That could cause worse problems. I have not tried to see what happens
when the repo that fails to be upgraded has unlocked files.
I also found some v1 upgrade code that does the same thing, and presumably I also found some v1 upgrade code that does the same thing, and presumably
also has the problem, although there are probably no v1 repos left. also has the problem, although there are probably no v1 repos left.
@ -22,3 +29,11 @@ that looks like it would have then problem. That would affect upgrading
from a V5 direct mode repo to V6. from a V5 direct mode repo to V6.
--[[Joey] --[[Joey]
> Fixed all such upgrade bugs by changing how local remotes are upgraded,
> running git-annex upgrade inside the remote.
>
> Also, guarded all git ls-files calls with a check that it's not being
> run on a local remote, just in case there are other such bugs.
>
> [[done]] --[[Joey]]

View file

@ -8,7 +8,7 @@ git annex upgrade
# DESCRIPTION # DESCRIPTION
Upgrades the repository. Upgrades the repository to the latest version.
Each git-annex repository has an annex.version in its git configuration, Each git-annex repository has an annex.version in its git configuration,
that indicates the repository version. When an old repository version that indicates the repository version. When an old repository version
@ -24,6 +24,13 @@ was only used by its author. It's expected that git-annex will always
support upgrading from all past repository versions -- this is necessary to support upgrading from all past repository versions -- this is necessary to
allow archives to be taken offline for years and later used. allow archives to be taken offline for years and later used.
# OPTIONS
* --autoonly
Only do whatever automatic upgrade can be done, don't necessarily
upgrade to the latest version. This is used internally by git-annex.
# SEE ALSO # SEE ALSO
[[git-annex]](1) [[git-annex]](1)