more OsPath conversion
Git.Types now uses it, as does TopFilePath, making for plenty of new compile errors needing fixing. Sponsored-by: Brock Spratlen
This commit is contained in:
parent
12660314f1
commit
ea775baccd
22 changed files with 159 additions and 163 deletions
|
@ -99,7 +99,7 @@ read' repo = go repo
|
|||
global :: IO (Maybe Repo)
|
||||
global = do
|
||||
home <- myHomeDir
|
||||
ifM (doesFileExist $ home </> ".gitconfig")
|
||||
ifM (doesFileExist $ toOsPath home </> literalOsPath ".gitconfig")
|
||||
( Just <$> withCreateProcess p go
|
||||
, return Nothing
|
||||
)
|
||||
|
@ -153,22 +153,22 @@ store' k v repo = repo
|
|||
-}
|
||||
updateLocation :: Repo -> IO Repo
|
||||
updateLocation r@(Repo { location = LocalUnknown d }) = case isBare r of
|
||||
Just True -> ifM (doesDirectoryExist (fromRawFilePath dotgit))
|
||||
Just True -> ifM (doesDirectoryExist dotgit)
|
||||
( updateLocation' r $ Local dotgit Nothing
|
||||
, updateLocation' r $ Local d Nothing
|
||||
)
|
||||
Just False -> mknonbare
|
||||
{- core.bare not in config, probably because safe.directory
|
||||
- did not allow reading the config -}
|
||||
Nothing -> ifM (Git.Construct.isBareRepo (fromRawFilePath d))
|
||||
Nothing -> ifM (Git.Construct.isBareRepo d)
|
||||
( mkbare
|
||||
, mknonbare
|
||||
)
|
||||
where
|
||||
dotgit = d P.</> ".git"
|
||||
dotgit = d </> literalOsPath ".git"
|
||||
-- git treats eg ~/foo as a bare git repository located in
|
||||
-- ~/foo/.git if ~/foo/.git/config has core.bare=true
|
||||
mkbare = ifM (doesDirectoryExist (fromRawFilePath dotgit))
|
||||
mkbare = ifM (doesDirectoryExist dotgit)
|
||||
( updateLocation' r $ Local dotgit Nothing
|
||||
, updateLocation' r $ Local d Nothing
|
||||
)
|
||||
|
|
|
@ -176,43 +176,43 @@ fromRemoteLocation s knownurl repo = gen $ parseRemoteLocation s knownurl repo
|
|||
fromRemotePath :: FilePath -> Repo -> IO Repo
|
||||
fromRemotePath dir repo = do
|
||||
dir' <- expandTilde dir
|
||||
fromPath $ repoPath repo P.</> toRawFilePath dir'
|
||||
fromPath $ repoPath repo P.</> dir'
|
||||
|
||||
{- Git remotes can have a directory that is specified relative
|
||||
- to the user's home directory, or that contains tilde expansions.
|
||||
- This converts such a directory to an absolute path.
|
||||
- Note that it has to run on the system where the remote is.
|
||||
-}
|
||||
repoAbsPath :: RawFilePath -> IO RawFilePath
|
||||
repoAbsPath :: OsPath -> IO OsPath
|
||||
repoAbsPath d = do
|
||||
d' <- expandTilde (fromRawFilePath d)
|
||||
d' <- expandTilde (fromOsPath d)
|
||||
h <- myHomeDir
|
||||
return $ toRawFilePath $ h </> d'
|
||||
return $ toOsPath h </> d'
|
||||
|
||||
expandTilde :: FilePath -> IO FilePath
|
||||
expandTilde :: FilePath -> IO OsPath
|
||||
#ifdef mingw32_HOST_OS
|
||||
expandTilde = return
|
||||
expandTilde = return . toOsPath
|
||||
#else
|
||||
expandTilde p = expandt True p
|
||||
-- If unable to expand a tilde, eg due to a user not existing,
|
||||
-- use the path as given.
|
||||
`catchNonAsync` (const (return p))
|
||||
`catchNonAsync` (const (return (toOsPath p)))
|
||||
where
|
||||
expandt _ [] = return ""
|
||||
expandt _ [] = return $ literalOsPath ""
|
||||
expandt _ ('/':cs) = do
|
||||
v <- expandt True cs
|
||||
return ('/':v)
|
||||
return $ literalOsPath "/" <> v
|
||||
expandt True ('~':'/':cs) = do
|
||||
h <- myHomeDir
|
||||
return $ h </> cs
|
||||
expandt True "~" = myHomeDir
|
||||
return $ toOsPath h </> toOsPath cs
|
||||
expandt True "~" = toOsPath <$> myHomeDir
|
||||
expandt True ('~':cs) = do
|
||||
let (name, rest) = findname "" cs
|
||||
u <- getUserEntryForName name
|
||||
return $ homeDirectory u </> rest
|
||||
return $ toOsPath (homeDirectory u) </> toOsPath rest
|
||||
expandt _ (c:cs) = do
|
||||
v <- expandt False cs
|
||||
return (c:v)
|
||||
return $ toOsPath [c] <> v
|
||||
findname n [] = (n, "")
|
||||
findname n (c:cs)
|
||||
| c == '/' = (n, cs)
|
||||
|
@ -221,11 +221,11 @@ expandTilde p = expandt True p
|
|||
|
||||
{- Checks if a git repository exists in a directory. Does not find
|
||||
- git repositories in parent directories. -}
|
||||
checkForRepo :: RawFilePath -> IO (Maybe RepoLocation)
|
||||
checkForRepo :: OsPath -> IO (Maybe RepoLocation)
|
||||
checkForRepo dir =
|
||||
check isRepo $
|
||||
check (checkGitDirFile dir) $
|
||||
check (checkdir (isBareRepo dir')) $
|
||||
check (checkdir (isBareRepo dir)) $
|
||||
return Nothing
|
||||
where
|
||||
check test cont = maybe cont (return . Just) =<< test
|
||||
|
@ -234,23 +234,22 @@ checkForRepo dir =
|
|||
, return Nothing
|
||||
)
|
||||
isRepo = checkdir $
|
||||
doesFileExist (dir' </> ".git" </> "config")
|
||||
doesFileExist (dir </> literalOsPath ".git" </> literalOsPath "config")
|
||||
<||>
|
||||
-- A git-worktree lacks .git/config, but has .git/gitdir.
|
||||
-- (Normally the .git is a file, not a symlink, but it can
|
||||
-- be converted to a symlink and git will still work;
|
||||
-- this handles that case.)
|
||||
doesFileExist (dir' </> ".git" </> "gitdir")
|
||||
dir' = fromRawFilePath dir
|
||||
doesFileExist (dir </> literalOsPath ".git" </> literalOsPath "gitdir")
|
||||
|
||||
isBareRepo :: FilePath -> IO Bool
|
||||
isBareRepo dir = doesFileExist (dir </> "config")
|
||||
<&&> doesDirectoryExist (dir </> "objects")
|
||||
isBareRepo :: OsPath -> IO Bool
|
||||
isBareRepo dir = doesFileExist (dir </> literalOsPath "config")
|
||||
<&&> doesDirectoryExist (dir </> literalOsPath "objects")
|
||||
|
||||
-- Check for a .git file.
|
||||
checkGitDirFile :: RawFilePath -> IO (Maybe RepoLocation)
|
||||
checkGitDirFile :: OsPath -> IO (Maybe RepoLocation)
|
||||
checkGitDirFile dir = adjustGitDirFile' $ Local
|
||||
{ gitdir = dir P.</> ".git"
|
||||
{ gitdir = dir </> literalOsPath ".git"
|
||||
, worktree = Just dir
|
||||
}
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ get = do
|
|||
Just d -> do
|
||||
curr <- R.getCurrentDirectory
|
||||
unless (d `dirContains` curr) $
|
||||
setCurrentDirectory (fromRawFilePath d)
|
||||
setCurrentDirectory d
|
||||
relPath $ addworktree wt r
|
||||
where
|
||||
getpathenv s = do
|
||||
|
|
|
@ -32,13 +32,11 @@ import Common
|
|||
import Git
|
||||
import Git.Quote
|
||||
|
||||
import qualified System.FilePath.ByteString as P
|
||||
import qualified System.FilePath.Posix.ByteString
|
||||
import GHC.Generics
|
||||
import Control.DeepSeq
|
||||
|
||||
{- A RawFilePath, relative to the top of the git repository. -}
|
||||
newtype TopFilePath = TopFilePath { getTopFilePath :: RawFilePath }
|
||||
{- A path relative to the top of the git repository. -}
|
||||
newtype TopFilePath = TopFilePath { getTopFilePath :: OsPath }
|
||||
deriving (Show, Eq, Ord, Generic)
|
||||
|
||||
instance NFData TopFilePath
|
||||
|
@ -53,16 +51,16 @@ descBranchFilePath (BranchFilePath b f) =
|
|||
UnquotedByteString (fromRef' b) <> ":" <> QuotedPath (getTopFilePath f)
|
||||
|
||||
{- Path to a TopFilePath, within the provided git repo. -}
|
||||
fromTopFilePath :: TopFilePath -> Git.Repo -> RawFilePath
|
||||
fromTopFilePath p repo = P.combine (repoPath repo) (getTopFilePath p)
|
||||
fromTopFilePath :: TopFilePath -> Git.Repo -> OsPath
|
||||
fromTopFilePath p repo = combine (repoPath repo) (getTopFilePath p)
|
||||
|
||||
{- The input FilePath can be absolute, or relative to the CWD. -}
|
||||
toTopFilePath :: RawFilePath -> Git.Repo -> IO TopFilePath
|
||||
toTopFilePath :: OsPath -> Git.Repo -> IO TopFilePath
|
||||
toTopFilePath file repo = TopFilePath <$> relPathDirToFile (repoPath repo) file
|
||||
|
||||
{- The input RawFilePath must already be relative to the top of the git
|
||||
- repository -}
|
||||
asTopFilePath :: RawFilePath -> TopFilePath
|
||||
asTopFilePath :: OsPath -> TopFilePath
|
||||
asTopFilePath file = TopFilePath file
|
||||
|
||||
{- Git may use a different representation of a path when storing
|
||||
|
@ -72,25 +70,24 @@ asTopFilePath file = TopFilePath file
|
|||
- despite Windows using '\'.
|
||||
-
|
||||
-}
|
||||
type InternalGitPath = RawFilePath
|
||||
type InternalGitPath = OsPath
|
||||
|
||||
toInternalGitPath :: RawFilePath -> InternalGitPath
|
||||
toInternalGitPath :: OsPath -> InternalGitPath
|
||||
#ifndef mingw32_HOST_OS
|
||||
toInternalGitPath = id
|
||||
#else
|
||||
toInternalGitPath = encodeBS . replace "\\" "/" . decodeBS
|
||||
toInternalGitPath = toOsPath . encodeBS . replace "\\" "/" . decodeBS . fromOsPath
|
||||
#endif
|
||||
|
||||
fromInternalGitPath :: InternalGitPath -> RawFilePath
|
||||
fromInternalGitPath :: InternalGitPath -> OsPath
|
||||
#ifndef mingw32_HOST_OS
|
||||
fromInternalGitPath = id
|
||||
#else
|
||||
fromInternalGitPath = encodeBS . replace "/" "\\" . decodeBS
|
||||
fromInternalGitPath = toOsPath . encodeBS . replace "/" "\\" . decodeBS . fromOsPath
|
||||
#endif
|
||||
|
||||
{- isAbsolute on Windows does not think "/foo" or "\foo" is absolute,
|
||||
- so try posix paths.
|
||||
-}
|
||||
absoluteGitPath :: RawFilePath -> Bool
|
||||
absoluteGitPath p = P.isAbsolute p ||
|
||||
System.FilePath.Posix.ByteString.isAbsolute (toInternalGitPath p)
|
||||
absoluteGitPath p = isAbsolute p || isAbsolute (toInternalGitPath p)
|
||||
|
|
|
@ -83,7 +83,7 @@ instance HashableBlob Builder where
|
|||
{- Injects a blob into git. Unfortunately, the current git-hash-object
|
||||
- interface does not allow batch hashing without using temp files. -}
|
||||
hashBlob :: HashableBlob b => HashObjectHandle -> b -> IO Sha
|
||||
hashBlob h b = withTmpFile (toOsPath "hash") $ \tmp tmph -> do
|
||||
hashBlob h b = withTmpFile (literalOsPath "hash") $ \tmp tmph -> do
|
||||
hashableBlobToHandle tmph b
|
||||
hClose tmph
|
||||
hashFile h (fromOsPath tmp)
|
||||
|
|
|
@ -50,7 +50,7 @@ hookFile h r = localGitDir r P.</> "hooks" P.</> hookName h
|
|||
- is run with a bundled bash, so should start with #!/bin/sh
|
||||
-}
|
||||
hookWrite :: Hook -> Repo -> IO Bool
|
||||
hookWrite h r = ifM (doesFileExist (fromRawFilePath f))
|
||||
hookWrite h r = ifM (doesFileExist f)
|
||||
( expectedContent h r >>= \case
|
||||
UnexpectedContent -> return False
|
||||
ExpectedContent -> return True
|
||||
|
@ -81,7 +81,7 @@ hookUnWrite h r = ifM (doesFileExist f)
|
|||
, return True
|
||||
)
|
||||
where
|
||||
f = fromRawFilePath $ hookFile h r
|
||||
f = hookFile h r
|
||||
|
||||
data ExpectedContent = UnexpectedContent | ExpectedContent | OldExpectedContent
|
||||
|
||||
|
|
|
@ -113,8 +113,8 @@ exists ref = runBool
|
|||
|
||||
{- The file used to record a ref. (Git also stores some refs in a
|
||||
- packed-refs file.) -}
|
||||
file :: Ref -> Repo -> FilePath
|
||||
file ref repo = fromRawFilePath (localGitDir repo) </> fromRef ref
|
||||
file :: Ref -> Repo -> OsPath
|
||||
file ref repo = localGitDir repo </> toOsPath (fromRef' ref)
|
||||
|
||||
{- Checks if HEAD exists. It generally will, except for in a repository
|
||||
- that was just created. -}
|
||||
|
|
|
@ -137,7 +137,7 @@ mkTreeOutput fm ot s f = concat
|
|||
, " "
|
||||
, fromRef s
|
||||
, "\t"
|
||||
, takeFileName (fromRawFilePath (getTopFilePath f))
|
||||
, fromOsPath (takeFileName (getTopFilePath f))
|
||||
, "\NUL"
|
||||
]
|
||||
|
||||
|
|
10
Git/Types.hs
10
Git/Types.hs
|
@ -9,6 +9,10 @@
|
|||
|
||||
module Git.Types where
|
||||
|
||||
import Utility.SafeCommand
|
||||
import Utility.FileSystemEncoding
|
||||
import Utility.OsPath
|
||||
|
||||
import Network.URI
|
||||
import Data.String
|
||||
import Data.Default
|
||||
|
@ -16,8 +20,6 @@ import qualified Data.Map as M
|
|||
import qualified Data.ByteString as S
|
||||
import qualified Data.List.NonEmpty as NE
|
||||
import System.Posix.Types
|
||||
import Utility.SafeCommand
|
||||
import Utility.FileSystemEncoding
|
||||
import qualified Data.Semigroup as Sem
|
||||
import Prelude
|
||||
|
||||
|
@ -32,8 +34,8 @@ import Prelude
|
|||
- else known about it.
|
||||
-}
|
||||
data RepoLocation
|
||||
= Local { gitdir :: RawFilePath, worktree :: Maybe RawFilePath }
|
||||
| LocalUnknown RawFilePath
|
||||
= Local { gitdir :: OsPath, worktree :: Maybe OsPath }
|
||||
| LocalUnknown OsPath
|
||||
| Url URI
|
||||
| UnparseableUrl String
|
||||
| Unknown
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue