pre-commit: Block partial commit of unlocked annexed file, since that left a typechange staged in index

I had hoped that the git devs could change git's handling of partial
commits to not use a false index file, but seems not.

So, this relies on some git internals to detect that case. The test suite
has a test case added to catch it if changes to git break it.

This commit was sponsored by Paul Tagliamonte.
This commit is contained in:
Joey Hess 2014-11-10 15:36:24 -04:00
parent 7e558371ab
commit adc5ca70a8
6 changed files with 59 additions and 8 deletions

View file

@ -11,6 +11,9 @@ import Common
import Git
import Utility.Env
indexEnv :: String
indexEnv = "GIT_INDEX_FILE"
{- Forces git to use the specified index file.
-
- Returns an action that will reset back to the default
@ -25,7 +28,7 @@ override index = do
return $ reset res
where
var = "GIT_INDEX_FILE"
reset (Just v) = setEnv var v True
reset (Just v) = setEnv indexEnv v True
reset _ = unsetEnv var
indexFile :: Repo -> FilePath
@ -34,3 +37,19 @@ indexFile r = localGitDir r </> "index"
{- Git locks the index by creating this file. -}
indexFileLock :: Repo -> FilePath
indexFileLock r = indexFile r ++ ".lock"
{- When the pre-commit hook is run, and git commit has been run with
- a file or files specified to commit, rather than committing the staged
- index, git provides the pre-commit hook with a "false index file".
-
- Changes made to this index will influence the commit, but won't
- affect the real index file.
-
- This detects when we're in this situation, using a heiristic, which
- might be broken by changes to git. Any use of this should have a test
- case to make sure it works.
-}
haveFalseIndex :: IO Bool
haveFalseIndex = maybe (False) check <$> getEnv indexEnv
where
check f = "next-index" `isPrefixOf` takeFileName f