diff options
author | Joey Hess <joey@kitenet.net> | 2011-12-30 14:07:17 -0400 |
---|---|---|
committer | Joey Hess <joey@kitenet.net> | 2011-12-30 14:07:46 -0400 |
commit | 5287d1dc3f293b6eb7f6759fe9f25be1ad85fbae (patch) | |
tree | a1b88f731331bbff60edd207403e56bd1ea87cc7 | |
parent | 3dffcf9ccb4eebba48e904b9fb5bfe5d8446b761 (diff) |
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.
-rw-r--r-- | Git/Config.hs | 11 | ||||
-rw-r--r-- | Git/Construct.hs | 6 | ||||
-rw-r--r-- | Git/Types.hs | 2 | ||||
-rw-r--r-- | debian/changelog | 2 |
4 files changed, 17 insertions, 4 deletions
diff --git a/Git/Config.hs b/Git/Config.hs index 7b72eba5a..b2587aa44 100644 --- a/Git/Config.hs +++ b/Git/Config.hs @@ -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)) diff --git a/Git/Construct.hs b/Git/Construct.hs index a35a87cc7..2cc965b4e 100644 --- a/Git/Construct.hs +++ b/Git/Construct.hs @@ -115,7 +115,6 @@ remoteNamedFromKey k = remoteNamed basename fromRemoteLocation :: String -> Repo -> IO Repo fromRemoteLocation s repo = gen $ calcloc s where - filterconfig f = filter f $ M.toList $ config repo gen v | scpstyle v = fromUrl $ scptourl v | isURI v = fromUrl v @@ -133,6 +132,10 @@ fromRemoteLocation s repo = gen $ calcloc s startswith prefix k && endswith suffix k && startswith v l + filterconfig f = filter f $ + concatMap splitconfigs $ + M.toList $ fullconfig repo + splitconfigs (k, vs) = map (\v -> (k, v)) vs (prefix, suffix) = ("url." , ".insteadof") -- git remotes can be written scp style -- [user@]host:dir scpstyle v = ":" `isInfixOf` v && not ("//" `isInfixOf` v) @@ -210,6 +213,7 @@ newFrom l = Repo { location = l, config = M.empty, + fullconfig = M.empty, remotes = [], remoteName = Nothing } diff --git a/Git/Types.hs b/Git/Types.hs index 250da5f5e..6063ad213 100644 --- a/Git/Types.hs +++ b/Git/Types.hs @@ -18,6 +18,8 @@ data RepoLocation = Dir FilePath | Url URI | Unknown data Repo = Repo { location :: RepoLocation, config :: M.Map String String, + -- a given git config key can actually have multiple values + fullconfig :: M.Map String [String], remotes :: [Repo], -- remoteName holds the name used for this repo in remotes remoteName :: Maybe String diff --git a/debian/changelog b/debian/changelog index 33d196fa3..bbed54765 100644 --- a/debian/changelog +++ b/debian/changelog @@ -13,6 +13,8 @@ git-annex (3.20111212) UNRELEASED; urgency=low * Format strings can be specified using the new --format option, to control what is output by git annex find. * Support git annex find --json + * Fixed behavior when multiple insteadOf configs are provided for the + same url base. -- Joey Hess <joeyh@debian.org> Mon, 12 Dec 2011 01:57:49 -0400 |