{- git-update-index library - - Copyright 2011, 2012 Joey Hess - - Licensed under the GNU GPL version 3 or higher. -} {-# LANGUAGE BangPatterns #-} module Git.UpdateIndex ( Streamer, pureStreamer, streamUpdateIndex, lsTree, updateIndexLine, stageSymlink ) where import System.Cmd.Utils import Common import Git import Git.Types import Git.Command import Git.FilePath import Git.HashObject {- Streamers are passed a callback and should feed it lines in the form - read by update-index, and generated by ls-tree. -} type Streamer = (String -> IO ()) -> IO () {- A streamer with a precalculated value. -} pureStreamer :: String -> Streamer pureStreamer !s = \streamer -> streamer s {- Streams content into update-index from a list of Streamers. -} streamUpdateIndex :: Repo -> [Streamer] -> IO () streamUpdateIndex repo as = do (p, h) <- hPipeTo "git" (toCommand $ gitCommandLine params repo) fileEncoding h forM_ as (stream h) hClose h forceSuccess p where params = map Param ["update-index", "-z", "--index-info"] stream h a = a (streamer h) streamer h s = do hPutStr h s hPutStr h "\0" {- A streamer that adds the current tree for a ref. Useful for eg, copying - and modifying branches. -} lsTree :: Ref -> Repo -> Streamer lsTree (Ref x) repo streamer = mapM_ streamer =<< pipeNullSplit params repo where params = map Param ["ls-tree", "-z", "-r", "--full-tree", x] {- Generates a line suitable to be fed into update-index, to add - a given file with a given sha. -} updateIndexLine :: Sha -> BlobType -> TopFilePath -> String updateIndexLine sha filetype file = show filetype ++ " blob " ++ show sha ++ "\t" ++ getTopFilePath file {- A streamer that adds a symlink to the index. -} stageSymlink :: FilePath -> String -> Repo -> IO Streamer stageSymlink file linktext repo = do line <- updateIndexLine <$> hashObject BlobObject linktext repo <*> pure SymlinkBlob <*> toTopFilePath file repo return $ pureStreamer line