summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Joey Hess <joey@kitenet.net>2013-02-05 16:48:00 -0400
committerGravatar Joey Hess <joey@kitenet.net>2013-02-05 16:48:00 -0400
commit4b690643b335b8892a0fb3b8cb05b7b50f987a36 (patch)
tree79a566f701cada6d870c388a5f8447aa9b255ee5
parent053587b22832cc0db37055ee90ebd9bb066b29d9 (diff)
Deal with stale mappings for deleted file in direct mode.
The most common way for a mapping to be stale is when a file was deleted, or renamed. Nothing updates the mappings for deletions yet. But they can also become stale in other ways. For example a file can be modified. So, the mapping is not trusted to be consistent. When we get a key, only replace symlinks that still point to that key with its content. When we drop a key, only put back symlinks for files that still have the direct mode content.
-rw-r--r--Annex/Content.hs19
-rw-r--r--debian/changelog1
-rw-r--r--doc/design/assistant/desymlink.mdwn6
3 files changed, 22 insertions, 4 deletions
diff --git a/Annex/Content.hs b/Annex/Content.hs
index feb1d25e6..87ff3f692 100644
--- a/Annex/Content.hs
+++ b/Annex/Content.hs
@@ -247,8 +247,18 @@ moveAnnex key src = withObjectLoc key storeobject storedirect
freezeContent dest
freezeContentDir dest
)
- storedirect [] = storeobject =<< inRepo (gitAnnexLocation key)
- storedirect (dest:fs) = do
+ storedirect fs = storedirect' =<< liftIO (filterM validsymlink fs)
+
+ validsymlink f = do
+ tl <- tryIO $ readSymbolicLink f
+ return $ case tl of
+ Right l
+ | isLinkToAnnex l ->
+ Just key == fileKey (takeFileName l)
+ _ -> False
+
+ storedirect' [] = storeobject =<< inRepo (gitAnnexLocation key)
+ storedirect' (dest:fs) = do
updateCache key src
thawContent src
liftIO $ replaceFile dest $ moveFile src
@@ -345,9 +355,10 @@ removeAnnex key = withObjectLoc key remove removedirect
removeFile file
cleanObjectLoc key
removedirect fs = do
+ cache <- recordedCache key
removeCache key
- mapM_ resetfile fs
- resetfile f = do
+ mapM_ (resetfile cache) fs
+ resetfile cache f = whenM (compareCache f cache) $ do
l <- calcGitLink f key
top <- fromRepo Git.repoPath
cwd <- liftIO getCurrentDirectory
diff --git a/debian/changelog b/debian/changelog
index 05ceb00b9..c289794c9 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -9,6 +9,7 @@ git-annex (3.20130125) UNRELEASED; urgency=low
and other tasks.
* assistant: Ignore .DS_Store on OSX.
* assistant: Fix location log when adding new file in direct mode.
+ * Deal with stale mappings for deleted file in direct mode.
-- Joey Hess <joeyh@debian.org> Sat, 26 Jan 2013 15:48:40 +1100
diff --git a/doc/design/assistant/desymlink.mdwn b/doc/design/assistant/desymlink.mdwn
index 64c56f466..05f965358 100644
--- a/doc/design/assistant/desymlink.mdwn
+++ b/doc/design/assistant/desymlink.mdwn
@@ -87,6 +87,12 @@ is converted to a real file when it becomes present.
* kqueue does not deliver an event when an existing file is modified.
This doesn't affect OSX, which uses FSEvents now, but it makes direct
mode assistant not 100% on other BSD's.
+* The mapping is not updated when files are deleted (or for the deletion
+ part of a rename). So it can contain old filenames that are no longer in
+ use. Code that uses the mapping has to take care to check that the
+ files they refer to exists, which is a good idea anyway. But,
+ it would be good to at some point update the mappings to remove deleted
+ files (fsck does this FWIW).
## done