summaryrefslogtreecommitdiff
path: root/Git
diff options
context:
space:
mode:
authorGravatar Joey Hess <joey@kitenet.net>2013-02-06 12:40:59 -0400
committerGravatar Joey Hess <joey@kitenet.net>2013-02-06 12:44:19 -0400
commit48d59dbad11a2f99a0003f5f3bd93734429be11d (patch)
treeef74a5cb149d78c8dc3e74732ae52f5afb73f274 /Git
parent6be68947dcf80c99ed5135c1a968641dca199555 (diff)
pre-commit: Update direct mode mappings.
Making the pre-commit hook look at git diff-index to find changed direct mode files and update the mappings works pretty well. One case where it does not work is when a file is git annex added, and then git rmed, and then this is committed. That's a no-op commit, so the hook probably doesn't even run, and it certianly never notices that the file was deleted, so the mapping will still have the original filename in it. For this and other reasons, it's important that the mappings still be treated as possibly inconsistent. Also, the assistant now allows the pre-commit hook to run when in direct mode, so the mappings also get updated there.
Diffstat (limited to 'Git')
-rw-r--r--Git/DiffTree.hs25
-rw-r--r--Git/Ref.hs7
2 files changed, 25 insertions, 7 deletions
diff --git a/Git/DiffTree.hs b/Git/DiffTree.hs
index af230b495..f122a4fb5 100644
--- a/Git/DiffTree.hs
+++ b/Git/DiffTree.hs
@@ -9,7 +9,7 @@ module Git.DiffTree (
DiffTreeItem(..),
diffTree,
diffTreeRecursive,
- parseDiffTree
+ diffIndex,
) where
import Numeric
@@ -20,6 +20,7 @@ import Git
import Git.Sha
import Git.Command
import qualified Git.Filename
+import qualified Git.Ref
data DiffTreeItem = DiffTreeItem
{ srcmode :: FileMode
@@ -32,19 +33,29 @@ data DiffTreeItem = DiffTreeItem
{- Diffs two tree Refs. -}
diffTree :: Ref -> Ref -> Repo -> IO ([DiffTreeItem], IO Bool)
-diffTree = diffTree' []
+diffTree src dst = getdiff (Param "diff-tree")
+ [Param (show src), Param (show dst)]
{- Diffs two tree Refs, recursing into sub-trees -}
diffTreeRecursive :: Ref -> Ref -> Repo -> IO ([DiffTreeItem], IO Bool)
-diffTreeRecursive = diffTree' [Param "-r"]
+diffTreeRecursive src dst = getdiff (Param "diff-tree")
+ [Param "-r", Param (show src), Param (show dst)]
-diffTree' :: [CommandParam] -> Ref -> Ref -> Repo -> IO ([DiffTreeItem], IO Bool)
-diffTree' params src dst repo = do
+{- Diffs between the repository and index. Does nothing if there is not
+ - yet a commit in the repository. -}
+diffIndex :: Repo -> IO ([DiffTreeItem], IO Bool)
+diffIndex repo = do
+ ifM (Git.Ref.headExists repo)
+ ( getdiff (Param "diff-index") [Param "--cached", Param "HEAD"] repo
+ , return ([], return True)
+ )
+
+getdiff :: CommandParam -> [CommandParam] -> Repo -> IO ([DiffTreeItem], IO Bool)
+getdiff command params repo = do
(diff, cleanup) <- pipeNullSplit ps repo
return (parseDiffTree diff, cleanup)
where
- ps = Params "diff-tree -z --raw --no-renames -l0" : params ++
- [Param (show src), Param (show dst)]
+ ps = command : Params "-z --raw --no-renames -l0" : params
{- Parses diff-tree output. -}
parseDiffTree :: [String] -> [DiffTreeItem]
diff --git a/Git/Ref.hs b/Git/Ref.hs
index 02adf0547..3f7613726 100644
--- a/Git/Ref.hs
+++ b/Git/Ref.hs
@@ -37,6 +37,13 @@ exists :: Ref -> Repo -> IO Bool
exists ref = runBool "show-ref"
[Param "--verify", Param "-q", Param $ show ref]
+{- Checks if HEAD exists. It generally will, except for in a repository
+ - that was just created. -}
+headExists :: Repo -> IO Bool
+headExists repo = do
+ ls <- lines <$> pipeReadStrict [Param "show-ref", Param "--head"] repo
+ return $ any (" HEAD" `isSuffixOf`) ls
+
{- Get the sha of a fully qualified git ref, if it exists. -}
sha :: Branch -> Repo -> IO (Maybe Sha)
sha branch repo = process <$> showref repo