From 177e45517ff1d5aa7c599c05fa9c36721d4d6920 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Tue, 25 Sep 2018 15:02:12 -0400 Subject: [PATCH] improve back-compat of post-receive hook * init: Improve generated post-receive hook, so it won't fail when run on a system whose git-annex is too old to support git-annex post-receive * init: Update the post-receive hook when re-run in an existing repository. This commit was sponsored by Jack Hill on Patreon. --- Annex/Hook.hs | 17 ++++-- CHANGELOG | 3 + Git/Hook.hs | 60 +++++++++++-------- doc/bugs/post-receive.mdwn | 2 + ..._80c2251beb6a434b364346abc1b2fc02._comment | 22 +++++++ 5 files changed, 74 insertions(+), 30 deletions(-) create mode 100644 doc/bugs/post-receive/comment_1_80c2251beb6a434b364346abc1b2fc02._comment diff --git a/Annex/Hook.hs b/Annex/Hook.hs index b539145054..450ed261b3 100644 --- a/Annex/Hook.hs +++ b/Annex/Hook.hs @@ -4,7 +4,7 @@ - not change, otherwise removing old hooks using an old version of - the script would fail. - - - Copyright 2013-2017 Joey Hess + - Copyright 2013-2018 Joey Hess - - Licensed under the GNU GPL version 3 or higher. -} @@ -20,16 +20,23 @@ import Utility.Shell import qualified Data.Map as M preCommitHook :: Git.Hook -preCommitHook = Git.Hook "pre-commit" (mkHookScript "git annex pre-commit .") +preCommitHook = Git.Hook "pre-commit" (mkHookScript "git annex pre-commit .") [] postReceiveHook :: Git.Hook -postReceiveHook = Git.Hook "post-receive" (mkHookScript "git annex post-receive") +postReceiveHook = Git.Hook "post-receive" + -- Only run git-annex post-receive when git-annex supports it, + -- to avoid failing if the repository with this hook is used + -- with an older version of git-annex. + (mkHookScript "if git annex post-receive --help >/dev/null 2>&1; then git annex post-receive; fi") + -- This is an old version of the hook script. + [ mkHookScript "git annex post-receive" + ] preCommitAnnexHook :: Git.Hook -preCommitAnnexHook = Git.Hook "pre-commit-annex" "" +preCommitAnnexHook = Git.Hook "pre-commit-annex" "" [] postUpdateAnnexHook :: Git.Hook -postUpdateAnnexHook = Git.Hook "post-update-annex" "" +postUpdateAnnexHook = Git.Hook "post-update-annex" "" [] mkHookScript :: String -> String mkHookScript s = unlines diff --git a/CHANGELOG b/CHANGELOG index e9dc83a5b2..6d0212d2fb 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -3,6 +3,9 @@ git-annex (6.20180914) UNRELEASED; urgency=medium [ Joey Hess ] * Fixes a reversion in the last release that broke interoperation with older versions of git-annex-shell. + * init: Improve generated post-receive hook, so it won't fail when + run on a system whose git-annex is too old to support git-annex post-receive + * init: Update the post-receive hook when re-run in an existing repository. * S3: Fix url construction bug when the publicurl has been set to an url that does not end with a slash. * --debug shows urls accessed by git-annex, like it used to do when diff --git a/Git/Hook.hs b/Git/Hook.hs index da999733d4..3f7c3dd850 100644 --- a/Git/Hook.hs +++ b/Git/Hook.hs @@ -1,6 +1,6 @@ {- git hooks - - - Copyright 2013-2015 Joey Hess + - Copyright 2013-2018 Joey Hess - - Licensed under the GNU GPL version 3 or higher. -} @@ -20,6 +20,7 @@ import Utility.FileMode data Hook = Hook { hookName :: FilePath , hookScript :: String + , hookOldScripts :: [String] } deriving (Ord) @@ -30,38 +31,47 @@ hookFile :: Hook -> Repo -> FilePath hookFile h r = localGitDir r "hooks" hookName h {- Writes a hook. Returns False if the hook already exists with a different - - content. -} + - content. Upgrades old scripts. -} hookWrite :: Hook -> Repo -> IO Bool -hookWrite h r = do - let f = hookFile h r - ifM (doesFileExist f) - ( expectedContent h r - , do - viaTmp writeFile f (hookScript h) - p <- getPermissions f - setPermissions f $ p {executable = True} - return True - ) +hookWrite h r = ifM (doesFileExist f) + ( expectedContent h r >>= \case + UnexpectedContent -> return False + ExpectedContent -> return True + OldExpectedContent -> go + , go + ) + where + f = hookFile h r + go = do + viaTmp writeFile f (hookScript h) + p <- getPermissions f + setPermissions f $ p {executable = True} + return True {- Removes a hook. Returns False if the hook contained something else, and - could not be removed. -} hookUnWrite :: Hook -> Repo -> IO Bool -hookUnWrite h r = do - let f = hookFile h r - ifM (doesFileExist f) - ( ifM (expectedContent h r) - ( do - removeFile f - return True - , return False - ) - , return True - ) +hookUnWrite h r = ifM (doesFileExist f) + ( expectedContent h r >>= \case + UnexpectedContent -> return False + _ -> do + removeFile f + return True + , return True + ) + where + f = hookFile h r -expectedContent :: Hook -> Repo -> IO Bool +data ExpectedContent = UnexpectedContent | ExpectedContent | OldExpectedContent + +expectedContent :: Hook -> Repo -> IO ExpectedContent expectedContent h r = do content <- readFile $ hookFile h r - return $ content == hookScript h + return $ if content == hookScript h + then ExpectedContent + else if any (content ==) (hookOldScripts h) + then OldExpectedContent + else UnexpectedContent hookExists :: Hook -> Repo -> IO Bool hookExists h r = do diff --git a/doc/bugs/post-receive.mdwn b/doc/bugs/post-receive.mdwn index 96519313fe..86747a14bf 100644 --- a/doc/bugs/post-receive.mdwn +++ b/doc/bugs/post-receive.mdwn @@ -65,3 +65,5 @@ tai@trasa:~$ I did not hit enter, the script just failed on me during tab-complete and exited. Thanks, I look forward to any response from the community this might get. + +> [[fixed|done]] --[[Joey]] diff --git a/doc/bugs/post-receive/comment_1_80c2251beb6a434b364346abc1b2fc02._comment b/doc/bugs/post-receive/comment_1_80c2251beb6a434b364346abc1b2fc02._comment new file mode 100644 index 0000000000..589bee8067 --- /dev/null +++ b/doc/bugs/post-receive/comment_1_80c2251beb6a434b364346abc1b2fc02._comment @@ -0,0 +1,22 @@ +[[!comment format=mdwn + username="joey" + subject="""comment 1""" + date="2018-09-25T18:17:59Z" + content=""" +> When I try to use that drive with my raspberry pi, however, there are some new git hooks (or at least one) that the older version of git annex (still the latest available in the Pi's repos, 2016, which is really old :/). + +Ok, that sentance no verb. But I'll make a guess what you meant to say.. +The old post-receive hook installed by the new version of git-annex runs +"git-annex post-receive", which fails on the old version of git-annex. + +Yes, it's fine to delete the hook in this situation. + +The fist version of git-annex to support that is 6.20170228. +The latest raspbian release is tracking debian stable AFAICS, which has +6.20170101, just slightly too old. + +I agree this is a backwards compatability problem that should have been avoided. +I've made `git annex init` generate a better hook script that won't fail +with an older git-annex version. You can re-run `git annex init` in +your repository and it will update the hook script. +"""]]