push RawFilePath down into Annex.ReplaceFile

Minor optimisation, but a win in every case, except for a couple where
it's a wash.

Note that replaceFile still takes a FilePath, because it needs to
operate on Chars to truncate unicode filenames properly.
This commit is contained in:
Joey Hess 2023-10-26 13:36:49 -04:00
parent c873586e14
commit d9fd205cbb
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
12 changed files with 38 additions and 44 deletions

View file

@ -242,7 +242,7 @@ resolveMerge' unstagedmap (Just us) them inoverlay u = do
stageSymlink dest' =<< hashSymlink l stageSymlink dest' =<< hashSymlink l
replacewithsymlink dest link = replaceWorkTreeFile dest $ replacewithsymlink dest link = replaceWorkTreeFile dest $
makeGitLink link . toRawFilePath makeGitLink link
makepointer key dest destmode = do makepointer key dest destmode = do
unless inoverlay $ unless inoverlay $
@ -267,10 +267,10 @@ resolveMerge' unstagedmap (Just us) them inoverlay u = do
Nothing -> noop Nothing -> noop
Just sha -> replaceWorkTreeFile item $ \tmp -> do Just sha -> replaceWorkTreeFile item $ \tmp -> do
c <- catObject sha c <- catObject sha
liftIO $ L.writeFile tmp c liftIO $ L.writeFile (decodeBS tmp) c
when isexecutable $ when isexecutable $
liftIO $ void $ tryIO $ liftIO $ void $ tryIO $
modifyFileMode (toRawFilePath tmp) $ modifyFileMode tmp $
addModes executeModes addModes executeModes
-- Update the work tree to reflect the graft. -- Update the work tree to reflect the graft.

View file

