diff options
author | Roman Smrž <roman.smrz@seznam.cz> | 2025-03-07 22:00:57 +0100 |
---|---|---|
committer | Roman Smrž <roman.smrz@seznam.cz> | 2025-03-07 22:00:57 +0100 |
commit | b2295603ac1a8e333079fe1a87c04b27bd4ce157 (patch) | |
tree | cdc68ec6d734b100453c22ab68ae09459fec9205 | |
parent | 53ed8a2eb2c0f8eab4c346114c0b777cdf7c9f55 (diff) |
Subtree checkout option
-rw-r--r-- | src/Command/Checkout.hs | 10 | ||||
-rw-r--r-- | src/Repo.hs | 15 |
2 files changed, 24 insertions, 1 deletions
diff --git a/src/Command/Checkout.hs b/src/Command/Checkout.hs index 0ed062d..65857b8 100644 --- a/src/Command/Checkout.hs +++ b/src/Command/Checkout.hs @@ -15,6 +15,7 @@ data CheckoutCommand = CheckoutCommand CheckoutOptions (Maybe RepoName) Text data CheckoutOptions = CheckoutOptions { coPath :: Maybe FilePath + , coSubtree :: Maybe FilePath } instance Command CheckoutCommand where @@ -30,12 +31,16 @@ instance Command CheckoutCommand where type CommandOptions CheckoutCommand = CheckoutOptions defaultCommandOptions _ = CheckoutOptions { coPath = Nothing + , coSubtree = Nothing } commandOptions _ = [ Option [] [ "path" ] (ReqArg (\val opts -> opts { coPath = Just val }) "<path>") "destination path" + , Option [] [ "subtree" ] + (ReqArg (\val opts -> opts { coSubtree = Just val }) "<path>") + "repository subtree to checkout" ] commandInit _ co = uncurry (CheckoutCommand co) . \case @@ -47,5 +52,8 @@ instance Command CheckoutCommand where cmdCheckout :: CheckoutCommand -> CommandExec () cmdCheckout (CheckoutCommand CheckoutOptions {..} name revision) = do repo <- maybe getDefaultRepo getRepo name - tree <- maybe (fail $ T.unpack $ "revision `" <> revision <> "' not found") getCommitTree =<< readCommit repo revision + root <- maybe (fail $ T.unpack $ "revision `" <> revision <> "' not found") getCommitTree =<< readCommit repo revision + tree <- case coSubtree of + Nothing -> return root + Just subtree -> maybe (fail $ "subtree `" <> subtree <> "' not found in revision `" <> T.unpack revision <> "'") return =<< getSubtree subtree root checkoutAt tree $ maybe "." id coPath diff --git a/src/Repo.hs b/src/Repo.hs index 0720179..ef95b36 100644 --- a/src/Repo.hs +++ b/src/Repo.hs @@ -19,6 +19,8 @@ module Repo ( getCommitTitle, getCommitMessage, + getSubtree, + checkoutAt, readCommittedFile, @@ -245,6 +247,19 @@ getCommitMessage :: (MonadIO m, MonadFail m) => Commit -> m Text getCommitMessage = fmap commitMessage . getCommitDetails +getSubtree :: MonadIO m => FilePath -> Tree -> m (Maybe Tree) +getSubtree path tree = liftIO $ do + let GitRepo {..} = treeRepo tree + readProcessWithExitCode "git" [ "--git-dir=" <> gitDir, "rev-parse", "--verify", "--quiet", showTreeId (treeId tree) <> ":" <> path ] "" >>= \case + ( ExitSuccess, out, _ ) | tid : _ <- lines out -> do + return $ Just Tree + { treeRepo = treeRepo tree + , treeId = TreeId (BC.pack tid) + } + _ -> do + return Nothing + + checkoutAt :: (MonadIO m, MonadFail m) => Tree -> FilePath -> m () checkoutAt Tree {..} dest = do let GitRepo {..} = treeRepo |