summaryrefslogtreecommitdiff
path: root/src/Repo.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Repo.hs')
-rw-r--r--src/Repo.hs27
1 files changed, 27 insertions, 0 deletions
diff --git a/src/Repo.hs b/src/Repo.hs
index 9e05ccd..c0500f3 100644
--- a/src/Repo.hs
+++ b/src/Repo.hs
@@ -7,6 +7,7 @@ module Repo (
listCommits,
checkoutAt,
readTreeId,
+ readCommittedFile,
) where
import Control.Concurrent
@@ -15,6 +16,7 @@ import Control.Monad.IO.Class
import Data.ByteString (ByteString)
import Data.ByteString.Char8 qualified as BC
+import Data.ByteString.Lazy qualified as BL
import Data.Text (Text)
import Data.Text qualified as T
@@ -93,3 +95,28 @@ readTreeId Commit {..} = do
liftIO $ withMVar gitLock $ \_ -> do
[ "tree", tid ] : _ <- map words . lines <$> readProcess "git" [ "--git-dir=" <> gitDir, "cat-file", "commit", showCommitId commitId ] ""
return $ TreeId $ BC.pack tid
+
+
+readCommittedFile :: Commit -> FilePath -> IO (Maybe BL.ByteString)
+readCommittedFile Commit {..} path = do
+ let GitRepo {..} = commitRepo
+ liftIO $ withMVar gitLock $ \_ -> do
+ let cmd = (proc "git" [ "--git-dir=" <> gitDir, "cat-file", "blob", showCommitId commitId <> ":" <> path ])
+ { std_in = NoStream
+ , std_out = CreatePipe
+ }
+ createProcess cmd >>= \( _, mbstdout, _, ph ) -> if
+ | Just stdout <- mbstdout -> do
+ content <- BL.hGetContents stdout
+
+ -- check if there will be some output:
+ case BL.uncons content of
+ Just (c, _) -> c `seq` return ()
+ Nothing -> return ()
+
+ getProcessExitCode ph >>= \case
+ Just code | code /= ExitSuccess ->
+ return Nothing
+ _ ->
+ return (Just content)
+ | otherwise -> error "createProcess must return stdout handle"