summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Joey Hess <joeyh@joeyh.name>2015-11-06 15:28:20 -0400
committerGravatar Joey Hess <joeyh@joeyh.name>2015-11-06 15:28:20 -0400
commit90d833e44240dd0a83fd2439fa1a23e490959235 (patch)
tree9a0f4bed733aa274422d932c761b972a754cdd34
parentd2ab9f9c90e8a73f99bfad452fd17cc2f77ad230 (diff)
add: Fix error recovery rollback to not move the injested file content out of the annex back to the file, because other files may point to that same content. Instead, copy the injected file content out to recover.
That was not a data loss, but it came close!
-rw-r--r--Annex/Content.hs8
-rw-r--r--Command/Add.hs15
-rw-r--r--debian/changelog4
3 files changed, 11 insertions, 16 deletions
diff --git a/Annex/Content.hs b/Annex/Content.hs
index 9648083cb..bc28cc6b4 100644
--- a/Annex/Content.hs
+++ b/Annex/Content.hs
@@ -27,7 +27,6 @@ module Annex.Content (
sendAnnex,
prepSendAnnex,
removeAnnex,
- fromAnnex,
moveBad,
KeyLocation(..),
getKeysPresent,
@@ -573,13 +572,6 @@ secureErase file = maybe noop go =<< annexSecureEraseCommand <$> Annex.getGitCon
boolSystem "sh" [Param "-c", Param $ gencmd basecmd]
gencmd = massReplace [ ("%file", shellEscape file) ]
-{- Moves a key's file out of .git/annex/objects/ -}
-fromAnnex :: Key -> FilePath -> Annex ()
-fromAnnex key dest = cleanObjectLoc key $ do
- file <- calcRepo $ gitAnnexLocation key
- thawContent file
- liftIO $ moveFile file dest
-
{- Moves a key out of .git/annex/objects/ into .git/annex/bad, and
- returns the file it was moved to. -}
moveBad :: Key -> Annex FilePath
diff --git a/Command/Add.hs b/Command/Add.hs
index 94a19fba5..fd92f04ef 100644
--- a/Command/Add.hs
+++ b/Command/Add.hs
@@ -31,6 +31,7 @@ import Utility.InodeCache
import Annex.FileMatcher
import Annex.ReplaceFile
import Utility.Tmp
+import Utility.CopyFile
import Control.Exception (IOException)
@@ -244,15 +245,13 @@ undo :: FilePath -> Key -> SomeException -> Annex a
undo file key e = do
whenM (inAnnex key) $ do
liftIO $ nukeFile file
- catchNonAsync (fromAnnex key file) tryharder
- logStatus key InfoMissing
+ -- The key could be used by other files too, so leave the
+ -- content in the annex, and make a copy back to the file.
+ obj <- calcRepo $ gitAnnexLocation key
+ unlessM (liftIO $ copyFileExternal CopyTimeStamps obj file) $
+ warning $ "Unable to restore content of " ++ file ++ "; it should be located in " ++ obj
+ thawContent file
throwM e
- where
- -- fromAnnex could fail if the file ownership is weird
- tryharder :: SomeException -> Annex ()
- tryharder _ = do
- src <- calcRepo $ gitAnnexLocation key
- liftIO $ moveFile src file
{- Creates the symlink to the annexed content, returns the link target. -}
link :: FilePath -> Key -> Maybe InodeCache -> Annex String
diff --git a/debian/changelog b/debian/changelog
index 4f10ff57d..43eddfa0d 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -10,6 +10,10 @@ git-annex (5.20151102.2) UNRELEASED; urgency=medium
that moves file contents around.
* Fix race that could result in an annexed file's symlink not being
created, when eg, running concurrent git-annex adds.
+ * add: Fix error recovery rollback to not move the injested file content
+ out of the annex back to the file, because other files may point to
+ that same content. Instead, copy the injected file content out to
+ recover.
-- Joey Hess <id@joeyh.name> Wed, 04 Nov 2015 12:50:20 -0400