diff --git a/Annex.hs b/Annex.hs index dc3466e3ee..02d4fa0354 100644 --- a/Annex.hs +++ b/Annex.hs @@ -247,7 +247,7 @@ newState c r = do - any necessary git repo fixups. -} new :: Git.Repo -> IO AnnexState new r = do - r' <- Git.Config.read =<< Git.relPath r + r' <- Git.Config.read r let c = extractGitConfig FromGitConfig r' newState c =<< fixupRepo r' c diff --git a/CHANGELOG b/CHANGELOG index 09043473f9..2667075cc2 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -20,6 +20,8 @@ git-annex (8.20210128) UNRELEASED; urgency=medium transfer progress consistently enough. * When annex.stalldetection is not enabled and a likely stall is detected, display a suggestion to enable it. + * When a git remote is configured with an absolute path, use that + path, rather than making it relative. -- Joey Hess Thu, 28 Jan 2021 12:34:32 -0400 diff --git a/Command/Map.hs b/Command/Map.hs index 4f34190011..7af7db08c0 100644 --- a/Command/Map.hs +++ b/Command/Map.hs @@ -178,7 +178,7 @@ absRepo reference r | Git.repoIsUrl reference = return $ Git.Construct.localToUrl reference r | Git.repoIsUrl r = return r | otherwise = liftIO $ do - r' <- Git.Construct.fromAbsPath =<< absPath (Git.repoPath r) + r' <- Git.Construct.fromPath =<< absPath (Git.repoPath r) r'' <- safely $ flip Annex.eval Annex.gitRepo =<< Annex.new r' return (fromMaybe r' r'') diff --git a/Git/Construct.hs b/Git/Construct.hs index de896bbe59..af7bb0557b 100644 --- a/Git/Construct.hs +++ b/Git/Construct.hs @@ -57,35 +57,34 @@ fromCwd = getCurrentDirectory >>= seekUp {- Local Repo constructor, accepts a relative or absolute path. -} fromPath :: RawFilePath -> IO Repo -fromPath dir = fromAbsPath =<< absPath dir +fromPath dir + -- When dir == "foo/.git", git looks for "foo/.git/.git", + -- and failing that, uses "foo" as the repository. + | (P.pathSeparator `B.cons` ".git") `B.isSuffixOf` canondir = + ifM (doesDirectoryExist $ fromRawFilePath dir ".git") + ( ret dir + , ret (P.takeDirectory canondir) + ) + | otherwise = ifM (doesDirectoryExist (fromRawFilePath dir)) + ( checkGitDirFile dir >>= maybe (ret dir) (pure . newFrom) + -- git falls back to dir.git when dir doesn't + -- exist, as long as dir didn't end with a + -- path separator + , if dir == canondir + then ret (dir <> ".git") + else ret dir + ) + where + ret = pure . newFrom . LocalUnknown + canondir = P.dropTrailingPathSeparator dir {- Local Repo constructor, requires an absolute path to the repo be - specified. -} fromAbsPath :: RawFilePath -> IO Repo fromAbsPath dir - | absoluteGitPath dir = hunt + | absoluteGitPath dir = fromPath dir | otherwise = error $ "internal error, " ++ show dir ++ " is not absolute" - where - ret = pure . newFrom . LocalUnknown - canondir = P.dropTrailingPathSeparator dir - {- When dir == "foo/.git", git looks for "foo/.git/.git", - - and failing that, uses "foo" as the repository. -} - hunt - | (P.pathSeparator `B.cons` ".git") `B.isSuffixOf` canondir = - ifM (doesDirectoryExist $ fromRawFilePath dir ".git") - ( ret dir - , ret (P.takeDirectory canondir) - ) - | otherwise = ifM (doesDirectoryExist (fromRawFilePath dir)) - ( checkGitDirFile dir >>= maybe (ret dir) (pure . newFrom) - -- git falls back to dir.git when dir doesn't - -- exist, as long as dir didn't end with a - -- path separator - , if dir == canondir - then ret (dir <> ".git") - else ret dir - ) {- Construct a Repo for a remote's url. - diff --git a/Git/CurrentRepo.hs b/Git/CurrentRepo.hs index 25bdc5c635..9261eabca1 100644 --- a/Git/CurrentRepo.hs +++ b/Git/CurrentRepo.hs @@ -10,6 +10,7 @@ module Git.CurrentRepo where import Common +import Git import Git.Types import Git.Construct import qualified Git.Config @@ -46,12 +47,12 @@ get = do wt <- maybe (worktree (location r)) Just <$> getpathenvprefix "GIT_WORK_TREE" prefix case wt of - Nothing -> return r + Nothing -> relPath r Just d -> do curr <- R.getCurrentDirectory unless (d `dirContains` curr) $ setCurrentDirectory (fromRawFilePath d) - return $ addworktree wt r + relPath $ addworktree wt r where getpathenv s = do v <- getEnv s diff --git a/Git/Repair.hs b/Git/Repair.hs index 034d7e98dc..6d9aeec992 100644 --- a/Git/Repair.hs +++ b/Git/Repair.hs @@ -105,7 +105,7 @@ retrieveMissingObjects missing referencerepo r | otherwise = withTmpDir "tmprepo" $ \tmpdir -> do unlessM (boolSystem "git" [Param "init", File tmpdir]) $ error $ "failed to create temp repository in " ++ tmpdir - tmpr <- Config.read =<< Construct.fromAbsPath (toRawFilePath tmpdir) + tmpr <- Config.read =<< Construct.fromPath (toRawFilePath tmpdir) rs <- Construct.fromRemotes r stillmissing <- pullremotes tmpr rs fetchrefstags missing if S.null (knownMissing stillmissing) diff --git a/Remote/Bup.hs b/Remote/Bup.hs index 6ba638a2df..2da6642d26 100644 --- a/Remote/Bup.hs +++ b/Remote/Bup.hs @@ -287,11 +287,11 @@ bup2GitRemote :: BupRepo -> IO Git.Repo bup2GitRemote "" = do -- bup -r "" operates on ~/.bup h <- myHomeDir - Git.Construct.fromAbsPath $ toRawFilePath $ h ".bup" + Git.Construct.fromPath $ toRawFilePath $ h ".bup" bup2GitRemote r | bupLocal r = if "/" `isPrefixOf` r - then Git.Construct.fromAbsPath (toRawFilePath r) + then Git.Construct.fromPath (toRawFilePath r) else giveup "please specify an absolute path" | otherwise = Git.Construct.fromUrl $ "ssh://" ++ host ++ slash dir where diff --git a/doc/bugs/git-annex_get__58___createDirectory__58___does_not_exist.mdwn b/doc/bugs/git-annex_get__58___createDirectory__58___does_not_exist.mdwn index 0b64b968e6..4235bf3998 100644 --- a/doc/bugs/git-annex_get__58___createDirectory__58___does_not_exist.mdwn +++ b/doc/bugs/git-annex_get__58___createDirectory__58___does_not_exist.mdwn @@ -29,3 +29,7 @@ git-annex is critical infrastructure for me. There is no day without it. Thx muc [[!tag projects/datalad]] + +> So there's an OSX bug here, and git-annex has been made to use +> an absolute path to a remote when it has one, which can be used to work +> around the OSX bug. [[done]] --[[Joey]] diff --git a/doc/bugs/git-annex_get__58___createDirectory__58___does_not_exist/comment_7_2899ef72aa2a5488eb945d14f7a2d76e._comment b/doc/bugs/git-annex_get__58___createDirectory__58___does_not_exist/comment_7_2899ef72aa2a5488eb945d14f7a2d76e._comment new file mode 100644 index 0000000000..fc367bb9c9 --- /dev/null +++ b/doc/bugs/git-annex_get__58___createDirectory__58___does_not_exist/comment_7_2899ef72aa2a5488eb945d14f7a2d76e._comment @@ -0,0 +1,18 @@ +[[!comment format=mdwn + username="joey" + subject="""comment 7""" + date="2021-02-08T15:54:58Z" + content=""" +Agreed, what you show in the stackoverflow post can only be an OSX bug. + +Using a relative path for the current repository does avoid using long +absolute paths, and also has a minor benefit of letting the repository be +moved while git-annex is running and it still accessing the right files. + +Neither benefit applies to the paths to remotes. I think the only +reason relative paths are being used for them is that the same code +is used to operate on them as on the local repository. + +I've made some changes that will make it use absolute paths when the +remote has an absolute path. +"""]]