summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Joey Hess <joey@kitenet.net>2011-06-30 13:12:51 -0400
committerGravatar Joey Hess <joey@kitenet.net>2011-06-30 13:12:51 -0400
commit5fe02f280726442496303859e83f9ce1c48be0cb (patch)
tree004f47441faed4b1af09b5bdb425399b058d83f8
parent8562e6096ca9a6819c04b4fd1938202ccd68c701 (diff)
more robust git cat-file output parser
Only remaining ugliness is the handling of error messages for files that are not present on the branch.
-rw-r--r--Branch.hs30
1 files changed, 18 insertions, 12 deletions
diff --git a/Branch.hs b/Branch.hs
index ab24e4752..5ad89df20 100644
--- a/Branch.hs
+++ b/Branch.hs
@@ -243,8 +243,8 @@ catFile file = do
[Param "cat-file", Param "--batch"]
let gitcmd = join " " ("git" : toCommand cmd)
(_, from, to) <- liftIO $ hPipeBoth "sh"
- -- want stderr on stdin to handle error messages
- ["-c", "LANG=C exec " ++ gitcmd ++ " 2>&1"]
+ -- want stderr on stdin to see error messages
+ ["-c", "exec " ++ gitcmd ++ " 2>&1"]
setState state { catFileHandles = Just (from, to) }
ask (from, to)
ask (from, to) = liftIO $ do
@@ -252,16 +252,22 @@ catFile file = do
hPutStrLn to want
hFlush to
header <- hGetLine from
- if header == want ++ " missing"
- then return ""
- else do
- let [_sha, _type, size] = words header
- let bytes = read size
- content <- B.hGet from bytes
- c <- hGetChar from
- when (c /= '\n') $
- error "missing newline from git cat-file"
- return $ B.unpack content
+ case words header of
+ [sha, blob, size]
+ | length sha == Git.shaSize &&
+ blob == "blob" -> handle from size
+ | otherwise -> empty
+ _ -> empty
+ handle from size = case reads size of
+ [(bytes, "")] -> readcontent from bytes
+ _ -> empty
+ readcontent from bytes = do
+ content <- B.hGet from bytes
+ c <- hGetChar from
+ when (c /= '\n') $
+ error "missing newline from git cat-file"
+ return $ B.unpack content
+ empty = return ""
{- Lists all files on the branch. There may be duplicates in the list. -}
files :: Annex [FilePath]