git's handing of relative GIT_INDEX_FILE is more insane than I thought; always make absolute

This is actually worse than I thought; when git is being run with a
detached work tree, GIT_INDEX_FILE is treated as a path relative to CWD,
instead of the normal behavior of relative the top of the work tree.

This seems to make it basically impossible for any program that wants to
use GIT_INDEX_FILE to use anything other than an absolute path to it; there
are too many configurations to keep straight that can change how git
interprets what should be a simple relative path to a file.

(I have complained to the git developers.)
This commit is contained in:
Joey Hess 2016-05-22 14:58:04 -04:00
parent be03afac67
commit 097605e2e9
Failed to extract signature
2 changed files with 15 additions and 10 deletions

View file

@ -19,7 +19,7 @@ import qualified Annex
{- Runs an action using a different git index file. -} {- Runs an action using a different git index file. -}
withIndexFile :: FilePath -> Annex a -> Annex a withIndexFile :: FilePath -> Annex a -> Annex a
withIndexFile f a = do withIndexFile f a = do
f' <- inRepo $ indexEnvVal f f' <- liftIO $ indexEnvVal f
withAltRepo withAltRepo
(\g -> addGitEnv g indexEnv f') (\g -> addGitEnv g indexEnv f')
(\g g' -> g' { gitEnv = gitEnv g }) (\g g' -> g' { gitEnv = gitEnv g })

View file

@ -9,19 +9,24 @@ module Git.Index where
import Common import Common
import Git import Git
import Git.FilePath
import Utility.Env import Utility.Env
indexEnv :: String indexEnv :: String
indexEnv = "GIT_INDEX_FILE" indexEnv = "GIT_INDEX_FILE"
{- When relative, GIT_INDEX_FILE is interpreted by git as being {- Gets value to set GIT_INDEX_FILE to. Input should be absolute path,
- or relative to the CWD.
-
- When relative, GIT_INDEX_FILE is interpreted by git as being
- relative to the top of the work tree of the git repository, - relative to the top of the work tree of the git repository,
- not to the CWD. -} - not to the CWD. Worse, other environment variables (GIT_WORK_TREE)
indexEnvVal :: FilePath -> Repo -> IO String - or git options (--work-tree) or configuration (core.worktree)
indexEnvVal index r - can change what the relative path is interpreted relative to.
| isAbsolute index = return index -
| otherwise = getTopFilePath <$> toTopFilePath index r - So, an absolute path is the only safe option for this to return.
-}
indexEnvVal :: FilePath -> IO String
indexEnvVal = absPath
{- Forces git to use the specified index file. {- Forces git to use the specified index file.
- -
@ -31,9 +36,9 @@ indexEnvVal index r
- Warning: Not thread safe. - Warning: Not thread safe.
-} -}
override :: FilePath -> Repo -> IO (IO ()) override :: FilePath -> Repo -> IO (IO ())
override index r = do override index _r = do
res <- getEnv var res <- getEnv var
val <- indexEnvVal index r val <- indexEnvVal index
setEnv var val True setEnv var val True
return $ reset res return $ reset res
where where