diff --git a/UUID.hs b/UUID.hs index bd7b6b1d01..c4b870f39f 100644 --- a/UUID.hs +++ b/UUID.hs @@ -6,7 +6,9 @@ - UUIDs of remotes are cached in git config, using keys named - remote..annex-uuid - - - Copyright 2010 Joey Hess + - uuid.log stores a list of known uuids, and their descriptions. + - + - Copyright 2010-2011 Joey Hess - - Licensed under the GNU GPL version 3 or higher. -} @@ -18,11 +20,11 @@ module UUID ( prepUUID, genUUID, describeUUID, - uuidMap, - uuidLog + uuidMap ) where import qualified Data.Map as M +import Data.Time.Clock.POSIX import Common.Annex import qualified Git @@ -30,13 +32,14 @@ import qualified Annex.Branch import Types.UUID import qualified Build.SysConfig as SysConfig import Config +import UUIDLog configkey :: String configkey = "annex.uuid" {- Filename of uuid.log. -} -uuidLog :: FilePath -uuidLog = "uuid.log" +logfile :: FilePath +logfile = "uuid.log" {- Generates a UUID. There is a library for this, but it's not packaged, - so use the command line tool. -} @@ -50,8 +53,7 @@ genUUID = liftIO $ pOpen ReadFromPipe command params $ \h -> hGetLine h -- uuidgen generates random uuid by default else [] -{- Looks up a repo's UUID. May return "" if none is known. - -} +{- Looks up a repo's UUID. May return "" if none is known. -} getUUID :: Git.Repo -> Annex UUID getUUID r = do g <- gitRepo @@ -76,26 +78,17 @@ getUncachedUUID r = Git.configGet r configkey "" prepUUID :: Annex () prepUUID = do u <- getUUID =<< gitRepo - when ("" == u) $ do + when (null u) $ do uuid <- liftIO genUUID setConfig configkey uuid -{- Records a description for a uuid in the uuidLog. -} +{- Records a description for a uuid in the log. -} describeUUID :: UUID -> String -> Annex () -describeUUID uuid desc = Annex.Branch.change uuidLog $ - serialize . M.insert uuid desc . parse - where - serialize m = unlines $ map (\(u, d) -> u++" "++d) $ M.toList m +describeUUID uuid desc = do + ts <- liftIO $ getPOSIXTime + Annex.Branch.change logfile $ + showLog id . changeLog ts uuid desc . parseLog Just -{- Read the uuidLog into a Map -} +{- Read the uuidLog into a simple Map -} uuidMap :: Annex (M.Map UUID String) -uuidMap = parse <$> Annex.Branch.get uuidLog - -parse :: String -> M.Map UUID String -parse = M.fromList . map pair . lines - where - pair l - | null ws = ("", "") - | otherwise = (head ws, unwords $ drop 1 ws) - where - ws = words l +uuidMap = (simpleMap . parseLog Just) <$> Annex.Branch.get logfile diff --git a/debian/changelog b/debian/changelog index 7554cd5028..5eb7870ef5 100644 --- a/debian/changelog +++ b/debian/changelog @@ -7,6 +7,11 @@ git-annex (3.20110929) UNRELEASED; urgency=low in addition to their descriptions. * Contain the zombie hordes. * Add locking to avoid races when changing the git-annex branch. + * New or changed repository descriptions in uuid.log now have a timestamp, + which is used to ensure the newest description is used when the uuid.log + has been merged. + * Note that older versions of git-annex will display the timestamp as part + of the repository description, which is ugly but otherwise harmless. -- Joey Hess Thu, 29 Sep 2011 18:58:53 -0400 diff --git a/doc/bugs/uuid.log_trust.log_and_remote.log_merge_wackiness.mdwn b/doc/bugs/uuid.log_trust.log_and_remote.log_merge_wackiness.mdwn index 2724611fbf..5a703b2cbd 100644 --- a/doc/bugs/uuid.log_trust.log_and_remote.log_merge_wackiness.mdwn +++ b/doc/bugs/uuid.log_trust.log_and_remote.log_merge_wackiness.mdwn @@ -21,6 +21,7 @@ would keep working, ignoring the timestamp. - uuid.log: "uuid description timestamp" would work; old git-annex would just treat the timestamp as part of the description which would be ok + > update: converted! --[[Joey]] - trust.log: "uuid trustlevel timestamp" would work; old git-annex ignores trailing words - remote.log: "uuid key=value ... timestamp" is on the edge but does work diff --git a/doc/internals.mdwn b/doc/internals.mdwn index e80ecbac0d..4881588ca6 100644 --- a/doc/internals.mdwn +++ b/doc/internals.mdwn @@ -42,10 +42,10 @@ more useful than a UUID when it refers to a repository that does not have a configured git remote pointing at it. The file format is simply one line per repository, with the uuid followed by a -space and then the description through to the end of the line. Example: +space and then the description, followed by a timestamp. Example: - e605dca6-446a-11e0-8b2a-002170d25c55 laptop - 26339d22-446b-11e0-9101-002170d25c55 usb disk + e605dca6-446a-11e0-8b2a-002170d25c55 laptop timestamp=1317929189.157237s + 26339d22-446b-11e0-9101-002170d25c55 usb disk timestamp=1317929330.769997s ## `remotes.log` diff --git a/test.hs b/test.hs index 654af5713f..16f2a2bdf6 100644 --- a/test.hs +++ b/test.hs @@ -31,6 +31,7 @@ import qualified Types import qualified GitAnnex import qualified LocationLog import qualified UUID +import qualified UUIDLog import qualified Trust import qualified Remote import qualified RemoteLog @@ -78,6 +79,8 @@ quickcheck = TestLabel "quickcheck" $ TestList , qctest "prop_relPathDirToFile_basics" Utility.Path.prop_relPathDirToFile_basics , qctest "prop_cost_sane" Config.prop_cost_sane , qctest "prop_hmacWithCipher_sane" Crypto.prop_hmacWithCipher_sane + , qctest "prop_TimeStamp_sane" UUIDLog.prop_TimeStamp_sane + , qctest "prop_addLog_sane" UUIDLog.prop_addLog_sane ] blackbox :: Test