summaryrefslogtreecommitdiff
path: root/Git/Ref.hs
diff options
context:
space:
mode:
Diffstat (limited to 'Git/Ref.hs')
-rw-r--r--Git/Ref.hs33
1 files changed, 20 insertions, 13 deletions
diff --git a/Git/Ref.hs b/Git/Ref.hs
index 6929a8e..2d2874a 100644
--- a/Git/Ref.hs
+++ b/Git/Ref.hs
@@ -64,17 +64,21 @@ branchRef = underBase "refs/heads"
{- A Ref that can be used to refer to a file in the repository, as staged
- in the index.
+ -
+ - If the input file is located outside the repository, returns Nothing.
-}
-fileRef :: RawFilePath -> IO Ref
-fileRef f = do
+fileRef :: RawFilePath -> Repo -> IO (Maybe Ref)
+fileRef f repo = do
-- The filename could be absolute, or contain eg "../repo/file",
-- neither of which work in a ref, so convert it to a minimal
-- relative path.
f' <- relPathCwdToFile f
- -- Prefixing the file with ./ makes this work even when in a
- -- subdirectory of a repo. Eg, ./foo in directory bar refers
- -- to bar/foo, not to foo in the top of the repository.
- return $ Ref $ ":./" <> toInternalGitPath f'
+ return $ if repoPath repo `dirContains` f'
+ -- Prefixing the file with ./ makes this work even when in a
+ -- subdirectory of a repo. Eg, ./foo in directory bar refers
+ -- to bar/foo, not to foo in the top of the repository.
+ then Just $ Ref $ ":./" <> toInternalGitPath f'
+ else Nothing
{- A Ref that can be used to refer to a file in a particular branch. -}
branchFileRef :: Branch -> RawFilePath -> Ref
@@ -82,14 +86,17 @@ branchFileRef branch f = Ref $ fromRef' branch <> ":" <> toInternalGitPath f
{- Converts a Ref to refer to the content of the Ref on a given date. -}
dateRef :: Ref -> RefDate -> Ref
-dateRef r (RefDate d) = Ref $ fromRef' r <> "@" <> encodeBS' d
+dateRef r (RefDate d) = Ref $ fromRef' r <> "@" <> encodeBS d
{- A Ref that can be used to refer to a file in the repository as it
- - appears in a given Ref. -}
-fileFromRef :: Ref -> RawFilePath -> IO Ref
-fileFromRef r f = do
- (Ref fr) <- fileRef f
- return (Ref (fromRef' r <> fr))
+ - appears in a given Ref.
+ -
+ - If the file path is located outside the repository, returns Nothing.
+ -}
+fileFromRef :: Ref -> RawFilePath -> Repo -> IO (Maybe Ref)
+fileFromRef r f repo = fileRef f repo >>= return . \case
+ Just (Ref fr) -> Just (Ref (fromRef' r <> fr))
+ Nothing -> Nothing
{- Checks if a ref exists. Note that it must be fully qualified,
- eg refs/heads/master rather than master. -}
@@ -177,7 +184,7 @@ tree (Ref ref) = extractSha <$$> pipeReadStrict
[ Param "rev-parse"
, Param "--verify"
, Param "--quiet"
- , Param (decodeBS' ref')
+ , Param (decodeBS ref')
]
where
ref' = if ":" `S.isInfixOf` ref