aboutsummaryrefslogtreecommitdiff
path: root/Git.hs
diff options
context:
space:
mode:
authorGravatar Joey Hess <joey@kitenet.net>2011-09-29 23:43:42 -0400
committerGravatar Joey Hess <joey@kitenet.net>2011-09-29 23:48:57 -0400
commit7ff89ccfee13dcfe89cbdef83454e880dabd7186 (patch)
tree953858f36ccd021832d286c6a5915e44a05081ce /Git.hs
parent949ef94d5e5583e55d6ba9797cf71177b252173d (diff)
convert all git read/write functions to use ByteStrings
This yields a second or so speedup in unused, find, etc. Seems that even when the ByteString is immediately split and then converted to Strings, it's faster. I may try to push ByteStrings out into more of git-annex gradually, although I suspect most of the time-critical parts are already covered now, and many of the rest rely on libraries that only support Strings.
Diffstat (limited to 'Git.hs')
-rw-r--r--Git.hs54
1 files changed, 36 insertions, 18 deletions
diff --git a/Git.hs b/Git.hs
index 4c4f00e8d..d32aaaa56 100644
--- a/Git.hs
+++ b/Git.hs
@@ -44,6 +44,7 @@ module Git (
pipeWrite,
pipeWriteRead,
pipeNullSplit,
+ pipeNullSplitB,
attributes,
remotes,
remotesAdd,
@@ -85,6 +86,7 @@ import Text.Printf
import Data.List (isInfixOf, isPrefixOf, isSuffixOf)
import System.Exit
import System.Posix.Env (setEnv, unsetEnv, getEnv)
+import qualified Data.ByteString.Lazy.Char8 as L
import Utility
import Utility.Path
@@ -379,22 +381,41 @@ run repo subcommand params = assertLocal repo $
- Note that this leaves the git process running, and so zombies will
- result unless reap is called.
-}
-pipeRead :: Repo -> [CommandParam] -> IO String
+pipeRead :: Repo -> [CommandParam] -> IO L.ByteString
pipeRead repo params = assertLocal repo $ do
- (_, s) <- pipeFrom "git" $ toCommand $ gitCommandLine repo params
- return s
+ (_, h) <- hPipeFrom "git" $ toCommand $ gitCommandLine repo params
+ hSetBinaryMode h True
+ L.hGetContents h
{- Runs a git subcommand, feeding it input.
- You should call either getProcessStatus or forceSuccess on the PipeHandle. -}
-pipeWrite :: Repo -> [CommandParam] -> String -> IO PipeHandle
-pipeWrite repo params s = assertLocal repo $
- pipeTo "git" (toCommand $ gitCommandLine repo params) s
+pipeWrite :: Repo -> [CommandParam] -> L.ByteString -> IO PipeHandle
+pipeWrite repo params s = assertLocal repo $ do
+ (p, h) <- hPipeTo "git" (toCommand $ gitCommandLine repo params)
+ L.hPut h s
+ hClose h
+ return p
{- Runs a git subcommand, feeding it input, and returning its output.
- You should call either getProcessStatus or forceSuccess on the PipeHandle. -}
-pipeWriteRead :: Repo -> [CommandParam] -> String -> IO (PipeHandle, String)
-pipeWriteRead repo params s = assertLocal repo $
- pipeBoth "git" (toCommand $ gitCommandLine repo params) s
+pipeWriteRead :: Repo -> [CommandParam] -> L.ByteString -> IO (PipeHandle, L.ByteString)
+pipeWriteRead repo params s = assertLocal repo $ do
+ (p, from, to) <- hPipeBoth "git" (toCommand $ gitCommandLine repo params)
+ hSetBinaryMode from True
+ L.hPut to s
+ hClose to
+ c <- L.hGetContents from
+ return (p, c)
+
+{- Reads null terminated output of a git command (as enabled by the -z
+ - parameter), and splits it. -}
+pipeNullSplit :: Repo -> [CommandParam] -> IO [String]
+pipeNullSplit repo params = map L.unpack <$> pipeNullSplitB repo params
+
+{- For when Strings are not needed. -}
+pipeNullSplitB :: Repo -> [CommandParam] -> IO [L.ByteString]
+pipeNullSplitB repo params = filter (not . L.null) . L.split '\0' <$>
+ pipeRead repo params
{- Reaps any zombie git processes. -}
reap :: IO ()
@@ -436,21 +457,18 @@ shaSize = 40
- with the specified parent refs. -}
commit :: Repo -> String -> String -> [String] -> IO ()
commit g message newref parentrefs = do
- tree <- getSha "write-tree" $
+ tree <- getSha "write-tree" $ asString $
pipeRead g [Param "write-tree"]
- sha <- getSha "commit-tree" $ ignorehandle $
- pipeWriteRead g (map Param $ ["commit-tree", tree] ++ ps) message
+ sha <- getSha "commit-tree" $ asString $
+ ignorehandle $ pipeWriteRead g
+ (map Param $ ["commit-tree", tree] ++ ps)
+ (L.pack message)
run g "update-ref" [Param newref, Param sha]
where
ignorehandle a = snd <$> a
+ asString a = L.unpack <$> a
ps = concatMap (\r -> ["-p", r]) parentrefs
-{- Reads null terminated output of a git command (as enabled by the -z
- - parameter), and splits it. -}
-pipeNullSplit :: Repo -> [CommandParam] -> IO [String]
-pipeNullSplit repo params = filter (not . null) . split "\0" <$>
- pipeRead repo params
-
{- Runs git config and populates a repo with its config. -}
configRead :: Repo -> IO Repo
configRead repo@(Repo { location = Dir d }) = do