
Added git configs annex.post-update-command and annex.pre-commit-command that correspond to the git-annex hook scripts post-update-annex and pre-commit-annex. Note that the hook files take precience over the git config, since the git config can includ global config which should be overridden by local config. These new git configs are probably not super useful. Especially the pre-commit-annex hook is there to install scripts to instead of the pre-commit hook, since git-annex installs that hook itself. So why would someone want to use a git config for that? Only reason I can think of would be in a global git config. Or possibly because it's easier to set a git config than write a hook script, on an OS like Windows. The real reason I'm adding these is as groundwork for making other annex.*-command git configs also be available as hook scripts. I want to avoid having some things available as only git hooks and others as both gitconfigs and git hooks. (It seems that some annex.*-command configs don't translate to git hooks though.) In the man page, moved documentation of the hooks to be next to the documentation of the git configs. This is to avoid repitition.
88 lines
2.5 KiB
Haskell
88 lines
2.5 KiB
Haskell
{- git-annex command
|
|
-
|
|
- Copyright 2010-2024 Joey Hess <id@joeyh.name>
|
|
-
|
|
- Licensed under the GNU AGPL version 3 or higher.
|
|
-}
|
|
|
|
{-# LANGUAGE CPP #-}
|
|
|
|
module Command.PreCommit where
|
|
|
|
import Command
|
|
import qualified Command.Fix
|
|
import qualified Command.Smudge
|
|
import Annex.Hook
|
|
import Annex.Link
|
|
import Annex.View
|
|
import Annex.View.ViewedFile
|
|
import Logs.View
|
|
import Logs.MetaData
|
|
import Types.View
|
|
import Types.MetaData
|
|
import qualified Annex
|
|
import qualified Annex.Branch
|
|
|
|
import qualified Data.Set as S
|
|
import qualified Data.Text as T
|
|
|
|
cmd :: Command
|
|
cmd = noCommit $ command "pre-commit" SectionPlumbing
|
|
"run by git pre-commit hook"
|
|
paramPaths
|
|
(withParams seek)
|
|
|
|
seek :: CmdParams -> CommandSeek
|
|
seek ps = do
|
|
let ww = WarnUnmatchWorkTreeItems "pre-commit"
|
|
l <- workTreeItems ww ps
|
|
-- fix symlinks to files being committed
|
|
flip (withFilesToBeCommitted ww) l $ \(si, f) -> commandAction $
|
|
maybe stop (Command.Fix.start Command.Fix.FixSymlinks si f)
|
|
=<< isAnnexLink f
|
|
-- after a merge conflict or git cherry-pick or stash, pointer
|
|
-- files in the worktree won't be populated, so populate them here
|
|
Command.Smudge.updateSmudged (Restage False)
|
|
|
|
runAnnexHook preCommitAnnexHook annexPreCommitCommand
|
|
|
|
-- committing changes to a view updates metadata
|
|
currentView >>= \case
|
|
Nothing -> noop
|
|
Just (v, _madj) -> do
|
|
withViewChanges
|
|
(addViewMetaData v)
|
|
(removeViewMetaData v)
|
|
-- Manually commit in this case, because
|
|
-- noCommit prevents automatic commit.
|
|
whenM (annexAlwaysCommit <$> Annex.getGitConfig) $
|
|
Annex.Branch.commit =<< Annex.Branch.commitMessage
|
|
|
|
addViewMetaData :: View -> ViewedFile -> Key -> CommandStart
|
|
addViewMetaData v f k = starting "metadata" ai si $
|
|
next $ changeMetaData k $ fromView v f
|
|
where
|
|
ai = mkActionItem (k, toRawFilePath f)
|
|
si = SeekInput []
|
|
|
|
removeViewMetaData :: View -> ViewedFile -> Key -> CommandStart
|
|
removeViewMetaData v f k = starting "metadata" ai si $
|
|
next $ changeMetaData k $ unsetMetaData $ fromView v f
|
|
where
|
|
ai = mkActionItem (k, toRawFilePath f)
|
|
si = SeekInput []
|
|
|
|
changeMetaData :: Key -> MetaData -> CommandCleanup
|
|
changeMetaData k metadata = do
|
|
showMetaDataChange metadata
|
|
addMetaData k metadata
|
|
return True
|
|
|
|
showMetaDataChange :: MetaData -> Annex ()
|
|
showMetaDataChange = showLongNote . UnquotedString . unlines . concatMap showmeta . fromMetaData
|
|
where
|
|
showmeta (f, vs) = map (showmetavalue f) $ S.toList vs
|
|
showmetavalue f v = T.unpack (fromMetaField f) <> showset v <> "=" <> decodeBS (fromMetaValue v)
|
|
showset v
|
|
| isSet v = "+"
|
|
| otherwise = "-"
|