fixed behavior when multiple insteadOf configs are provided for the same url base

Consider this git config --list case:

url.git+ssh://git@example.com/.insteadOf=gl
url.git+ssh://git@example.com/.insteadOf=shared

Since config is stored in a Map, only the last of the values for this key
was stored and available for use by the insteadOf code. But that
is wrong; git allows either "gl" or "shared" to be used in an url and
the insteadOf value to be substituted in.

To support this, it seems best to keep the existing config map as-is,
and add a second map that accumulates a list of multiple values for
config keys. This new fullconfig map can be used in the rare places where
multiple values for a key make sense, without needing to complicate
everything else.

Haskell's laziness and data sharing keep the overhead of adding
this second map low.
This commit is contained in:
Joey Hess 2011-12-30 14:07:17 -04:00
parent 3dffcf9ccb
commit 5287d1dc3f
4 changed files with 17 additions and 4 deletions

View file

@ -42,13 +42,17 @@ hRead repo h = do
- can be updated inrementally. -}
store :: String -> Repo -> IO Repo
store s repo = do
let repo' = repo { config = parse s `M.union` config repo }
let c = parse s
let repo' = repo
{ config = (M.map Prelude.head c) `M.union` config repo
, fullconfig = M.unionWith (++) c (fullconfig repo)
}
rs <- Git.Construct.fromRemotes repo'
return $ repo' { remotes = rs }
{- Parses git config --list or git config --null --list output into a
- config map. -}
parse :: String -> M.Map String String
parse :: String -> M.Map String [String]
parse [] = M.empty
parse s
-- --list output will have an = in the first line
@ -57,4 +61,5 @@ parse s
| otherwise = sep '\n' $ split "\0" s
where
ls = lines s
sep c = M.fromList . map (separate (== c))
sep c = M.fromListWith (++) . map (\(k,v) -> (k, [v])) .
map (separate (== c))