summaryrefslogtreecommitdiff
path: root/Git
diff options
context:
space:
mode:
authorGravatar Joey Hess <joey@kitenet.net>2013-09-19 15:58:35 -0400
committerGravatar Joey Hess <joey@kitenet.net>2013-09-19 15:58:35 -0400
commit5fddb08efccedd5c1542f5e16ec63a57498bc1f0 (patch)
tree7b73782d332fea41fbe3dae4db846fa577858683 /Git
parent2ec103cb68110deee36e8445d7320d0297ed4342 (diff)
interface to parse git tree objects
Diffstat (limited to 'Git')
-rw-r--r--Git/CatFile.hs26
1 files changed, 26 insertions, 0 deletions
diff --git a/Git/CatFile.hs b/Git/CatFile.hs
index 46b59c631..984d2f465 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