metadata --batch: Fix bug when conflicting metadata changes were made in the same batch run.
1 microsecond delay is ugly.. but, maintaining an queue of a list of timestamps and taking a new one from the queue each time around, or maintaining a timestamp counter, would probably be slower.
This commit is contained in:
parent
f01b4cbf7c
commit
d9490685fd
3 changed files with 31 additions and 19 deletions
|
@ -1,6 +1,8 @@
|
||||||
git-annex (6.20161211) UNRELEASED; urgency=medium
|
git-annex (6.20161211) UNRELEASED; urgency=medium
|
||||||
|
|
||||||
* Debian: Build webapp on armel.
|
* Debian: Build webapp on armel.
|
||||||
|
* metadata --batch: Fix bug when conflicting metadata changes were
|
||||||
|
made in the same batch run.
|
||||||
|
|
||||||
-- Joey Hess <id@joeyh.name> Sun, 11 Dec 2016 21:29:51 -0400
|
-- Joey Hess <id@joeyh.name> Sun, 11 Dec 2016 21:29:51 -0400
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ import qualified Data.Text as T
|
||||||
import qualified Data.ByteString.Lazy.UTF8 as BU
|
import qualified Data.ByteString.Lazy.UTF8 as BU
|
||||||
import Data.Time.Clock.POSIX
|
import Data.Time.Clock.POSIX
|
||||||
import Data.Aeson
|
import Data.Aeson
|
||||||
|
import Control.Concurrent
|
||||||
|
|
||||||
cmd :: Command
|
cmd :: Command
|
||||||
cmd = withGlobalOptions ([jsonOption] ++ annexedMatchingOptions) $
|
cmd = withGlobalOptions ([jsonOption] ++ annexedMatchingOptions) $
|
||||||
|
@ -65,23 +66,22 @@ optParser desc = MetaDataOptions
|
||||||
)
|
)
|
||||||
|
|
||||||
seek :: MetaDataOptions -> CommandSeek
|
seek :: MetaDataOptions -> CommandSeek
|
||||||
seek o = do
|
seek o = case batchOption o of
|
||||||
now <- liftIO getPOSIXTime
|
NoBatch -> do
|
||||||
case batchOption o of
|
now <- liftIO getPOSIXTime
|
||||||
NoBatch -> do
|
let seeker = case getSet o of
|
||||||
let seeker = case getSet o of
|
Get _ -> withFilesInGit
|
||||||
Get _ -> withFilesInGit
|
GetAll -> withFilesInGit
|
||||||
GetAll -> withFilesInGit
|
Set _ -> withFilesInGitNonRecursive
|
||||||
Set _ -> withFilesInGitNonRecursive
|
"Not recursively setting metadata. Use --force to do that."
|
||||||
"Not recursively setting metadata. Use --force to do that."
|
withKeyOptions (keyOptions o) False
|
||||||
withKeyOptions (keyOptions o) False
|
(startKeys now o)
|
||||||
(startKeys now o)
|
(seeker $ whenAnnexed $ start now o)
|
||||||
(seeker $ whenAnnexed $ start now o)
|
(forFiles o)
|
||||||
(forFiles o)
|
Batch -> withMessageState $ \s -> case outputType s of
|
||||||
Batch -> withMessageState $ \s -> case outputType s of
|
JSONOutput _ -> batchInput parseJSONInput $
|
||||||
JSONOutput _ -> batchInput parseJSONInput $
|
commandAction . startBatch
|
||||||
commandAction . startBatch now
|
_ -> giveup "--batch is currently only supported in --json mode"
|
||||||
_ -> giveup "--batch is currently only supported in --json mode"
|
|
||||||
|
|
||||||
start :: POSIXTime -> MetaDataOptions -> FilePath -> Key -> CommandStart
|
start :: POSIXTime -> MetaDataOptions -> FilePath -> Key -> CommandStart
|
||||||
start now o file k = startKeys now o k (mkActionItem afile)
|
start now o file k = startKeys now o k (mkActionItem afile)
|
||||||
|
@ -150,8 +150,8 @@ parseJSONInput i = do
|
||||||
(Nothing, Just f) -> Right (Left f, m)
|
(Nothing, Just f) -> Right (Left f, m)
|
||||||
(Nothing, Nothing) -> Left "JSON input is missing either file or key"
|
(Nothing, Nothing) -> Left "JSON input is missing either file or key"
|
||||||
|
|
||||||
startBatch :: POSIXTime -> (Either FilePath Key, MetaData) -> CommandStart
|
startBatch :: (Either FilePath Key, MetaData) -> CommandStart
|
||||||
startBatch now (i, (MetaData m)) = case i of
|
startBatch (i, (MetaData m)) = case i of
|
||||||
Left f -> do
|
Left f -> do
|
||||||
mk <- lookupFile f
|
mk <- lookupFile f
|
||||||
case mk of
|
case mk of
|
||||||
|
@ -169,6 +169,15 @@ startBatch now (i, (MetaData m)) = case i of
|
||||||
, keyOptions = Nothing
|
, keyOptions = Nothing
|
||||||
, batchOption = NoBatch
|
, batchOption = NoBatch
|
||||||
}
|
}
|
||||||
|
now <- liftIO getPOSIXTime
|
||||||
|
-- It would be bad if two batch mode changes used exactly
|
||||||
|
-- the same timestamp, since the order of adds and removals
|
||||||
|
-- of the same metadata value would then be indeterminate.
|
||||||
|
-- To guarantee that never happens, delay 1 microsecond,
|
||||||
|
-- so the timestamp will always be different. This is
|
||||||
|
-- probably less expensive than cleaner methods,
|
||||||
|
-- such as taking from a list of increasing timestamps.
|
||||||
|
liftIO $ threadDelay 1
|
||||||
next $ perform now o k
|
next $ perform now o k
|
||||||
mkModMeta (f, s)
|
mkModMeta (f, s)
|
||||||
| S.null s = DelMeta f Nothing
|
| S.null s = DelMeta f Nothing
|
||||||
|
|
|
@ -82,3 +82,4 @@ I love the metadata functionality so much that I wrote [[tips/a_gui_for_metadata
|
||||||
Metadata driven views are awesome (but I don't like the entire folder hierarchy being appended to the filename).
|
Metadata driven views are awesome (but I don't like the entire folder hierarchy being appended to the filename).
|
||||||
I haven't used the other commands much since I have not yet organized most of my stuff (and their naively copy-pasted backups), but I am glad I discovered git-annex before I began organizing.
|
I haven't used the other commands much since I have not yet organized most of my stuff (and their naively copy-pasted backups), but I am glad I discovered git-annex before I began organizing.
|
||||||
|
|
||||||
|
> [[fixed|done]] --[[Joey]]
|
||||||
|
|
Loading…
Add table
Reference in a new issue