diff options
author | Joey Hess <joey@kitenet.net> | 2010-11-02 01:07:34 -0400 |
---|---|---|
committer | Joey Hess <joey@kitenet.net> | 2010-11-02 01:07:34 -0400 |
commit | 790613333c2d946d28fe62ef7da8ed3a23428f99 (patch) | |
tree | c1aef7c3e84413352c663247c0f323d48295d91a /GitRepo.hs | |
parent | 58c89565e9f9b3a05b0b4ff33944b543d226c398 (diff) |
deal with git's insane octal filename encoding
Diffstat (limited to 'GitRepo.hs')
-rw-r--r-- | GitRepo.hs | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/GitRepo.hs b/GitRepo.hs index 244acda86..389aa35fe 100644 --- a/GitRepo.hs +++ b/GitRepo.hs @@ -156,11 +156,40 @@ checkAttr repo attr files = do where params = gitCommandLine repo ["check-attr", attr, "-z", "--stdin"] files0 = join "\0" files - topair l = (bits !! 0, join sep $ drop 1 $ bits) + topair l = (file, value) where + file = decodeGitFile $ join sep $ take end bits + value = bits !! end + end = length bits - 1 bits = split sep l sep = ": " ++ attr ++ ": " +{- Some git commands output encoded filenames. Such a filename + - will always be double-quoted, and then \nnn (in octal) is used + - to escape high characters. -} +decodeGitFile :: String -> FilePath +decodeGitFile [] = [] +decodeGitFile f@(c:s) + | c == '"' = unescape middle + | otherwise = f + where + e = "\\" + middle = take (length s - 1) s + unescape v = foldl (++) beginning $ map decode $ split e rest + where + pair = span (/= '\\') v + beginning = fst pair + rest = snd pair + decode [] = "" + decode n + | length num == 3 = (chr $ readoctal num):rest + | otherwise = e++n + where + pair = span isOctDigit n + num = fst pair + rest = snd pair + readoctal o = read $ "0o" ++ o :: Int + {- Path to a repository's .git directory, relative to its workTree. -} gitDir :: Repo -> String gitDir repo |