summaryrefslogtreecommitdiff
path: root/Git/Ref.hs
diff options
context:
space:
mode:
authorJoey Hess <joeyh@joeyh.name>2022-05-04 11:40:38 -0400
committerJoey Hess <joeyh@joeyh.name>2022-05-04 11:43:20 -0400
commitc244daa32328f478bbf38a79f2fcacb138a1049f (patch)
treef1b2691357b88b267b9a77d5db23213bf0e2ac79 /Git/Ref.hs
parent3c9630388ab0234df9e13473ac20c147e77074c5 (diff)
downloadgit-repair-c244daa32328f478bbf38a79f2fcacb138a1049f.tar.gz
merge from git-annex
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