2016-04-06 19:33:29 +00:00
|
|
|
{- Temporarily changing the files git uses.
|
|
|
|
-
|
|
|
|
- Copyright 2014-2016 Joey Hess <id@joeyh.name>
|
|
|
|
-
|
|
|
|
- Licensed under the GNU GPL version 3 or higher.
|
|
|
|
-}
|
|
|
|
|
|
|
|
module Annex.GitOverlay where
|
|
|
|
|
|
|
|
import qualified Control.Exception as E
|
|
|
|
|
|
|
|
import Annex.Common
|
|
|
|
import Git
|
|
|
|
import Git.Types
|
|
|
|
import Git.Env
|
|
|
|
import qualified Annex
|
|
|
|
|
|
|
|
{- Runs an action using a different git index file. -}
|
|
|
|
withIndexFile :: FilePath -> Annex a -> Annex a
|
|
|
|
withIndexFile f = withAltRepo
|
|
|
|
(\g -> addGitEnv g "GIT_INDEX_FILE" f)
|
|
|
|
(\g g' -> g' { gitEnv = gitEnv g })
|
|
|
|
|
2016-04-06 21:32:04 +00:00
|
|
|
{- Runs an action using a different git work tree.
|
|
|
|
-
|
|
|
|
- Smudge and clean filters are disabled in this work tree. -}
|
2016-04-06 19:33:29 +00:00
|
|
|
withWorkTree :: FilePath -> Annex a -> Annex a
|
|
|
|
withWorkTree d = withAltRepo
|
2016-04-06 21:32:04 +00:00
|
|
|
(\g -> return $ g { location = modlocation (location g), gitGlobalOpts = gitGlobalOpts g ++ disableSmudgeConfig })
|
|
|
|
(\g g' -> g' { location = location g, gitGlobalOpts = gitGlobalOpts g })
|
2016-04-06 19:33:29 +00:00
|
|
|
where
|
|
|
|
modlocation l@(Local {}) = l { worktree = Just d }
|
|
|
|
modlocation _ = error "withWorkTree of non-local git repo"
|
2016-04-06 21:32:04 +00:00
|
|
|
disableSmudgeConfig = map Param
|
|
|
|
[ "-c", "filter.annex.smudge="
|
|
|
|
, "-c", "filter.annex.clean="
|
|
|
|
]
|
2016-04-06 19:33:29 +00:00
|
|
|
|
|
|
|
{- Runs an action with the git index file and HEAD, and a few other
|
|
|
|
- files that are related to the work tree coming from an overlay
|
|
|
|
- directory other than the usual. This is done by pointing
|
|
|
|
- GIT_COMMON_DIR at the regular git directory, and GIT_DIR at the
|
2016-04-22 16:29:32 +00:00
|
|
|
- overlay directory.
|
|
|
|
-
|
|
|
|
- Needs git 2.2.0 or newer.
|
|
|
|
-}
|
2016-04-06 19:33:29 +00:00
|
|
|
withWorkTreeRelated :: FilePath -> Annex a -> Annex a
|
|
|
|
withWorkTreeRelated d = withAltRepo modrepo unmodrepo
|
|
|
|
where
|
|
|
|
modrepo g = do
|
2016-04-08 18:24:00 +00:00
|
|
|
g' <- addGitEnv g "GIT_COMMON_DIR" =<< absPath (localGitDir g)
|
|
|
|
g'' <- addGitEnv g' "GIT_DIR" d
|
|
|
|
return (g'' { gitEnvOverridesGitDir = True })
|
|
|
|
unmodrepo g g' = g'
|
|
|
|
{ gitEnv = gitEnv g
|
|
|
|
, gitEnvOverridesGitDir = gitEnvOverridesGitDir g
|
|
|
|
}
|
2016-04-06 19:33:29 +00:00
|
|
|
|
|
|
|
withAltRepo
|
|
|
|
:: (Repo -> IO Repo)
|
|
|
|
-- ^ modify Repo
|
|
|
|
-> (Repo -> Repo -> Repo)
|
|
|
|
-- ^ undo modifications; first Repo is the original and second
|
|
|
|
-- is the one after running the action.
|
|
|
|
-> Annex a
|
|
|
|
-> Annex a
|
|
|
|
withAltRepo modrepo unmodrepo a = do
|
|
|
|
g <- gitRepo
|
|
|
|
g' <- liftIO $ modrepo g
|
|
|
|
r <- tryNonAsync $ do
|
|
|
|
Annex.changeState $ \s -> s { Annex.repo = g' }
|
|
|
|
a
|
|
|
|
Annex.changeState $ \s -> s { Annex.repo = unmodrepo g (Annex.repo s) }
|
|
|
|
either E.throw return r
|