pre-init config and hook
Added annex.pre-init-command git config and pre-init-annex hook that is run before git-annex repository initialization. This can block initialization. Or it can preform pre-initialization configuration or tweaking. I left stdio connected while it's running, so it could also be used for interactive prompting conceivably, although that would want to use /dev/tty anyway probably in order to not pollute the stdout of a command when automatic initialization is done. Sponsored-by: Dartmouth College's OpenNeuro project
This commit is contained in:
parent
9e95556d69
commit
42d55bc57c
9 changed files with 87 additions and 19 deletions
|
@ -48,6 +48,9 @@ preCommitAnnexHook = Git.Hook "pre-commit-annex" "" []
|
||||||
postUpdateAnnexHook :: Git.Hook
|
postUpdateAnnexHook :: Git.Hook
|
||||||
postUpdateAnnexHook = Git.Hook "post-update-annex" "" []
|
postUpdateAnnexHook = Git.Hook "post-update-annex" "" []
|
||||||
|
|
||||||
|
preInitAnnexHook :: Git.Hook
|
||||||
|
preInitAnnexHook = Git.Hook "pre-init-annex" "" []
|
||||||
|
|
||||||
freezeContentAnnexHook :: Git.Hook
|
freezeContentAnnexHook :: Git.Hook
|
||||||
freezeContentAnnexHook = Git.Hook "freezecontent-annex" "" []
|
freezeContentAnnexHook = Git.Hook "freezecontent-annex" "" []
|
||||||
|
|
||||||
|
@ -98,20 +101,33 @@ doesAnnexHookExist hook = do
|
||||||
return exists
|
return exists
|
||||||
|
|
||||||
runAnnexHook :: Git.Hook -> (GitConfig -> Maybe String) -> Annex ()
|
runAnnexHook :: Git.Hook -> (GitConfig -> Maybe String) -> Annex ()
|
||||||
runAnnexHook hook commandcfg = ifM (doesAnnexHookExist hook)
|
runAnnexHook hook commandcfg = runAnnexHook' hook commandcfg >>= \case
|
||||||
|
Nothing -> noop
|
||||||
|
Just failedcommanddesc ->
|
||||||
|
warning $ UnquotedString $ failedcommanddesc ++ " failed"
|
||||||
|
|
||||||
|
-- Returns Nothing if the hook or GitConfig command succeeded, or a
|
||||||
|
-- description of what failed.
|
||||||
|
runAnnexHook' :: Git.Hook -> (GitConfig -> Maybe String) -> Annex (Maybe String)
|
||||||
|
runAnnexHook' hook commandcfg = ifM (doesAnnexHookExist hook)
|
||||||
( runhook
|
( runhook
|
||||||
, runcommandcfg
|
, runcommandcfg
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
runhook = unlessM (inRepo $ Git.runHook boolSystem hook []) $ do
|
runhook = ifM (inRepo $ Git.runHook boolSystem hook [])
|
||||||
h <- fromRepo $ Git.hookFile hook
|
( return Nothing
|
||||||
commandfailed h
|
, do
|
||||||
|
h <- fromRepo (Git.hookFile hook)
|
||||||
|
commandfailed h
|
||||||
|
)
|
||||||
runcommandcfg = commandcfg <$> Annex.getGitConfig >>= \case
|
runcommandcfg = commandcfg <$> Annex.getGitConfig >>= \case
|
||||||
|
Nothing -> return Nothing
|
||||||
Just command ->
|
Just command ->
|
||||||
unlessM (liftIO $ boolSystem "sh" [Param "-c", Param command]) $
|
ifM (liftIO $ boolSystem "sh" [Param "-c", Param command])
|
||||||
commandfailed command
|
( return Nothing
|
||||||
Nothing -> noop
|
, commandfailed $ "git configured command '" ++ command ++ "'"
|
||||||
commandfailed c = warning $ UnquotedString $ c ++ " failed"
|
)
|
||||||
|
commandfailed c = return $ Just c
|
||||||
|
|
||||||
runAnnexPathHook :: String -> Git.Hook -> (GitConfig -> Maybe String) -> RawFilePath -> Annex Bool
|
runAnnexPathHook :: String -> Git.Hook -> (GitConfig -> Maybe String) -> RawFilePath -> Annex Bool
|
||||||
runAnnexPathHook pathtoken hook commandcfg p = ifM (doesAnnexHookExist hook)
|
runAnnexPathHook pathtoken hook commandcfg p = ifM (doesAnnexHookExist hook)
|
||||||
|
@ -121,9 +137,9 @@ runAnnexPathHook pathtoken hook commandcfg p = ifM (doesAnnexHookExist hook)
|
||||||
where
|
where
|
||||||
runhook = inRepo $ Git.runHook boolSystem hook [ File (fromRawFilePath p) ]
|
runhook = inRepo $ Git.runHook boolSystem hook [ File (fromRawFilePath p) ]
|
||||||
runcommandcfg = commandcfg <$> Annex.getGitConfig >>= \case
|
runcommandcfg = commandcfg <$> Annex.getGitConfig >>= \case
|
||||||
|
Nothing -> return True
|
||||||
Just basecmd -> liftIO $
|
Just basecmd -> liftIO $
|
||||||
boolSystem "sh" [Param "-c", Param $ gencmd basecmd]
|
boolSystem "sh" [Param "-c", Param $ gencmd basecmd]
|
||||||
Nothing -> return True
|
|
||||||
gencmd = massReplace [ (pathtoken, shellEscape (fromRawFilePath p)) ]
|
gencmd = massReplace [ (pathtoken, shellEscape (fromRawFilePath p)) ]
|
||||||
|
|
||||||
outputOfAnnexHook :: Git.Hook -> (GitConfig -> Maybe String) -> Annex (Maybe String)
|
outputOfAnnexHook :: Git.Hook -> (GitConfig -> Maybe String) -> Annex (Maybe String)
|
||||||
|
@ -135,6 +151,6 @@ outputOfAnnexHook hook commandcfg = ifM (doesAnnexHookExist hook)
|
||||||
runhook = inRepo (Git.runHook runhook' hook [])
|
runhook = inRepo (Git.runHook runhook' hook [])
|
||||||
runhook' c ps = Just <$> readProcess c (toCommand ps)
|
runhook' c ps = Just <$> readProcess c (toCommand ps)
|
||||||
runcommandcfg = commandcfg <$> Annex.getGitConfig >>= \case
|
runcommandcfg = commandcfg <$> Annex.getGitConfig >>= \case
|
||||||
|
Nothing -> return Nothing
|
||||||
Just command -> liftIO $
|
Just command -> liftIO $
|
||||||
Just <$> readProcess "sh" ["-c", command]
|
Just <$> readProcess "sh" ["-c", command]
|
||||||
Nothing -> return Nothing
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{- git-annex repository initialization
|
{- git-annex repository initialization
|
||||||
-
|
-
|
||||||
- Copyright 2011-2024 Joey Hess <id@joeyh.name>
|
- Copyright 2011-2025 Joey Hess <id@joeyh.name>
|
||||||
-
|
-
|
||||||
- Licensed under the GNU AGPL version 3 or higher.
|
- Licensed under the GNU AGPL version 3 or higher.
|
||||||
-}
|
-}
|
||||||
|
@ -74,17 +74,29 @@ data InitializeAllowed = InitializeAllowed
|
||||||
|
|
||||||
checkInitializeAllowed :: (InitializeAllowed -> Annex a) -> Annex a
|
checkInitializeAllowed :: (InitializeAllowed -> Annex a) -> Annex a
|
||||||
checkInitializeAllowed a = guardSafeToUseRepo $ noAnnexFileContent' >>= \case
|
checkInitializeAllowed a = guardSafeToUseRepo $ noAnnexFileContent' >>= \case
|
||||||
Nothing -> do
|
Nothing -> runAnnexHook' preInitAnnexHook annexPreInitCommand >>= \case
|
||||||
checkSqliteWorks
|
Nothing -> do
|
||||||
a InitializeAllowed
|
checkSqliteWorks
|
||||||
|
a InitializeAllowed
|
||||||
|
Just failedcommanddesc -> do
|
||||||
|
initpreventedby failedcommanddesc
|
||||||
|
notinitialized
|
||||||
Just noannexmsg -> do
|
Just noannexmsg -> do
|
||||||
warning "Initialization prevented by .noannex file (remove the file to override)"
|
initpreventedby ".noannex file (remove the file to override)"
|
||||||
unless (null noannexmsg) $
|
unless (null noannexmsg) $
|
||||||
warning (UnquotedString noannexmsg)
|
warning (UnquotedString noannexmsg)
|
||||||
giveup "Not initialized."
|
notinitialized
|
||||||
|
where
|
||||||
|
initpreventedby r = warning $ UnquotedString $
|
||||||
|
"Initialization prevented by " ++ r
|
||||||
|
notinitialized = giveup "Not initialized."
|
||||||
|
|
||||||
initializeAllowed :: Annex Bool
|
initializeAllowed :: Annex Bool
|
||||||
initializeAllowed = isNothing <$> noAnnexFileContent'
|
initializeAllowed = noAnnexFileContent' >>= \case
|
||||||
|
Nothing -> runAnnexHook' preInitAnnexHook annexPreInitCommand >>= \case
|
||||||
|
Nothing -> return True
|
||||||
|
Just _ -> return False
|
||||||
|
Just _ -> return False
|
||||||
|
|
||||||
noAnnexFileContent' :: Annex (Maybe String)
|
noAnnexFileContent' :: Annex (Maybe String)
|
||||||
noAnnexFileContent' = inRepo $
|
noAnnexFileContent' = inRepo $
|
||||||
|
@ -268,7 +280,7 @@ autoInitialize' check startupannex remotelist =
|
||||||
getInitializedVersion >>= maybe needsinit checkUpgrade
|
getInitializedVersion >>= maybe needsinit checkUpgrade
|
||||||
where
|
where
|
||||||
needsinit =
|
needsinit =
|
||||||
whenM (initializeAllowed <&&> check) $ do
|
whenM (check <&&> initializeAllowed) $ do
|
||||||
initialize startupannex Nothing Nothing
|
initialize startupannex Nothing Nothing
|
||||||
autoEnableSpecialRemotes remotelist
|
autoEnableSpecialRemotes remotelist
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,8 @@ git-annex (10.20250103) UNRELEASED; urgency=medium
|
||||||
annex.http-headers-command.
|
annex.http-headers-command.
|
||||||
* Added git configs annex.post-update-command and annex.pre-commit-command
|
* Added git configs annex.post-update-command and annex.pre-commit-command
|
||||||
that correspond to the post-update-annex and pre-commit-annex hooks.
|
that correspond to the post-update-annex and pre-commit-annex hooks.
|
||||||
|
* Added annex.pre-init-command git config and pre-init-annex hook
|
||||||
|
that is run before git-annex repository initialization.
|
||||||
|
|
||||||
-- Joey Hess <id@joeyh.name> Fri, 03 Jan 2025 14:30:38 -0400
|
-- Joey Hess <id@joeyh.name> Fri, 03 Jan 2025 14:30:38 -0400
|
||||||
|
|
||||||
|
|
|
@ -97,6 +97,7 @@ data GitConfig = GitConfig
|
||||||
, annexAlwaysCompact :: Bool
|
, annexAlwaysCompact :: Bool
|
||||||
, annexCommitMessage :: Maybe String
|
, annexCommitMessage :: Maybe String
|
||||||
, annexCommitMessageCommand :: Maybe String
|
, annexCommitMessageCommand :: Maybe String
|
||||||
|
, annexPreInitCommand :: Maybe String
|
||||||
, annexPreCommitCommand :: Maybe String
|
, annexPreCommitCommand :: Maybe String
|
||||||
, annexPostUpdateCommand :: Maybe String
|
, annexPostUpdateCommand :: Maybe String
|
||||||
, annexMergeAnnexBranches :: Bool
|
, annexMergeAnnexBranches :: Bool
|
||||||
|
@ -192,6 +193,7 @@ extractGitConfig configsource r = GitConfig
|
||||||
, annexAlwaysCompact = getbool (annexConfig "alwayscompact") True
|
, annexAlwaysCompact = getbool (annexConfig "alwayscompact") True
|
||||||
, annexCommitMessage = getmaybe (annexConfig "commitmessage")
|
, annexCommitMessage = getmaybe (annexConfig "commitmessage")
|
||||||
, annexCommitMessageCommand = getmaybe (annexConfig "commitmessage-command")
|
, annexCommitMessageCommand = getmaybe (annexConfig "commitmessage-command")
|
||||||
|
, annexPreInitCommand = getmaybe (annexConfig "pre-init-command")
|
||||||
, annexPreCommitCommand = getmaybe (annexConfig "pre-commit-command")
|
, annexPreCommitCommand = getmaybe (annexConfig "pre-commit-command")
|
||||||
, annexPostUpdateCommand = getmaybe (annexConfig "post-update-command")
|
, annexPostUpdateCommand = getmaybe (annexConfig "post-update-command")
|
||||||
, annexMergeAnnexBranches = getbool (annexConfig "merge-annex-branches") True
|
, annexMergeAnnexBranches = getbool (annexConfig "merge-annex-branches") True
|
||||||
|
|
|
@ -27,7 +27,11 @@ already initialized git-annex repository.
|
||||||
A top-level `.noannex` file will prevent git-annex init from being used
|
A top-level `.noannex` file will prevent git-annex init from being used
|
||||||
in a repository. This is useful for repositories that have a policy
|
in a repository. This is useful for repositories that have a policy
|
||||||
reason not to use git-annex. The content of the file will be displayed
|
reason not to use git-annex. The content of the file will be displayed
|
||||||
to the user who tries to run git-annex init.
|
to the user who tries to run git-annex init.
|
||||||
|
|
||||||
|
The annex.pre-init-command git configuration or pre-init-annex hook
|
||||||
|
is run before initialization and can exit nonzero as well to prevent
|
||||||
|
initialization, as well as doing other setup.
|
||||||
|
|
||||||
# EXAMPLES
|
# EXAMPLES
|
||||||
|
|
||||||
|
|
|
@ -1176,6 +1176,16 @@ repository, using [[git-annex-config]]. See its man page for a list.)
|
||||||
Alternatively, a hook script can be installed in
|
Alternatively, a hook script can be installed in
|
||||||
`.git/hooks/pre-commit-annex`
|
`.git/hooks/pre-commit-annex`
|
||||||
|
|
||||||
|
* `annex.pre-init-command`
|
||||||
|
|
||||||
|
This command is run before the repository is initialized, either by
|
||||||
|
`git-annex init`, or automatic initialization. It can configure
|
||||||
|
the repository in any way needed. If it exits nonzero, the repository
|
||||||
|
initialization will fail.
|
||||||
|
|
||||||
|
Alternatively, a hook script can be installed in
|
||||||
|
`.git/hooks/pre-init-annex`
|
||||||
|
|
||||||
* `annex.alwayscompact`
|
* `annex.alwayscompact`
|
||||||
|
|
||||||
By default, git-annex compacts data it records in the git-annex branch.
|
By default, git-annex compacts data it records in the git-annex branch.
|
||||||
|
|
|
@ -6,3 +6,5 @@ The idea is stemmed from discussions/problems with using freeze/thaw hooks, and
|
||||||
|
|
||||||
[[!meta author=yoh]]
|
[[!meta author=yoh]]
|
||||||
[[!tag projects/openneuro]]
|
[[!tag projects/openneuro]]
|
||||||
|
|
||||||
|
> [[done]] --[[Joey]]
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
[[!comment format=mdwn
|
||||||
|
username="joey"
|
||||||
|
subject="""comment 5"""
|
||||||
|
date="2025-01-13T17:33:02Z"
|
||||||
|
content="""
|
||||||
|
Note that the `.noannex` file that prevents init has some overlap with
|
||||||
|
a pre-init hook that exits nonzero. I guess the .noannex file has the
|
||||||
|
benefit of working in every clone of a repository without additional
|
||||||
|
configuration.
|
||||||
|
"""]]
|
|
@ -0,0 +1,10 @@
|
||||||
|
[[!comment format=mdwn
|
||||||
|
username="joey"
|
||||||
|
subject="""comment 6"""
|
||||||
|
date="2025-01-13T18:17:42Z"
|
||||||
|
content="""
|
||||||
|
Implemented .git/hooks/pre-init-annex
|
||||||
|
(and alternatively git config annex.pre-init-command)
|
||||||
|
|
||||||
|
Note that this is also run before automatic initialization.
|
||||||
|
"""]]
|
Loading…
Add table
Add a link
Reference in a new issue