summaryrefslogtreecommitdiff
path: root/Git/Config.hs
diff options
context:
space:
mode:
Diffstat (limited to 'Git/Config.hs')
-rw-r--r--Git/Config.hs62
1 files changed, 45 insertions, 17 deletions
diff --git a/Git/Config.hs b/Git/Config.hs
index 38b9ade45..e37b43707 100644
--- a/Git/Config.hs
+++ b/Git/Config.hs
@@ -1,15 +1,14 @@
{- git repository configuration handling
-
- - Copyright 2010,2011 Joey Hess <joey@kitenet.net>
+ - Copyright 2010-2012 Joey Hess <joey@kitenet.net>
-
- Licensed under the GNU GPL version 3 or higher.
-}
module Git.Config where
-import System.Posix.Directory
-import Control.Exception (bracket_)
import qualified Data.Map as M
+import Data.Char
import Common
import Git
@@ -30,17 +29,14 @@ getMaybe key repo = M.lookup key (config repo)
{- Runs git config and populates a repo with its config. -}
read :: Repo -> IO Repo
-read repo@(Repo { location = Dir d }) = bracketcd d $
- {- Cannot use pipeRead because it relies on the config having
- been already read. Instead, chdir to the repo. -}
+read repo@(Repo { location = Local { gitdir = d } }) = read' repo d
+read repo@(Repo { location = LocalUnknown d }) = read' repo d
+read r = assertLocal r $ error "internal"
+{- Cannot use pipeRead because it relies on the config having
+ been already read. Instead, chdir to the repo. -}
+read' :: Repo -> FilePath -> IO Repo
+read' repo d = bracketCd d $
pOpen ReadFromPipe "git" ["config", "--null", "--list"] $ hRead repo
- where
- bracketcd to a = bracketcd' to a =<< getCurrentDirectory
- bracketcd' to a cwd
- | dirContains to cwd = a
- | otherwise = bracket_ (changeWorkingDirectory to) (changeWorkingDirectory cwd) a
-read r = assertLocal r $
- error $ "internal error; trying to read config of " ++ show r
{- Reads git config from a handle and populates a repo with it. -}
hRead :: Repo -> Handle -> IO Repo
@@ -48,19 +44,42 @@ hRead repo h = do
val <- hGetContentsStrict h
store val repo
-{- Stores a git config into a repo, returning the new version of the repo.
- - The git config may be multiple lines, or a single line. Config settings
- - can be updated inrementally. -}
+{- Stores a git config into a Repo, returning the new version of the Repo.
+ - The git config may be multiple lines, or a single line.
+ - Config settings can be updated incrementally.
+ -}
store :: String -> Repo -> IO Repo
store s repo = do
let c = parse s
- let repo' = repo
+ let repo' = updateLocation $ repo
{ config = (M.map Prelude.head c) `M.union` config repo
, fullconfig = M.unionWith (++) c (fullconfig repo)
}
+ print repo'
rs <- Git.Construct.fromRemotes repo'
return $ repo' { remotes = rs }
+{- Updates the location of a repo, based on its configuration.
+ -
+ - Git.Construct makes LocalUknown repos, of which only a directory is
+ - known. Once the config is read, this can be fixed up to a Local repo,
+ - based on the core.bare and core.worktree settings.
+ -}
+updateLocation :: Repo -> Repo
+updateLocation r = go $ location r
+ where
+ go (LocalUnknown d)
+ | isbare = ret $ Local d Nothing
+ | otherwise = ret $ Local (d </> ".git") (Just d)
+ go l@(Local {}) = ret l
+ go _ = r
+ isbare = fromMaybe False $ isTrue =<< getMaybe "core.bare" r
+ ret l = r { location = l' }
+ where
+ l' = maybe l (setworktree l) $
+ getMaybe "core.worktree" r
+ setworktree l t = l { worktree = Just t }
+
{- Parses git config --list or git config --null --list output into a
- config map. -}
parse :: String -> M.Map String [String]
@@ -74,3 +93,12 @@ parse s
ls = lines s
sep c = M.fromListWith (++) . map (\(k,v) -> (k, [v])) .
map (separate (== c))
+
+{- Checks if a string from git config is a true value. -}
+isTrue :: String -> Maybe Bool
+isTrue s
+ | s' == "true" = Just True
+ | s' == "false" = Just False
+ | otherwise = Nothing
+ where
+ s' = map toLower s