dropunused edge case when annex.thin caused unused object to be modified

dropunused: When an unused object file has gotten modified, eg due to
annex.thin being set, don't silently skip it, but display a warning and let
--force drop it.

This commit was sponsored by Ethan Aubin.
This commit is contained in:
Joey Hess 2018-12-04 12:20:34 -04:00
parent 96d2000570
commit aa8243df4c
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
5 changed files with 63 additions and 3 deletions

View file

@ -12,6 +12,7 @@ module Annex.Content (
inAnnex',
inAnnexSafe,
inAnnexCheck,
objectFileExists,
lockContentShared,
lockContentForRemoval,
ContentRemovalLock,
@ -131,6 +132,11 @@ inAnnex' isgood bad check key = withObjectLoc key checkindirect checkdirect
)
else checkdirect locs
{- Like inAnnex, checks if the object file for a key exists,
- but there are no guarantees it has the right content. -}
objectFileExists :: Key -> Annex Bool
objectFileExists key = calcRepo (gitAnnexLocation key) >>= liftIO . doesFileExist
{- A safer check; the key's content must not only be present, but
- is not in the process of being removed. -}
inAnnexSafe :: Key -> Annex (Maybe Bool)

View file

@ -12,6 +12,9 @@ git-annex (7.20181122) UNRELEASED; urgency=medium
* info: When used with an exporttree remote, includes an "exportedtree"
info, which is the tree last exported to the remote. During an export
conflict, multiple values will be listed.
* dropunused: When an unused object file has gotten modified, eg due to
annex.thin being set, don't silently skip it, but display a warning
and let --force drop it.
-- Joey Hess <id@joeyh.name> Tue, 27 Nov 2018 12:29:27 -0400

View file

@ -1,6 +1,6 @@
{- git-annex command
-
- Copyright 2010,2012 Joey Hess <id@joeyh.name>
- Copyright 2010,2012,2018 Joey Hess <id@joeyh.name>
-
- Licensed under the GNU GPL version 3 or higher.
-}
@ -8,6 +8,7 @@
module Command.DropUnused where
import Command
import qualified Annex
import qualified Command.Drop
import qualified Remote
import qualified Git
@ -48,9 +49,19 @@ perform from numcopies key = case from of
showAction $ "from " ++ Remote.name r
Command.Drop.performRemote key (AssociatedFile Nothing) numcopies r
Nothing -> ifM (inAnnex key)
( Command.Drop.performLocal key (AssociatedFile Nothing) numcopies []
, next (return True)
( droplocal
, ifM (objectFileExists key)
( ifM (Annex.getState Annex.force)
( droplocal
, do
warning "Annexed object has been modified and dropping it would probably lose the only copy. Run this command with --force if you want to drop it anyway."
next $ return False
)
, next $ return True
)
)
where
droplocal = Command.Drop.performLocal key (AssociatedFile Nothing) numcopies []
performOther :: (Key -> Git.Repo -> FilePath) -> Key -> CommandPerform
performOther filespec key = do

View file

@ -0,0 +1,14 @@
[[!comment format=mdwn
username="joey"
subject="""comment 3"""
date="2018-12-04T15:46:05Z"
content="""
Indeed, the object seems to be there, but it looks like `dropunused`
probably for some reason fails its `inAnnex` check and so skips it.
Does `git config annex.thin` output true? If so, and if the object file you
found does not checksum to the right value, `dropunused` would skip it.
That seems to me to be a bug, it probably should delete even modified files
in this case. But I don't know if it's the bug you're seeing.
"""]]

View file

@ -0,0 +1,26 @@
[[!comment format=mdwn
username="joey"
subject="""comment 4"""
date="2018-12-04T15:52:52Z"
content="""
Test case for the annex.thin with modified file bug:
git annex init
git annex upgrade
git config annex.thin true
touch foo
git add foo
git commit -m add
echo foo >> foo
rm foo
git commit -m rm -a
git annex unused
git annex dropunused 1
git annex unused
Now, dropunused is supposed to honor numcopies, and if an object file
has been modified, that's probably the only existing copy of that object,
and so dropunused should refuse to drop it by default. There ought to be a
warning, and the user should be able to use --force to override and drop it
anyway. I've implemented that now.
"""]]