summaryrefslogtreecommitdiff
path: root/Git.hs
diff options
context:
space:
mode:
Diffstat (limited to 'Git.hs')
-rw-r--r--Git.hs42
1 files changed, 24 insertions, 18 deletions
diff --git a/Git.hs b/Git.hs
index 87a8d19..e567917 100644
--- a/Git.hs
+++ b/Git.hs
@@ -1,19 +1,21 @@
{- git repository handling
-
- - This is written to be completely independant of git-annex and should be
+ - This is written to be completely independent of git-annex and should be
- suitable for other uses.
-
- - Copyright 2010-2012 Joey Hess <id@joeyh.name>
+ - Copyright 2010-2021 Joey Hess <id@joeyh.name>
-
- Licensed under the GNU AGPL version 3 or higher.
-}
+{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE CPP #-}
module Git (
Repo(..),
Ref(..),
fromRef,
+ fromRef',
Branch,
Sha,
Tag,
@@ -36,10 +38,12 @@ module Git (
relPath,
) where
+import qualified Data.ByteString as B
import Network.URI (uriPath, uriScheme, unEscapeString)
#ifndef mingw32_HOST_OS
import System.Posix.Files
#endif
+import qualified System.FilePath.ByteString as P
import Common
import Git.Types
@@ -51,6 +55,7 @@ import Utility.FileMode
repoDescribe :: Repo -> String
repoDescribe Repo { remoteName = Just name } = name
repoDescribe Repo { location = Url url } = show url
+repoDescribe Repo { location = UnparseableUrl url } = url
repoDescribe Repo { location = Local { worktree = Just dir } } = fromRawFilePath dir
repoDescribe Repo { location = Local { gitdir = dir } } = fromRawFilePath dir
repoDescribe Repo { location = LocalUnknown dir } = fromRawFilePath dir
@@ -59,10 +64,11 @@ repoDescribe Repo { location = Unknown } = "UNKNOWN"
{- Location of the repo, either as a path or url. -}
repoLocation :: Repo -> String
repoLocation Repo { location = Url url } = show url
+repoLocation Repo { location = UnparseableUrl url } = url
repoLocation Repo { location = Local { worktree = Just dir } } = fromRawFilePath dir
repoLocation Repo { location = Local { gitdir = dir } } = fromRawFilePath dir
repoLocation Repo { location = LocalUnknown dir } = fromRawFilePath dir
-repoLocation Repo { location = Unknown } = error "unknown repoLocation"
+repoLocation Repo { location = Unknown } = giveup "unknown repoLocation"
{- Path to a repository. For non-bare, this is the worktree, for bare,
- it's the gitdir, and for URL repositories, is the path on the remote
@@ -72,7 +78,8 @@ repoPath Repo { location = Url u } = toRawFilePath $ unEscapeString $ uriPath u
repoPath Repo { location = Local { worktree = Just d } } = d
repoPath Repo { location = Local { gitdir = d } } = d
repoPath Repo { location = LocalUnknown dir } = dir
-repoPath Repo { location = Unknown } = error "unknown repoPath"
+repoPath Repo { location = Unknown } = giveup "unknown repoPath"
+repoPath Repo { location = UnparseableUrl _u } = giveup "unknown repoPath"
repoWorkTree :: Repo -> Maybe RawFilePath
repoWorkTree Repo { location = Local { worktree = Just d } } = Just d
@@ -81,12 +88,13 @@ repoWorkTree _ = Nothing
{- Path to a local repository's .git directory. -}
localGitDir :: Repo -> RawFilePath
localGitDir Repo { location = Local { gitdir = d } } = d
-localGitDir _ = error "unknown localGitDir"
+localGitDir _ = giveup "unknown localGitDir"
{- Some code needs to vary between URL and normal repos,
- or bare and non-bare, these functions help with that. -}
repoIsUrl :: Repo -> Bool
repoIsUrl Repo { location = Url _ } = True
+repoIsUrl Repo { location = UnparseableUrl _ } = True
repoIsUrl _ = False
repoIsSsh :: Repo -> Bool
@@ -121,7 +129,7 @@ repoIsLocalUnknown _ = False
assertLocal :: Repo -> a -> a
assertLocal repo action
- | repoIsUrl repo = error $ unwords
+ | repoIsUrl repo = giveup $ unwords
[ "acting on non-local git repo"
, repoDescribe repo
, "not supported"
@@ -129,14 +137,13 @@ assertLocal repo action
| otherwise = action
{- Path to a repository's gitattributes file. -}
-attributes :: Repo -> FilePath
+attributes :: Repo -> RawFilePath
attributes repo
| repoIsLocalBare repo = attributesLocal repo
- | otherwise = fromRawFilePath (repoPath repo) </> ".gitattributes"
+ | otherwise = repoPath repo P.</> ".gitattributes"
-attributesLocal :: Repo -> FilePath
-attributesLocal repo = fromRawFilePath (localGitDir repo)
- </> "info" </> "attributes"
+attributesLocal :: Repo -> RawFilePath
+attributesLocal repo = localGitDir repo P.</> "info" P.</> "attributes"
{- Path to a given hook script in a repository, only if the hook exists
- and is executable. -}
@@ -149,7 +156,7 @@ hookPath script repo = do
#if mingw32_HOST_OS
isexecutable f = doesFileExist f
#else
- isexecutable f = isExecutable . fileMode <$> getFileStatus f
+ isexecutable f = isExecutable . fileMode <$> getSymbolicLinkStatus f
#endif
{- Makes the path to a local Repo be relative to the cwd. -}
@@ -158,13 +165,13 @@ relPath = adjustPath torel
where
torel p = do
p' <- relPathCwdToFile p
- return $ if null p' then "." else p'
+ return $ if B.null p' then "." else p'
{- Adusts the path to a local Repo using the provided function. -}
-adjustPath :: (FilePath -> IO FilePath) -> Repo -> IO Repo
+adjustPath :: (RawFilePath -> IO RawFilePath) -> Repo -> IO Repo
adjustPath f r@(Repo { location = l@(Local { gitdir = d, worktree = w }) }) = do
- d' <- f' d
- w' <- maybe (pure Nothing) (Just <$$> f') w
+ d' <- f d
+ w' <- maybe (pure Nothing) (Just <$$> f) w
return $ r
{ location = l
{ gitdir = d'
@@ -172,8 +179,7 @@ adjustPath f r@(Repo { location = l@(Local { gitdir = d, worktree = w }) }) = do
}
}
where
- f' v = toRawFilePath <$> f (fromRawFilePath v)
adjustPath f r@(Repo { location = LocalUnknown d }) = do
- d' <- toRawFilePath <$> f (fromRawFilePath d)
+ d' <- f d
return $ r { location = LocalUnknown d' }
adjustPath _ r = pure r