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.
This commit is contained in:
Joey Hess 2018-09-25 15:02:12 -04:00
parent fc8be1980c
commit 177e45517f
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
5 changed files with 74 additions and 30 deletions

View file

@ -4,7 +4,7 @@
- not change, otherwise removing old hooks using an old version of
- the script would fail.
-
- Copyright 2013-2017 Joey Hess <id@joeyh.name>
- Copyright 2013-2018 Joey Hess <id@joeyh.name>
-
- 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

View file

@ -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

View file

@ -1,6 +1,6 @@
{- git hooks
-
- Copyright 2013-2015 Joey Hess <id@joeyh.name>
- Copyright 2013-2018 Joey Hess <id@joeyh.name>
-
- 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

View file

@ -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]]

View file

@ -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.
"""]]