Windows: Fix running of the pre-commit-annex hook.

This commit is contained in:
Joey Hess 2015-01-20 13:39:07 -04:00
parent d818e4c06c
commit 6035f94666
5 changed files with 83 additions and 11 deletions

View file

@ -16,7 +16,6 @@ import qualified Git.Hook as Git
import Config
import qualified Annex
import Utility.Shell
import Utility.FileMode
import qualified Data.Map as M
@ -53,19 +52,16 @@ hookWarning h msg = do
- the existing hooks are cached. -}
runAnnexHook :: Git.Hook -> Annex ()
runAnnexHook hook = do
cmd <- fromRepo $ Git.hookFile hook
m <- Annex.getState Annex.existinghooks
case M.lookup hook m of
Just True -> run cmd
Just True -> run
Just False -> noop
Nothing -> do
exists <- hookexists cmd
exists <- inRepo $ Git.hookExists hook
Annex.changeState $ \s -> s
{ Annex.existinghooks = M.insert hook exists m }
when exists $
run cmd
when exists run
where
hookexists f = liftIO $ catchBoolIO $
isExecutable . fileMode <$> getFileStatus f
run cmd = unlessM (liftIO $ boolSystem cmd []) $
warning $ cmd ++ " failed"
run = unlessM (inRepo $ Git.runHook hook) $ do
h <- fromRepo $ Git.hookFile hook
warning $ h ++ " failed"

View file

@ -1,15 +1,20 @@
{- git hooks
-
- Copyright 2013 Joey Hess <joey@kitenet.net>
- Copyright 2013-2015 Joey Hess <joey@kitenet.net>
-
- Licensed under the GNU GPL version 3 or higher.
-}
{-# LANGUAGE CPP #-}
module Git.Hook where
import Common
import Git
import Utility.Tmp
#ifndef mingw32_HOST_OS
import Utility.FileMode
#endif
data Hook = Hook
{ hookName :: FilePath
@ -56,3 +61,37 @@ expectedContent :: Hook -> Repo -> IO Bool
expectedContent h r = do
content <- readFile $ hookFile h r
return $ content == hookScript h
hookExists :: Hook -> Repo -> IO Bool
hookExists h r = do
let f = hookFile h r
catchBoolIO $
#ifndef mingw32_HOST_OS
isExecutable . fileMode <$> getFileStatus f
#else
doesFileExist f
#endif
runHook :: Hook -> Repo -> IO Bool
runHook h r = do
let f = hookFile h r
(c, ps) <- findcmd f
boolSystem c ps
where
#ifndef mingw32_HOST_OS
findcmd = defcmd
#else
{- Like msysgit, parse the first line of the hook file,
- look for "#!", and dispatch the interpreter on the file. -}
findcmd f = do
l <- headMaybe . lines <$> catchDefaultIO "" (readFile f)
case l of
Just ('#':'!':rest) -> case words rest of
[] -> defcmd f
(c:ps) -> do
let ps' = map Param (ps ++ [f])
ok <- inPath c
return (if ok then c else takeFileName c, ps')
_ -> defcmd f
#endif
defcmd f = return (f, [])

1
debian/changelog vendored
View file

@ -12,6 +12,7 @@ git-annex (5.20150114) UNRELEASED; urgency=medium
* Fix build failure when wget is not installed.
* Fix wording of message displayed when unable to get a file that
is available in untrusted repositories.
* Windows: Fix running of the pre-commit-annex hook.
-- Joey Hess <id@joeyh.name> Tue, 13 Jan 2015 17:03:39 -0400

View file

@ -0,0 +1,27 @@
On Windows, isExecutable fails to detect a file that is indeed executable
as such. This prevents git-annex from running the pre-commit-hook
on Windows.
getFileStatus yields a fileMode of 100666, which is
clearly a dummy mode. Not surprising, since unix-compat is partial stubs
on windows.
Actually, isExecutable is ok (it needs to check unix modes because it is
used on file modes coming out of git). But, getFileStatus is the wrong
thing to be using on Windows to check if a hook exists and is executable.
I don't see anything in Win32 or Win32-extras on hackage that can check
executablility. Looking at git's source, it uses `access(path, X_OK) < 0`;
haskell equivilant is System.Posix.Files.fileAccess, but the version
in unix-compat has the same problem as checking getFileStatus's fileMode.
I think it's reasonable to assume that if a hook exists on windows, it's
intended to be executable, and try to run it. Actually, testing with
msysgit, it runs hooks whether or not they have the execute bit set!
So, done that now.
However, now git-annex tries to run the hook but fails when it's a shell
script because #!/bin/sh is useless on windows. It looks to me like msysgit
runs "sh hook" to work around that, and it is in fact parsing the shebang
line and dispatching the interpreter. Ugh. (Also, pre-commit.bat doesn't
get run.) Ok, added this same hack to git-annex. [[done]] --[[Joey]]

View file

@ -0,0 +1,9 @@
[[!comment format=mdwn
username="joey"
subject="""comment 6"""
date="2015-01-20T17:19:34Z"
content="""
@Michele after testing, git-annex on Windows seems to not see a file that
does have the executable bit set as executable. I have opened a bug report
[[bugs/windows_isExecutable_fail]], and worked around the problem now.
"""]]