From f26c996dc6767e1b644b30e0280c904095602d5f Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Thu, 19 Sep 2013 15:58:35 -0400 Subject: [PATCH] interface to parse git tree objects --- Git/CatFile.hs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/Git/CatFile.hs b/Git/CatFile.hs index 46b59c631d..984d2f465d 100644 --- a/Git/CatFile.hs +++ b/Git/CatFile.hs @@ -10,6 +10,7 @@ module Git.CatFile ( catFileStart, catFileStop, catFile, + catTree, catObject, catObjectDetails, ) where @@ -20,6 +21,8 @@ import qualified Data.ByteString.Lazy as L import Data.Digest.Pure.SHA import Data.Char import System.Process (std_out, std_err) +import Numeric +import System.Posix.Types import Common import Git @@ -105,3 +108,26 @@ catObjectDetails (CatFileHandle hdl repo) object = CoProcess.query hdl send rece return $ if ok then Just (content, Ref sha) else Nothing + +{- Gets a list of files and directories in a tree. (Not recursive.) -} +catTree :: CatFileHandle -> Ref -> IO [(FilePath, FileMode)] +catTree h treeref = go <$> catObjectDetails h treeref + where + go Nothing = [] + go (Just (b, _)) = parsetree [] b + + parsetree c b = case L.break (== 0) b of + (modefile, rest) + | L.null modefile -> c + | otherwise -> parsetree + (parsemodefile modefile:c) + (dropsha rest) + + -- these 20 bytes after the NUL hold the file's sha + -- TODO: convert from raw form to regular sha + dropsha = L.drop 21 + + parsemodefile b = + let (modestr, file) = separate (== ' ') (encodeW8 $ L.unpack b) + in (file, readmode modestr) + readmode = fst . Prelude.head . readOct