assistant: Bug fix to avoid annexing the files that git uses to stand in for symlinks on FAT and other filesystem not supporting symlinks.

also, blog for the day..
This commit is contained in:
Joey Hess 2013-04-10 19:57:11 -04:00
parent 271a919d14
commit 04a27ad926
4 changed files with 79 additions and 17 deletions

View file

@ -80,7 +80,10 @@ runWatcher = do
startup <- asIO1 startupScan
matcher <- liftAnnex $ largeFilesMatcher
direct <- liftAnnex isDirect
addhook <- hook $ if direct then onAddDirect matcher else onAdd matcher
symlinkssupported <- liftAnnex $ coreSymlinks <$> Annex.getGitConfig
addhook <- hook $ if direct
then onAddDirect symlinkssupported matcher
else onAdd matcher
delhook <- hook onDel
addsymlinkhook <- hook $ onAddSymlink direct
deldirhook <- hook onDelDir
@ -188,9 +191,10 @@ onAdd matcher file filestatus
| otherwise = noChange
{- In direct mode, add events are received for both new files, and
- modified existing files. -}
onAddDirect :: FileMatcher -> Handler
onAddDirect matcher file fs = do
- modified existing files.
-}
onAddDirect :: Bool -> FileMatcher -> Handler
onAddDirect symlinkssupported matcher file fs = do
v <- liftAnnex $ catKeyFile file
case (v, fs) of
(Just key, Just filestatus) ->
@ -203,37 +207,59 @@ onAddDirect matcher file fs = do
( do
link <- liftAnnex $ inRepo $ gitAnnexLink file key
addLink file link (Just key)
, do
, guardSymlinkStandin (Just key) $ do
debug ["changed direct", file]
liftAnnex $ changedDirect key file
add matcher file
)
_ -> do
_ -> guardSymlinkStandin Nothing $ do
debug ["add direct", file]
add matcher file
where
{- On a filesystem without symlinks, we'll get changes for regular
- files that git uses to stand-in for symlinks. Detect when
- this happens, and stage the symlink, rather than annexing the
- file. -}
guardSymlinkStandin mk a
| symlinkssupported = a
| otherwise = do
linktarget <- liftAnnex $ getAnnexLinkTarget file
liftIO $ print (file, linktarget)
case linktarget of
Nothing -> a
Just lt -> do
case fileKey $ takeFileName lt of
Nothing -> noop
Just key -> void $ liftAnnex $
addAssociatedFile key file
onAddSymlink' linktarget mk True file fs
{- A symlink might be an arbitrary symlink, which is just added.
- Or, if it is a git-annex symlink, ensure it points to the content
- before adding it.
-}
onAddSymlink :: Bool -> Handler
onAddSymlink isdirect file filestatus = go =<< liftAnnex (Backend.lookupFile file)
onAddSymlink isdirect file filestatus = do
linktarget <- liftIO (catchMaybeIO $ readSymbolicLink file)
kv <- liftAnnex (Backend.lookupFile file)
onAddSymlink' linktarget (fmap fst kv) isdirect file filestatus
onAddSymlink' :: Maybe String -> Maybe Key -> Bool -> Handler
onAddSymlink' linktarget mk isdirect file filestatus = go mk
where
go (Just (key, _)) = do
go (Just key) = do
when isdirect $
liftAnnex $ void $ addAssociatedFile key file
link <- liftAnnex $ inRepo $ gitAnnexLink file key
ifM ((==) (Just link) <$> liftIO (catchMaybeIO $ readSymbolicLink file))
( ensurestaged (Just link) (Just key) =<< getDaemonStatus
, do
if linktarget == Just link
then ensurestaged (Just link) =<< getDaemonStatus
else do
unless isdirect $
liftAnnex $ replaceFile file $
makeAnnexLink link
addLink file link (Just key)
)
go Nothing = do -- other symlink
mlink <- liftIO (catchMaybeIO $ readSymbolicLink file)
ensurestaged mlink Nothing =<< getDaemonStatus
-- other symlink, not git-annex
go Nothing = ensurestaged linktarget =<< getDaemonStatus
{- This is often called on symlinks that are already
- staged correctly. A symlink may have been deleted
@ -246,13 +272,13 @@ onAddSymlink isdirect file filestatus = go =<< liftAnnex (Backend.lookupFile fil
- (If the daemon has never ran before, avoid staging
- links too.)
-}
ensurestaged (Just link) mk daemonstatus
ensurestaged (Just link) daemonstatus
| scanComplete daemonstatus = addLink file link mk
| otherwise = case filestatus of
Just s
| not (afterLastDaemonRun (statusChangeTime s) daemonstatus) -> noChange
_ -> addLink file link mk
ensurestaged Nothing _ _ = noChange
ensurestaged Nothing _ = noChange
{- For speed, tries to reuse the existing blob for symlink target. -}
addLink :: FilePath -> FilePath -> Maybe Key -> Assistant (Maybe Change)

3
debian/changelog vendored
View file

@ -19,6 +19,9 @@ git-annex (4.20130406) UNRELEASED; urgency=low
* webapp: Added animations.
* assistant: Stop any transfers the assistant initiated on shutdown.
* assistant: Added sequence numbers to XMPP git push packets. (Not yet used.)
* assistant: Bug fix to avoid annexing the files that git uses
to stand in for symlinks on FAT and other filesystem not supporting
symlinks.
-- Joey Hess <joeyh@debian.org> Sat, 06 Apr 2013 15:24:15 -0400

View file

@ -16,3 +16,7 @@ Linux
Please provide any additional information below.
> Reproduced the core bug, which is that the assistant saw symlink standin
> files as new files, and annexed them. Now it doesn't, and I have
> it running on FAT with no trouble; can even rename symlink standin files
> and it commits symlink changes. Calling this [[done]]. --[[Joey]]

View file

@ -0,0 +1,29 @@
Short day because I spent 3 hours this morning explaining free software
and kickstarter to an accountant. And was away until 3 pm, so how did I get
all this done‽
Eliot pointed out that shutting down the assistant could leave transfers
running. This happened because `git annex transferkeys` is a separate
process, and so it was left to finish up any transfer that was in
process. I've made shutdown stop all transfers that the
assistant started. (Other paired computers could still be connecting to
make transfers even when the assistant is not running, and those are not
affected.)
Added sequence numbers to the XMPP messages used for git pushes. While
these numbers are not used yet, they're available for debugging, and will
help me determine if packets are lost or come out of order. So if you have
experienced problems with XMPP syncing sometimes failing, run tonight's
build of the assistant with `--debug` (or turn on debugging in the webapp
configuration screen), and send me a log by email to
<debuglogs201204@joeyh.name>
Changed the way that autobuilds and manual builds report their version
number. It now includes the date of the last commit, and the abbreviated
commit ID, rather than being some random date after the last release.
Frederik found a bug using the assistant on a FAT filesystem. It didn't
properly handle the files that git uses to stand-in for symlinks in that
situation, and annexed those files. I've fixed this, and even moving
around symlink stand-in files on a FAT filesystem now results in correct
changes to symlinks being committed.