diff options
author | Joey Hess <joey@kitenet.net> | 2014-02-19 14:14:44 -0400 |
---|---|---|
committer | Joey Hess <joey@kitenet.net> | 2014-02-19 14:17:58 -0400 |
commit | ade0216bd08c2f9c1ed10c1c2274fd5b071c9c93 (patch) | |
tree | 6097def98c91ec5a0b6b9a694ab5b4b4137063c0 /Command/PreCommit.hs | |
parent | 8d0b3f09a9effc71f729d5b820076c642b605eb4 (diff) |
pre-commit: Update metadata when committing changes to annexed files within a view.
So the user can now switch to a view and then move files around within it
to manage metadata. For example, moving a file into a new directory
when in the tags=* view adds a tag to it.
Implementation is fairly efficient. One diff-index, which is no more
expensive than the first stage of a git commit, followed by possibly
some cat-file --batch traffic to find the key (when deleting a file).
Very similar to what's done in direct mode when committing. And like
direct mode when updating the WC after a merge, it has to buffer the
diff-tree values in order to make 2 passes over them.
When not in a view, pre-commit now does one extra git symbolic-ref,
which is tiny overhead.
This commit was sponsored by Andrew Eskridge.
Diffstat (limited to 'Command/PreCommit.hs')
-rw-r--r-- | Command/PreCommit.hs | 47 |
1 files changed, 43 insertions, 4 deletions
diff --git a/Command/PreCommit.hs b/Command/PreCommit.hs index 388d065c0..4b90b5c2e 100644 --- a/Command/PreCommit.hs +++ b/Command/PreCommit.hs @@ -1,6 +1,6 @@ {- git-annex command - - - Copyright 2010, 2013 Joey Hess <joey@kitenet.net> + - Copyright 2010-2014 Joey Hess <joey@kitenet.net> - - Licensed under the GNU GPL version 3 or higher. -} @@ -13,6 +13,13 @@ import Config import qualified Command.Add import qualified Command.Fix import Annex.Direct +import Annex.View +import Logs.View +import Logs.MetaData +import Types.View +import Types.MetaData + +import qualified Data.Set as S def :: [Command] def = [command "pre-commit" paramPaths seek SectionPlumbing @@ -27,13 +34,45 @@ seek ps = ifM isDirect withFilesToBeCommitted (whenAnnexed Command.Fix.start) ps -- inject unlocked files into the annex withFilesUnlockedToBeCommitted startIndirect ps + -- committing changes to a view updates metadata + mv <- currentView + case mv of + Nothing -> noop + Just v -> withViewChanges + (addViewMetaData v) + (removeViewMetaData v) ) startIndirect :: FilePath -> CommandStart -startIndirect file = next $ do - unlessM (callCommandAction $ Command.Add.start file) $ - error $ "failed to add " ++ file ++ "; canceling commit" +startIndirect f = next $ do + unlessM (callCommandAction $ Command.Add.start f) $ + error $ "failed to add " ++ f ++ "; canceling commit" next $ return True startDirect :: [String] -> CommandStart startDirect _ = next $ next $ preCommitDirect + +addViewMetaData :: View -> FileView -> Key -> CommandStart +addViewMetaData v f k = do + showStart "metadata" f + next $ next $ changeMetaData k $ fromView v f + +removeViewMetaData :: View -> FileView -> Key -> CommandStart +removeViewMetaData v f k = do + showStart "metadata" f + next $ next $ changeMetaData k $ unsetMetaData $ fromView v f + +changeMetaData :: Key -> MetaData -> CommandCleanup +changeMetaData k metadata = do + showMetaDataChange metadata + addMetaData k metadata + return True + +showMetaDataChange :: MetaData -> Annex () +showMetaDataChange = showLongNote . unlines . concatMap showmeta . fromMetaData + where + showmeta (f, vs) = map (showmetavalue f) $ S.toList vs + showmetavalue f v = fromMetaField f ++ showset v ++ "=" ++ fromMetaValue v + showset v + | isSet v = "+" + | otherwise = "-" |