@ -477,7 +477,7 @@ linkToAnnex key src srcic = ifM (checkSecureHashes' key)
linkFromAnnex :: Key -> RawFilePath -> Maybe FileMode -> Annex LinkAnnexResult linkFromAnnex :: Key -> RawFilePath -> Maybe FileMode -> Annex LinkAnnexResult
linkFromAnnex key dest destmode = linkFromAnnex key dest destmode =
replaceFile' (const noop) (fromRawFilePath dest) (== LinkAnnexOk) $ \tmp -> replaceFile' (const noop) (fromRawFilePath dest) (== LinkAnnexOk) $ \tmp ->
linkFromAnnex' key (toRawFilePath tmp) destmode linkFromAnnex' key tmp destmode
{- This is only safe to use when dest is not a worktree file. -} {- This is only safe to use when dest is not a worktree file. -}
linkFromAnnex' :: Key -> RawFilePath -> Maybe FileMode -> Annex LinkAnnexResult linkFromAnnex' :: Key -> RawFilePath -> Maybe FileMode -> Annex LinkAnnexResult

View file

@ -38,11 +38,10 @@ populatePointerFile restage k obj f = go =<< liftIO (isPointerFile f)
destmode <- liftIO $ catchMaybeIO $ fileMode <$> R.getFileStatus f destmode <- liftIO $ catchMaybeIO $ fileMode <$> R.getFileStatus f
liftIO $ removeWhenExistsWith R.removeLink f liftIO $ removeWhenExistsWith R.removeLink f
(ic, populated) <- replaceWorkTreeFile f' $ \tmp -> do (ic, populated) <- replaceWorkTreeFile f' $ \tmp -> do
let tmp' = toRawFilePath tmp ok <- linkOrCopy k obj tmp destmode >>= \case
ok <- linkOrCopy k obj tmp' destmode >>= \case Just _ -> thawContent tmp >> return True
Just _ -> thawContent tmp' >> return True Nothing -> liftIO (writePointerFile tmp k destmode) >> return False
Nothing -> liftIO (writePointerFile tmp' k destmode) >> return False ic <- withTSDelta (liftIO . genInodeCache tmp)
ic <- withTSDelta (liftIO . genInodeCache tmp')
return (ic, ok) return (ic, ok)
maybe noop (restagePointerFile restage f) ic maybe noop (restagePointerFile restage f) ic
if populated if populated
@ -60,14 +59,13 @@ depopulatePointerFile key file = do
secureErase file secureErase file
liftIO $ removeWhenExistsWith R.removeLink file liftIO $ removeWhenExistsWith R.removeLink file
ic <- replaceWorkTreeFile (fromRawFilePath file) $ \tmp -> do ic <- replaceWorkTreeFile (fromRawFilePath file) $ \tmp -> do
let tmp' = toRawFilePath tmp liftIO $ writePointerFile tmp key mode
liftIO $ writePointerFile tmp' key mode
#if ! defined(mingw32_HOST_OS) #if ! defined(mingw32_HOST_OS)
-- Don't advance mtime; this avoids unnecessary re-smudging -- Don't advance mtime; this avoids unnecessary re-smudging
-- by git in some cases. -- by git in some cases.
liftIO $ maybe noop liftIO $ maybe noop
(\t -> touch tmp' t False) (\t -> touch tmp t False)
(fmap Posix.modificationTimeHiRes st) (fmap Posix.modificationTimeHiRes st)
#endif #endif
withTSDelta (liftIO . genInodeCache tmp') withTSDelta (liftIO . genInodeCache tmp)
maybe noop (restagePointerFile (Restage True) file) ic maybe noop (restagePointerFile (Restage True) file) ic

View file

@ -306,7 +306,7 @@ restoreFile file key e = do
makeLink :: RawFilePath -> Key -> Maybe InodeCache -> Annex LinkTarget makeLink :: RawFilePath -> Key -> Maybe InodeCache -> Annex LinkTarget
makeLink file key mcache = flip catchNonAsync (restoreFile file key) $ do makeLink file key mcache = flip catchNonAsync (restoreFile file key) $ do
l <- calcRepo $ gitAnnexLink file key l <- calcRepo $ gitAnnexLink file key
replaceWorkTreeFile file' $ makeAnnexLink l . toRawFilePath replaceWorkTreeFile file' $ makeAnnexLink l
-- touch symlink to have same time as the original file, -- touch symlink to have same time as the original file,
-- as provided in the InodeCache -- as provided in the InodeCache

View file

@ -26,17 +26,17 @@ import Utility.Path.Max
#endif #endif
{- replaceFile on a file located inside the gitAnnexDir. -} {- replaceFile on a file located inside the gitAnnexDir. -}
replaceGitAnnexDirFile :: FilePath -> (FilePath -> Annex a) -> Annex a replaceGitAnnexDirFile :: FilePath -> (RawFilePath -> Annex a) -> Annex a
replaceGitAnnexDirFile = replaceFile createAnnexDirectory replaceGitAnnexDirFile = replaceFile createAnnexDirectory
{- replaceFile on a file located inside the .git directory. -} {- replaceFile on a file located inside the .git directory. -}
replaceGitDirFile :: FilePath -> (FilePath -> Annex a) -> Annex a replaceGitDirFile :: FilePath -> (RawFilePath -> Annex a) -> Annex a
replaceGitDirFile = replaceFile $ \dir -> do replaceGitDirFile = replaceFile $ \dir -> do
top <- fromRepo localGitDir top <- fromRepo localGitDir
liftIO $ createDirectoryUnder [top] dir liftIO $ createDirectoryUnder [top] dir
{- replaceFile on a worktree file. -} {- replaceFile on a worktree file. -}
replaceWorkTreeFile :: FilePath -> (FilePath -> Annex a) -> Annex a replaceWorkTreeFile :: FilePath -> (RawFilePath -> Annex a) -> Annex a
replaceWorkTreeFile = replaceFile createWorkTreeDirectory replaceWorkTreeFile = replaceFile createWorkTreeDirectory
{- Replaces a possibly already existing file with a new version, {- Replaces a possibly already existing file with a new version,
@ -54,10 +54,10 @@ replaceWorkTreeFile = replaceFile createWorkTreeDirectory
- The createdirectory action is only run when moving the file into place - The createdirectory action is only run when moving the file into place
- fails, and can create any parent directory structure needed. - fails, and can create any parent directory structure needed.
-} -}
replaceFile :: (RawFilePath -> Annex ()) -> FilePath -> (FilePath -> Annex a) -> Annex a replaceFile :: (RawFilePath -> Annex ()) -> FilePath -> (RawFilePath -> Annex a) -> Annex a
replaceFile createdirectory file action = replaceFile' createdirectory file (const True) action replaceFile createdirectory file action = replaceFile' createdirectory file (const True) action
replaceFile' :: (RawFilePath -> Annex ()) -> FilePath -> (a -> Bool) -> (FilePath -> Annex a) -> Annex a replaceFile' :: (RawFilePath -> Annex ()) -> FilePath -> (a -> Bool) -> (RawFilePath -> Annex a) -> Annex a
replaceFile' createdirectory file checkres action = withOtherTmp $ \othertmpdir -> do replaceFile' createdirectory file checkres action = withOtherTmp $ \othertmpdir -> do
let othertmpdir' = fromRawFilePath othertmpdir let othertmpdir' = fromRawFilePath othertmpdir
#ifndef mingw32_HOST_OS #ifndef mingw32_HOST_OS
@ -72,10 +72,10 @@ replaceFile' createdirectory file checkres action = withOtherTmp $ \othertmpdir
let basetmp = "t" let basetmp = "t"
#endif #endif
withTmpDirIn othertmpdir' basetmp $ \tmpdir -> do withTmpDirIn othertmpdir' basetmp $ \tmpdir -> do
let tmpfile = tmpdir </> basetmp let tmpfile = toRawFilePath (tmpdir </> basetmp)
r <- action tmpfile r <- action tmpfile
when (checkres r) $ when (checkres r) $
replaceFileFrom (toRawFilePath tmpfile) (toRawFilePath file) createdirectory replaceFileFrom tmpfile (toRawFilePath file) createdirectory
return r return r
replaceFileFrom :: RawFilePath -> RawFilePath -> (RawFilePath -> Annex ()) -> Annex () replaceFileFrom :: RawFilePath -> RawFilePath -> (RawFilePath -> Annex ()) -> Annex ()

View file

@ -293,7 +293,7 @@ onAddSymlink' linktarget mk file filestatus = go mk
then ensurestaged (Just link) =<< getDaemonStatus then ensurestaged (Just link) =<< getDaemonStatus
else do else do
liftAnnex $ replaceWorkTreeFile file $ liftAnnex $ replaceWorkTreeFile file $
makeAnnexLink link . toRawFilePath makeAnnexLink link
addLink file link (Just key) addLink file link (Just key)
-- other symlink, not git-annex -- other symlink, not git-annex
go Nothing = ensurestaged linktarget =<< getDaemonStatus go Nothing = ensurestaged linktarget =<< getDaemonStatus

View file

@ -73,12 +73,11 @@ start fixwhat si file key = do
breakHardLink :: RawFilePath -> Key -> RawFilePath -> CommandPerform breakHardLink :: RawFilePath -> Key -> RawFilePath -> CommandPerform
breakHardLink file key obj = do breakHardLink file key obj = do
replaceWorkTreeFile (fromRawFilePath file) $ \tmp -> do replaceWorkTreeFile (fromRawFilePath file) $ \tmp -> do
let tmp' = toRawFilePath tmp
mode <- liftIO $ catchMaybeIO $ fileMode <$> R.getFileStatus file mode <- liftIO $ catchMaybeIO $ fileMode <$> R.getFileStatus file
unlessM (checkedCopyFile key obj tmp' mode) $ unlessM (checkedCopyFile key obj tmp mode) $
giveup "unable to break hard link" giveup "unable to break hard link"
thawContent tmp' thawContent tmp
Database.Keys.storeInodeCaches key [tmp'] Database.Keys.storeInodeCaches key [tmp]
modifyContentDir obj $ freezeContent obj modifyContentDir obj $ freezeContent obj
next $ return True next $ return True
@ -86,7 +85,7 @@ makeHardLink :: RawFilePath -> Key -> CommandPerform
makeHardLink file key = do makeHardLink file key = do
replaceWorkTreeFile (fromRawFilePath file) $ \tmp -> do replaceWorkTreeFile (fromRawFilePath file) $ \tmp -> do
mode <- liftIO $ catchMaybeIO $ fileMode <$> R.getFileStatus file mode <- liftIO $ catchMaybeIO $ fileMode <$> R.getFileStatus file
linkFromAnnex' key (toRawFilePath tmp) mode >>= \case linkFromAnnex' key tmp mode >>= \case
LinkAnnexFailed -> giveup "unable to make hard link" LinkAnnexFailed -> giveup "unable to make hard link"
_ -> noop _ -> noop
next $ return True next $ return True
@ -99,10 +98,9 @@ fixSymlink file link = do
<$> R.getSymbolicLinkStatus file <$> R.getSymbolicLinkStatus file
#endif #endif
replaceWorkTreeFile (fromRawFilePath file) $ \tmpfile -> do replaceWorkTreeFile (fromRawFilePath file) $ \tmpfile -> do
let tmpfile' = toRawFilePath tmpfile liftIO $ R.createSymbolicLink link tmpfile
liftIO $ R.createSymbolicLink link tmpfile'
#if ! defined(mingw32_HOST_OS) #if ! defined(mingw32_HOST_OS)
liftIO $ maybe noop (\t -> touch tmpfile' t False) mtime liftIO $ maybe noop (\t -> touch tmpfile t False) mtime
#endif #endif
stageSymlink file =<< hashSymlink link stageSymlink file =<< hashSymlink link
next $ return True next $ return True

View file

@ -417,16 +417,15 @@ verifyWorkTree key file = do
Just k | k == key -> whenM (inAnnex key) $ do Just k | k == key -> whenM (inAnnex key) $ do
showNote "fixing worktree content" showNote "fixing worktree content"
replaceWorkTreeFile (fromRawFilePath file) $ \tmp -> do replaceWorkTreeFile (fromRawFilePath file) $ \tmp -> do
let tmp' = toRawFilePath tmp
mode <- liftIO $ catchMaybeIO $ fileMode <$> R.getFileStatus file mode <- liftIO $ catchMaybeIO $ fileMode <$> R.getFileStatus file
ifM (annexThin <$> Annex.getGitConfig) ifM (annexThin <$> Annex.getGitConfig)
( void $ linkFromAnnex' key tmp' mode ( void $ linkFromAnnex' key tmp mode
, do , do
obj <- calcRepo (gitAnnexLocation key) obj <- calcRepo (gitAnnexLocation key)
void $ checkedCopyFile key obj tmp' mode void $ checkedCopyFile key obj tmp mode
thawContent tmp' thawContent tmp
) )
Database.Keys.storeInodeCaches key [tmp'] Database.Keys.storeInodeCaches key [tmp]
_ -> return () _ -> return ()
return True return True

View file

@ -79,7 +79,7 @@ perform file key = do
mfc <- withTSDelta (liftIO . genInodeCache file) mfc <- withTSDelta (liftIO . genInodeCache file)
unlessM (sameInodeCache obj (maybeToList mfc)) $ do unlessM (sameInodeCache obj (maybeToList mfc)) $ do
modifyContentDir obj $ replaceGitAnnexDirFile (fromRawFilePath obj) $ \tmp -> do modifyContentDir obj $ replaceGitAnnexDirFile (fromRawFilePath obj) $ \tmp -> do
unlessM (checkedCopyFile key obj (toRawFilePath tmp) Nothing) $ unlessM (checkedCopyFile key obj tmp Nothing) $
giveup "unable to lock file" giveup "unable to lock file"
Database.Keys.storeInodeCaches key [obj] Database.Keys.storeInodeCaches key [obj]

View file

@ -111,10 +111,9 @@ linkKey file oldkey newkey = ifM (isJust <$> isAnnexLink file)
when (linkCount st > 1) $ do when (linkCount st > 1) $ do
freezeContent oldobj freezeContent oldobj
replaceWorkTreeFile (fromRawFilePath file) $ \tmp -> do replaceWorkTreeFile (fromRawFilePath file) $ \tmp -> do
let tmp' = toRawFilePath tmp unlessM (checkedCopyFile oldkey oldobj tmp Nothing) $
unlessM (checkedCopyFile oldkey oldobj tmp' Nothing) $
giveup "can't lock old key" giveup "can't lock old key"
thawContent tmp' thawContent tmp
ic <- withTSDelta (liftIO . genInodeCache file) ic <- withTSDelta (liftIO . genInodeCache file)
case v of case v of
Left e -> do Left e -> do

View file

@ -54,14 +54,14 @@ perform dest key = do
destic <- replaceWorkTreeFile (fromRawFilePath dest) $ \tmp -> do destic <- replaceWorkTreeFile (fromRawFilePath dest) $ \tmp -> do
ifM (inAnnex key) ifM (inAnnex key)
( do ( do
r <- linkFromAnnex' key (toRawFilePath tmp) destmode r <- linkFromAnnex' key tmp destmode
case r of case r of
LinkAnnexOk -> return () LinkAnnexOk -> return ()
LinkAnnexNoop -> return () LinkAnnexNoop -> return ()
LinkAnnexFailed -> giveup "unlock failed" LinkAnnexFailed -> giveup "unlock failed"
, liftIO $ writePointerFile (toRawFilePath tmp) key destmode , liftIO $ writePointerFile tmp key destmode
) )
withTSDelta (liftIO . genInodeCache (toRawFilePath tmp)) withTSDelta (liftIO . genInodeCache tmp)
next $ cleanup dest destic key destmode next $ cleanup dest destic key destmode
cleanup :: RawFilePath -> Maybe InodeCache -> Key -> Maybe FileMode -> CommandCleanup cleanup :: RawFilePath -> Maybe InodeCache -> Key -> Maybe FileMode -> CommandCleanup

View file

@ -47,8 +47,8 @@ withLogHandle f a = do
bracket (setup tmp) cleanup a bracket (setup tmp) cleanup a
where where
setup tmp = do setup tmp = do
setAnnexFilePerm (toRawFilePath tmp) setAnnexFilePerm tmp
liftIO $ openFile tmp WriteMode liftIO $ openFile (fromRawFilePath tmp) WriteMode
cleanup h = liftIO $ hClose h cleanup h = liftIO $ hClose h
-- | Appends a line to a log file, first locking it to prevent -- | Appends a line to a log file, first locking it to prevent