sync: Bug fix, avoid adding to the annex the dummy symlinks used on crippled filesystems.

The root of the problem is that toInodeCache sees a non-symlink, and so
goes on and generates a new inode cache for the dummy symlink.

Any place that toInodeCache, or sameFileStatus, or genInodeCache are called
may need to deal with this case. Although many of them are ok. For example,
prepSendAnnex calls sameInodeCache, which calls genInodeCache.. but if
the file content is not present, the InodeCache generated for its standin
file is appropriately not the same, and so it returns Nothing.

I've audited some, but have to say I'm not happy with this; it should be
handled at the type level somehow, or a toInodeCache wrapper be used that
is aware of dummy symlinks.

(The Watcher already dealt with it, via the guardSymlinkStandin function.)
This commit is contained in:
Joey Hess 2013-04-23 17:13:09 -04:00
parent 16503f5692
commit 07580dc3df
2 changed files with 18 additions and 6 deletions

View file

@ -43,10 +43,15 @@ stageDirect = do
- efficiently as we can, by getting any key that's associated
- with it in git, as well as its stat info. -}
go (file, Just sha) = do
mkey <- catKey sha
shakey <- catKey sha
mstat <- liftIO $ catchMaybeIO $ getSymbolicLinkStatus file
case (mkey, mstat, toInodeCache =<< mstat) of
(Just key, _, Just cache) -> do
filekey <- isAnnexLink file
case (shakey, filekey, mstat, toInodeCache =<< mstat) of
(_, Just key, _, _)
| shakey == filekey -> noop
{- A changed symlink. -}
| otherwise -> stageannexlink file key
(Just key, _, _, Just cache) -> do
{- All direct mode files will show as
- modified, so compare the cache to see if
- it really was. -}
@ -55,9 +60,9 @@ stageDirect = do
[] -> modifiedannexed file key cache
_ -> unlessM (elemInodeCaches cache oldcache) $
modifiedannexed file key cache
(Just key, Nothing, _) -> deletedannexed file key
(Nothing, Nothing, _) -> deletegit file
(_, Just _, _) -> addgit file
(Just key, _, Nothing, _) -> deletedannexed file key
(Nothing, _, Nothing, _) -> deletegit file
(_, _, Just _, _) -> addgit file
go _ = noop
modifiedannexed file oldkey cache = do
@ -68,6 +73,11 @@ stageDirect = do
void $ removeAssociatedFile key file
deletegit file
stageannexlink file key = do
l <- inRepo $ gitAnnexLink file key
stageSymlink file =<< hashSymlink l
void $ addAssociatedFile key file
addgit file = Annex.Queue.addCommand "add" [Param "-f"] [file]
deletegit file = Annex.Queue.addCommand "rm" [Param "-f"] [file]

2
debian/changelog vendored
View file

@ -21,6 +21,8 @@ git-annex (4.20130418) UNRELEASED; urgency=low
* assistant: When built with git before 1.8.0, use `git remote rm`
to delete a remote. Newer git uses `git remote remove`.
* rmurl: New command, removes one of the recorded urls for a file.
* sync: Bug fix, avoid adding to the annex the
dummy symlinks used on crippled filesystems.
-- Joey Hess <joeyh@debian.org> Thu, 18 Apr 2013 16:22:48 -0400