aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Joey Hess <joey@kitenet.net>2010-11-28 17:17:18 -0400
committerGravatar Joey Hess <joey@kitenet.net>2010-11-28 17:17:18 -0400
commitabf084f628a8c5f5a3685dbb2826739e3e38541e (patch)
tree1b24036e91aef3a2c046af809f49250bd060f939
parent52ec6e748d5ef8350e9788d0f19dc5c3d609ab86 (diff)
Bugfix: Always correctly handle gitattributes when in a subdirectory of the repository.
-rw-r--r--GitRepo.hs26
-rw-r--r--Utility.hs20
-rw-r--r--debian/changelog2
3 files changed, 31 insertions, 17 deletions
diff --git a/GitRepo.hs b/GitRepo.hs
index f50b3fb2e..539acecb7 100644
--- a/GitRepo.hs
+++ b/GitRepo.hs
@@ -171,15 +171,17 @@ workTree (Repo { location = Dir d }) = d
{- Given a relative or absolute filename in a repository, calculates the
- name to use to refer to the file relative to a git repository's top.
- This is the same form displayed and used by git. -}
-relative :: Repo -> String -> String
-relative repo@(Repo { location = Dir d }) file = drop (length absrepo) absfile
+relative :: Repo -> FilePath -> IO FilePath
+relative repo@(Repo { location = Dir d }) file = do
+ cwd <- getCurrentDirectory
+ return $ drop (length absrepo) (absfile cwd)
where
-- normalize both repo and file, so that repo
-- will be substring of file
absrepo = case (absNormPath "/" d) of
Just f -> f ++ "/"
Nothing -> error $ "bad repo" ++ repoDescribe repo
- absfile = case (secureAbsNormPath absrepo file) of
+ absfile c = case (secureAbsNormPath c file) of
Just f -> f
Nothing -> error $ file ++ " is not located inside git repository " ++ absrepo
relative repo _ = assertLocal repo $ error "internal"
@@ -333,18 +335,26 @@ configGet repo key defaultValue =
configMap :: Repo -> Map.Map String String
configMap repo = config repo
-{- Looks up a gitattributes value for each file in a list. -}
+{- Efficiently looks up a gitattributes value for each file in a list. -}
checkAttr :: Repo -> String -> [FilePath] -> IO [(FilePath, String)]
checkAttr repo attr files = do
- (_, s) <- pipeBoth "git" params files0
- return $ map topair $ lines s
+ -- git check-attr wants files that are absolute (or relative to the
+ -- top of the repo). But we're passed files relative to the current
+ -- directory. Convert to absolute, and then convert the filenames
+ -- in its output back to relative.
+ absfiles <- mapM absPath files
+ (_, s) <- pipeBoth "git" params $ join "\0" absfiles
+ cwd <- getCurrentDirectory
+ return $ map (topair $ cwd++"/") $ lines s
-- XXX handle is left open, this is ok for git-annex, but may need
-- to be cleaned up for other uses.
where
params = gitCommandLine repo ["check-attr", attr, "-z", "--stdin"]
- files0 = join "\0" files
- topair l = (file, value)
+ topair cwd l = (relfile, value)
where
+ relfile
+ | startswith cwd file = drop (length cwd) file
+ | otherwise = file
file = decodeGitFile $ join sep $ take end bits
value = bits !! end
end = length bits - 1
diff --git a/Utility.hs b/Utility.hs
index 882492a2d..0f7ce42aa 100644
--- a/Utility.hs
+++ b/Utility.hs
@@ -8,6 +8,7 @@
module Utility (
hGetContentsStrict,
parentDir,
+ absPath,
relPathCwdToDir,
relPathDirToDir,
boolSystem,
@@ -44,24 +45,25 @@ parentDir dir =
slash = if isAbsolute dir then s else ""
s = [pathSeparator]
+{- Converts a filename into a normalized, absolute path. -}
+absPath :: FilePath -> IO FilePath
+absPath file = do
+ cwd <- getCurrentDirectory
+ case absNormPath cwd file of
+ Just f -> return f
+ Nothing -> error $ "unable to normalize " ++ file
+
{- Constructs a relative path from the CWD to a directory.
-
- For example, assuming CWD is /tmp/foo/bar:
- relPathCwdToDir "/tmp/foo" == "../"
- relPathCwdToDir "/tmp/foo/bar" == ""
- - relPathCwdToDir "/tmp/foo/bar" == ""
-}
relPathCwdToDir :: FilePath -> IO FilePath
relPathCwdToDir dir = do
cwd <- getCurrentDirectory
- let absdir = absnorm cwd
- return $ relPathDirToDir cwd absdir
- where
- -- absolute, normalized form of the directory
- absnorm cwd =
- case absNormPath cwd dir of
- Just d -> d
- Nothing -> error $ "unable to normalize " ++ dir
+ a <- absPath dir
+ return $ relPathDirToDir cwd a
{- Constructs a relative path from one directory to another.
-
diff --git a/debian/changelog b/debian/changelog
index 213895c5f..34e1757df 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -3,6 +3,8 @@ git-annex (0.10) UNRELEASED; urgency=low
* precommit: Optimise to avoid calling git-check-attr more than once.
* In .gitattributes, the git-annex-numcopies attribute can be used
to control the number of copies to retain of different types of files.
+ * Bugfix: Always correctly handle gitattributes when in a subdirectory of
+ the repository.
-- Joey Hess <joeyh@debian.org> Sun, 28 Nov 2010 14:19:15 -0400