Windows: Fix handling of absolute unix-style git repository paths.

Note that on Windows a remote with a path like /home/foo/bar
is interpreted by git as being some screwy relative path (relative to what
exactly seems ill-defined -- it seemed relative to C:\Program Files\Git\ in
my tests!) So no attempt has been made to handle such a path sanely, just not
to crash when encountering it.

Note that "C:\\foo" </> "/home/foo/bar" yields /home/foo/bar even though
that is not absolute! I don't know what to make of all this,
except that I will be very happy when this crock of **** vanishes from
the face of the earth.
This commit is contained in:
Joey Hess 2014-02-08 15:31:03 -04:00
parent f068f4e579
commit c95d0cf7a8
6 changed files with 28 additions and 5 deletions

View file

@ -9,6 +9,7 @@ module CmdLine.GitAnnexShell.Fields where
import Common.Annex import Common.Annex
import qualified Annex import qualified Annex
import Git.FilePath
import Data.Char import Data.Char
@ -29,7 +30,7 @@ remoteUUID = Field "remoteuuid" $
associatedFile :: Field associatedFile :: Field
associatedFile = Field "associatedfile" $ \f -> associatedFile = Field "associatedfile" $ \f ->
-- is the file a safe relative filename? -- is the file a safe relative filename?
not (isAbsolute f) && not ("../" `isPrefixOf` f) not (absoluteGitPath f) && not ("../" `isPrefixOf` f)
direct :: Field direct :: Field
direct = Field "direct" $ \f -> f == "1" direct = Field "direct" $ \f -> f == "1"

View file

@ -32,7 +32,7 @@ gitCommandLine params r@(Repo { location = l@(Local _ _ ) }) =
#ifdef mingw32_HOST_OS #ifdef mingw32_HOST_OS
-- despite running on windows, msysgit wants a unix-formatted path -- despite running on windows, msysgit wants a unix-formatted path
gitpath s gitpath s
| isAbsolute s = "/" ++ dropDrive (toInternalGitPath s) | absoluteGitPath s = "/" ++ dropDrive (toInternalGitPath s)
| otherwise = s | otherwise = s
#else #else
gitpath = id gitpath = id

View file

@ -33,6 +33,7 @@ import Common
import Git.Types import Git.Types
import Git import Git
import Git.Remote import Git.Remote
import Git.FilePath
import qualified Git.Url as Url import qualified Git.Url as Url
import Utility.UserInfo import Utility.UserInfo
@ -57,7 +58,7 @@ fromPath dir = fromAbsPath =<< absPath dir
- specified. -} - specified. -}
fromAbsPath :: FilePath -> IO Repo fromAbsPath :: FilePath -> IO Repo
fromAbsPath dir fromAbsPath dir
| isAbsolute dir = ifM (doesDirectoryExist dir') ( ret dir' , hunt ) | absoluteGitPath dir = ifM (doesDirectoryExist dir') ( ret dir' , hunt )
| otherwise = | otherwise =
error $ "internal error, " ++ dir ++ " is not absolute" error $ "internal error, " ++ dir ++ " is not absolute"
where where

View file

@ -20,12 +20,15 @@ module Git.FilePath (
asTopFilePath, asTopFilePath,
InternalGitPath, InternalGitPath,
toInternalGitPath, toInternalGitPath,
fromInternalGitPath fromInternalGitPath,
absoluteGitPath
) where ) where
import Common import Common
import Git import Git
import qualified System.FilePath.Posix
{- A FilePath, relative to the top of the git repository. -} {- A FilePath, relative to the top of the git repository. -}
newtype TopFilePath = TopFilePath { getTopFilePath :: FilePath } newtype TopFilePath = TopFilePath { getTopFilePath :: FilePath }
deriving (Show) deriving (Show)
@ -66,3 +69,10 @@ fromInternalGitPath = id
#else #else
fromInternalGitPath = replace "/" "\\" fromInternalGitPath = replace "/" "\\"
#endif #endif
{- isAbsolute on Windows does not think "/foo" or "\foo" is absolute,
- so try posix paths.
-}
absoluteGitPath :: FilePath -> Bool
absoluteGitPath p = isAbsolute p ||
System.FilePath.Posix.isAbsolute (toInternalGitPath p)

2
debian/changelog vendored
View file

@ -29,12 +29,14 @@ git-annex (5.20140128) UNRELEASED; urgency=medium
* Windows: Fix deletion of repositories by test suite and webapp. * Windows: Fix deletion of repositories by test suite and webapp.
* Windows: Test suite 100% passes again. * Windows: Test suite 100% passes again.
* Windows: Fix bug in symlink calculation code. * Windows: Fix bug in symlink calculation code.
* Windows: Fix handling of absolute unix-style git repository paths.
* Fix initremote with encryption=pubkey to work with S3, glacier, webdav, * Fix initremote with encryption=pubkey to work with S3, glacier, webdav,
and external special remotes. and external special remotes.
* Android: Avoid crashing when unable to set file mode for ssh config file * Android: Avoid crashing when unable to set file mode for ssh config file
due to Android filesystem horribleness. due to Android filesystem horribleness.
* Avoid building with DAV 0.6 which is badly broken (see #737902). * Avoid building with DAV 0.6 which is badly broken (see #737902).
* Fix build on platforms not supporting the webapp. * Fix build on platforms not supporting the webapp.
* Fix dropping of unused keys with spaces in their name.
-- Joey Hess <joeyh@debian.org> Tue, 28 Jan 2014 13:57:19 -0400 -- Joey Hess <joeyh@debian.org> Tue, 28 Jan 2014 13:57:19 -0400

View file

@ -6,9 +6,18 @@ internal error, /home/michele/assistannex is not absolute
### What steps will reproduce the problem? ### What steps will reproduce the problem?
create a transfer repository on a usb drive (from windows) merge it with a repository on linux, try to merge it on another target windows machine create a transfer repository on a usb drive (from windows) merge it with a
repository on linux, try to merge it on another target windows machine
### What version of git-annex are you using? On what operating system? ### What version of git-annex are you using? On what operating system?
git-annex version 5.20140128-g29aea74 git-annex version 5.20140128-g29aea74
> I'm not able to follow the steps to reproduce this, but I think
> I see what the problem is. `isAbsolute` on windows does not think that
> unix-style path is absolute. Such a path can appear in a remote of a git
> repository, particularly if part of that repository was set up on a
> non-Windows system. While the remote won't be usable on Windows with a
> path like that, git-annex should not choke on the path either.
> I have fixed the code to deal with this.
> [[done]] --[[Joey]]