Avoid crashing when run in a bare git repo that somehow contains an index file
Do not populate the keys database with associated files, because a bare repo has no working tree, and so it does not make sense to populate it. Queries of associated files in the keys database always return empty lists in a bare repo, even if it's somehow populated. One way it could be populated is if a user converts a non-bare repo to a bare repo. Note that Git.Config.isBare does a string comparison, so this is not free! But, that string comparison is very small compared to a sqlite query. Sponsored-by: Erik Bjäreholt on Patreon
This commit is contained in:
parent
c031d19c32
commit
f54c58f0df
4 changed files with 48 additions and 4 deletions
|
@ -10,6 +10,8 @@ git-annex (8.20211232) UNRELEASED; urgency=medium
|
||||||
a retry from failing again.
|
a retry from failing again.
|
||||||
(reversion introduced in version 8.20210903)
|
(reversion introduced in version 8.20210903)
|
||||||
* adb: Added ignorefinderror configuration parameter.
|
* adb: Added ignorefinderror configuration parameter.
|
||||||
|
* Avoid crashing when run in a bare git repo that somehow contains an
|
||||||
|
index file.
|
||||||
|
|
||||||
-- Joey Hess <id@joeyh.name> Mon, 03 Jan 2022 14:01:14 -0400
|
-- Joey Hess <id@joeyh.name> Mon, 03 Jan 2022 14:01:14 -0400
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,7 @@ import Git.Sha
|
||||||
import Git.CatFile
|
import Git.CatFile
|
||||||
import Git.Branch (writeTreeQuiet, update')
|
import Git.Branch (writeTreeQuiet, update')
|
||||||
import qualified Git.Ref
|
import qualified Git.Ref
|
||||||
|
import qualified Git.Config
|
||||||
import Config.Smudge
|
import Config.Smudge
|
||||||
import qualified Utility.RawFilePath as R
|
import qualified Utility.RawFilePath as R
|
||||||
|
|
||||||
|
@ -154,11 +155,23 @@ addAssociatedFile k f = runWriterIO $ SQL.addAssociatedFile k f
|
||||||
{- Note that the files returned were once associated with the key, but
|
{- Note that the files returned were once associated with the key, but
|
||||||
- some of them may not be any longer. -}
|
- some of them may not be any longer. -}
|
||||||
getAssociatedFiles :: Key -> Annex [TopFilePath]
|
getAssociatedFiles :: Key -> Annex [TopFilePath]
|
||||||
getAssociatedFiles = runReaderIO . SQL.getAssociatedFiles
|
getAssociatedFiles k = emptyWhenBare $ runReaderIO $ SQL.getAssociatedFiles k
|
||||||
|
|
||||||
|
{- Queries for associated files never return anything when in a bare
|
||||||
|
- repository, since without a work tree there can be no associated files.
|
||||||
|
-
|
||||||
|
- Normally the keys database is not even populated with associated files
|
||||||
|
- in a bare repository, but it might happen if a non-bare repo got
|
||||||
|
- converted to bare. -}
|
||||||
|
emptyWhenBare :: Annex [a] -> Annex [a]
|
||||||
|
emptyWhenBare a = ifM (Git.Config.isBare <$> gitRepo)
|
||||||
|
( return []
|
||||||
|
, a
|
||||||
|
)
|
||||||
|
|
||||||
{- Include a known associated file along with any recorded in the database. -}
|
{- Include a known associated file along with any recorded in the database. -}
|
||||||
getAssociatedFilesIncluding :: AssociatedFile -> Key -> Annex [RawFilePath]
|
getAssociatedFilesIncluding :: AssociatedFile -> Key -> Annex [RawFilePath]
|
||||||
getAssociatedFilesIncluding afile k = do
|
getAssociatedFilesIncluding afile k = emptyWhenBare $ do
|
||||||
g <- Annex.gitRepo
|
g <- Annex.gitRepo
|
||||||
l <- map (`fromTopFilePath` g) <$> getAssociatedFiles k
|
l <- map (`fromTopFilePath` g) <$> getAssociatedFiles k
|
||||||
return $ case afile of
|
return $ case afile of
|
||||||
|
@ -168,7 +181,7 @@ getAssociatedFilesIncluding afile k = do
|
||||||
{- Gets any keys that are on record as having a particular associated file.
|
{- Gets any keys that are on record as having a particular associated file.
|
||||||
- (Should be one or none but the database doesn't enforce that.) -}
|
- (Should be one or none but the database doesn't enforce that.) -}
|
||||||
getAssociatedKey :: TopFilePath -> Annex [Key]
|
getAssociatedKey :: TopFilePath -> Annex [Key]
|
||||||
getAssociatedKey = runReaderIO . SQL.getAssociatedKey
|
getAssociatedKey f = emptyWhenBare $ runReaderIO $ SQL.getAssociatedKey f
|
||||||
|
|
||||||
removeAssociatedFile :: Key -> TopFilePath -> Annex ()
|
removeAssociatedFile :: Key -> TopFilePath -> Annex ()
|
||||||
removeAssociatedFile k = runWriterIO . SQL.removeAssociatedFile k
|
removeAssociatedFile k = runWriterIO . SQL.removeAssociatedFile k
|
||||||
|
@ -233,7 +246,7 @@ isInodeKnown i s = or <$> runReaderIO ((:[]) <$$> SQL.isInodeKnown i s)
|
||||||
- is an associated file.
|
- is an associated file.
|
||||||
-}
|
-}
|
||||||
reconcileStaged :: H.DbQueue -> Annex ()
|
reconcileStaged :: H.DbQueue -> Annex ()
|
||||||
reconcileStaged qh = do
|
reconcileStaged qh = unlessM (Git.Config.isBare <$> gitRepo) $ do
|
||||||
gitindex <- inRepo currentIndexFile
|
gitindex <- inRepo currentIndexFile
|
||||||
indexcache <- fromRawFilePath <$> fromRepo gitAnnexKeysDbIndexCache
|
indexcache <- fromRawFilePath <$> fromRepo gitAnnexKeysDbIndexCache
|
||||||
withTSDelta (liftIO . genInodeCache gitindex) >>= \case
|
withTSDelta (liftIO . genInodeCache gitindex) >>= \case
|
||||||
|
|
|
@ -55,3 +55,4 @@ AFAICS this creates the same records as if I would have done this in a regular w
|
||||||
|
|
||||||
Is this a bug, or am I doing something wrong? Thanks in advance for your time!
|
Is this a bug, or am I doing something wrong? Thanks in advance for your time!
|
||||||
|
|
||||||
|
> [[fixed|done]] --[[Joey]]
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
[[!comment format=mdwn
|
||||||
|
username="joey"
|
||||||
|
subject="""comment 1"""
|
||||||
|
date="2022-01-11T16:25:50Z"
|
||||||
|
content="""
|
||||||
|
`git update-index` creates an index file. A repo with an index file is no
|
||||||
|
longer a bare repo to a certain extent, at least it is very unusual for a
|
||||||
|
repo to be both bare and contain an index file, since after all an index
|
||||||
|
file is a record of the files in the working tree. This seems to be the root
|
||||||
|
of the confusion.
|
||||||
|
|
||||||
|
I was able to reproduce this by simply copying `.git/index` from a non-bare
|
||||||
|
repo into the bare repo and then running `git-annex drop --all`.
|
||||||
|
|
||||||
|
Removing the index file was not sufficient to fix it. It turned out I also
|
||||||
|
needed to delete `annex/keydb*`. Then things returned to normal.
|
||||||
|
|
||||||
|
So, it seems that the keys database is getting populated in a bare repo
|
||||||
|
when there's an index file, and once the keys database is populated, it
|
||||||
|
runs code paths that will not work in a bare repo, because that database
|
||||||
|
contains paths (taken from the index) that it treats as being present in a
|
||||||
|
nonexistant working tree. I've fixed it to both avoid populating the keys
|
||||||
|
database, and ignore a populated keys database in this situation.
|
||||||
|
|
||||||
|
But.. My suggestion is, if you need to do this kind of thing in a bare repo,
|
||||||
|
set `GIT_INDEX_FILE` to some other file. That's how git-annex makes similar
|
||||||
|
tree objects.
|
||||||
|
"""]]
|
Loading…
Add table
Add a link
Reference in a new issue