restage pointer file after unlock

This avoids a later git status or similar taking a long time to run
as it runs git-annex smudge once per file. While v9 repositories do
avoid that taking long when the files are small, large files can still
make git status take a very long time.

This does make unlock slower, because now git-annex smudge is being run
once per file unlocked. However, the next commit should speed that up in
many cases.

Sponsored-by: Boyd Stephen Smith Jr. on Patreon
This commit is contained in:
Joey Hess 2022-02-18 14:23:25 -04:00
parent 07215cfeb5
commit c68f52c6a2
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
2 changed files with 31 additions and 5 deletions

View file

@ -1,6 +1,6 @@
{- git-annex command {- git-annex command
- -
- Copyright 2010-2016 Joey Hess <id@joeyh.name> - Copyright 2010-2022 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 @@ import Annex.Content
import Annex.Perms import Annex.Perms
import Annex.Link import Annex.Link
import Annex.ReplaceFile import Annex.ReplaceFile
import Annex.InodeSentinal
import Utility.InodeCache
import Git.FilePath import Git.FilePath
import qualified Database.Keys import qualified Database.Keys
import qualified Utility.RawFilePath as R import qualified Utility.RawFilePath as R
@ -47,7 +49,7 @@ start si file key = ifM (isJust <$> isAnnexLink file)
perform :: RawFilePath -> Key -> CommandPerform perform :: RawFilePath -> Key -> CommandPerform
perform dest key = do perform dest key = do
destmode <- liftIO $ catchMaybeIO $ fileMode <$> R.getFileStatus dest destmode <- liftIO $ catchMaybeIO $ fileMode <$> R.getFileStatus dest
replaceWorkTreeFile (fromRawFilePath dest) $ \tmp -> destic <- replaceWorkTreeFile (fromRawFilePath dest) $ \tmp -> do
ifM (inAnnex key) ifM (inAnnex key)
( do ( do
r <- linkFromAnnex' key (toRawFilePath tmp) destmode r <- linkFromAnnex' key (toRawFilePath tmp) destmode
@ -57,10 +59,12 @@ perform dest key = do
LinkAnnexFailed -> error "unlock failed" LinkAnnexFailed -> error "unlock failed"
, liftIO $ writePointerFile (toRawFilePath tmp) key destmode , liftIO $ writePointerFile (toRawFilePath tmp) key destmode
) )
next $ cleanup dest key destmode withTSDelta (liftIO . genInodeCache (toRawFilePath tmp))
next $ cleanup dest destic key destmode
cleanup :: RawFilePath -> Key -> Maybe FileMode -> CommandCleanup cleanup :: RawFilePath -> Maybe InodeCache -> Key -> Maybe FileMode -> CommandCleanup
cleanup dest key destmode = do cleanup dest destic key destmode = do
stagePointerFile dest destmode =<< hashPointerFile key stagePointerFile dest destmode =<< hashPointerFile key
maybe noop (restagePointerFile (Restage True) dest) destic
Database.Keys.addAssociatedFile key =<< inRepo (toTopFilePath dest) Database.Keys.addAssociatedFile key =<< inRepo (toTopFilePath dest)
return True return True

View file

@ -12,3 +12,25 @@ commit -a`). Afterwards, `git status` then smudged it again, unsure why!
--[[Joey]] --[[Joey]]
[[!tag confirmed]] [[!tag confirmed]]
> I wondered if this was still a problem in a v9 repository with
> filter-process used instead of smudge. It's not really -- after unlocking
> 1000 files, git status did need to refresh all 1000, but it ran
> relatively quickly because it was able to use filter-process.
>
> But, those were small files. Large files would make it slower as it pipes
> their content though. It would be better for Command.Unlock to use
> restagePointerFile, so whatever price there is is paid during unlocking
> and not unexpectedly later on.
>
> I tried again making Command.Unlock use restagePointerFile, and this
> slowed git-annex unlock. But git status did then avoid doing any more
> smudgeing. It seems that each call to restagePointerFile is running
> git update-index, so still one git-annex smudge per file, rather
> than combining several together.
>
> That's because restagePointerFile uses the git queue, and unlock
> also queues a git add or something, so the queue isn't able to built
> up because two dissimilar things are being queued. This seems an
> unncessary behavior; it could queue up all the git adds and then
> run restagePointerFile after them all.