aboutsummaryrefslogtreecommitdiffstats
path: root/app/Git.hs
diff options
context:
space:
mode:
Diffstat (limited to 'app/Git.hs')
-rw-r--r--app/Git.hs18
1 files changed, 15 insertions, 3 deletions
diff --git a/app/Git.hs b/app/Git.hs
index eae3a85..2e8fa82 100644
--- a/app/Git.hs
+++ b/app/Git.hs
@@ -31,7 +31,7 @@ import Exception qualified as E
import GHC.Generics (Generic)
import Git.CommitHash
import Patch qualified as A
-import Process (proc, sh)
+import Process (proc, sh, sh_)
import Text.Printf (printf)
getCommitHashes :: IO (NonEmpty T.Text)
@@ -96,6 +96,7 @@ readTextFileOfText = readTextFileOf LT.readFile LT.decodeUtf8
readTextFileOfBS :: CommitHash -> FilePath -> IO LB.ByteString
readTextFileOfBS = readTextFileOf LB.readFile id
+
-- REVIEW Suggestion: we could use `id` instead of `\x -> x`
--
-- REVIEW OK!
@@ -118,9 +119,20 @@ resolveRef =
. sh
. proc "git rev-parse %"
--- TODO Throw if `prevHash` is not an ancestor of `hash`.
+-- | `getCommitsBetween prevCommit commit` returns the commits from `prevCommit` to `commit`. The result excludes `prevCommit`, but includes `commit`.
+--
+-- If `prevCommit` is not an ancestor of `commit`, this functions throws `NoAncestor commit prevCommit`.
getCommitsBetween :: CommitHash -> CommitHash -> IO [CommitHash]
-getCommitsBetween (Commit prevHash) (Commit hash) = do
+getCommitsBetween WorkingTree commit@(Commit _) =
+ throwIO (E.NoAncestor WorkingTree commit)
+getCommitsBetween WorkingTree WorkingTree = pure [WorkingTree]
+getCommitsBetween prevCommit WorkingTree =
+ fmap (++ [WorkingTree]) . getCommitsBetween prevCommit
+ =<< resolveRef "HEAD"
+getCommitsBetween prevCommit@(Commit prevHash) commit@(Commit hash) = do
+ catch
+ (sh_ (proc "git merge-base --is-ancestor % %" prevHash hash))
+ (\(_ :: E.ProcessException) -> throwIO (E.NoAncestor commit prevCommit))
map (Commit . T.strip) . T.lines . T.decodeUtf8 . LB.toStrict
<$> sh (proc "git log --format=%%H %..%" prevHash hash)