@@ -56,60 +56,63 @@ getDotGitPath fp = do
5656 else getDotGitPath dirName
5757
5858func :: String -> CString -> Pointers -> IO (Map FilePath Integer )
59- func require repoPath pointers = do
59+ func matchPrefix repoPath pointers = do
6060 c'git_repository_open (pointers ^. repoP) repoPath >>= errorCheck
6161 repo <- peek $ pointers ^. repoP
6262 c'git_repository_head (pointers ^. headP) repo >>= errorCheck
6363 headOid <- peek (pointers ^. headP) >>= c'git_reference_target
6464 c'git_commit_lookup (pointers ^. commitP) repo headOid >>= errorCheck
6565 headCommit <- peek (pointers ^. commitP)
6666 lineage <- unfoldCommits headCommit
67- maps <- mapM (makeEntryMap require) lineage
67+ let constructEntryMap' = constructEntrymap matchPrefix repo
68+ maps <- mapM (getRootAndTime >=> uncurry constructEntryMap') lineage
6869 c'git_repository_free repo
6970 return $ Map. unionsWith min maps
7071
72+ getRootAndTime :: Ptr C'git_commit -> IO (Ptr C'git_tree , Integer )
73+ getRootAndTime commit = do
74+ alloca $ \ rootP -> do
75+ c'git_commit_tree rootP commit >>= errorCheck
76+ root <- peek rootP
77+ time <- c'git_commit_time commit
78+ return (root, toInteger time)
79+
7180unfoldCommits :: Ptr C'git_commit -> IO [Ptr C'git_commit ]
7281unfoldCommits commit = alloca $ \ parentP -> do
7382 result <- c'git_commit_parent parentP commit 0
7483 if result == 0
7584 then peek parentP >>= unfoldCommits <&> (++ [commit])
7685 else return [commit]
7786
78- makeEntryMap'' :: String -> Ptr C'git_repository -> String -> Integer -> Ptr C'git_tree_entry -> IO (Map FilePath Integer )
79- makeEntryMap'' require repo prefix time entry = do
80- entryType <- c'git_tree_entry_type entry
81- name <- c'git_tree_entry_name entry >>= peekCString
82- if entryType == c'GIT_OBJ_TREE
83- then do
84- eoid <- c'git_tree_entry_id entry
85- alloca $ \ subTreeP -> do
86- c'git_tree_lookup subTreeP repo eoid >>= errorCheck
87- subTree <- peek subTreeP
88- let next = prefix ++ name ++ " /"
89- if next `isPrefixOf` require || require `isPrefixOf` next
90- then makeEntryMap' require (prefix ++ name ++ " /" ) time subTree
91- else return Map. empty
92- else do
93- if require `isPrefixOf` prefix
94- then do
95- let relPath = makeRelative require (prefix ++ name)
96- return $ Map. singleton relPath time
97- else return Map. empty
87+ constructEntrymap :: String -> Ptr C'git_repository -> Ptr C'git_tree -> Integer -> IO (Map FilePath Integer )
88+ constructEntrymap matchPrefix repo root time =
89+ let makeEntryMap'' :: String -> Ptr C'git_tree_entry -> IO (Map FilePath Integer )
90+ makeEntryMap'' parentDir entry = do
91+ entryType <- c'git_tree_entry_type entry
92+ name <- c'git_tree_entry_name entry >>= peekCString
93+ let next = parentDir ++ name ++ " /"
94+ if entryType == c'GIT_OBJ_TREE
95+ then do
96+ eoid <- c'git_tree_entry_id entry
97+ alloca $ \ subTreeP -> do
98+ c'git_tree_lookup subTreeP repo eoid >>= errorCheck
99+ subTree <- peek subTreeP
100+ if next `isPrefixOf` matchPrefix || matchPrefix `isPrefixOf` next
101+ then makeEntryMap' (parentDir ++ name ++ " /" ) subTree
102+ else return Map. empty
103+ else do
104+ if matchPrefix `isPrefixOf` parentDir
105+ then do
106+ let relPath = makeRelative matchPrefix (parentDir ++ name)
107+ return $ Map. singleton relPath time
108+ else return Map. empty
98109
99- makeEntryMap' :: String -> String -> Integer -> Ptr C'git_tree -> IO (Map FilePath Integer )
100- makeEntryMap' require prefix time tree = do
101- entryCountC <- c'git_tree_entrycount tree
102- let f = c'git_tree_entry_byindex tree
103- repo <- c'git_tree_owner tree
104- foldMap (f >=> makeEntryMap'' require repo prefix time) [0 .. (entryCountC - 1 )]
105-
106- makeEntryMap :: String -> Ptr C'git_commit -> IO (Map FilePath Integer )
107- makeEntryMap require commit = do
108- alloca $ \ treeP -> do
109- c'git_commit_tree treeP commit >>= errorCheck
110- tree <- peek treeP
111- time <- c'git_commit_time commit
112- makeEntryMap' require " " (toInteger time) tree
110+ makeEntryMap' :: String -> Ptr C'git_tree -> IO (Map FilePath Integer )
111+ makeEntryMap' parentDir tree = do
112+ entryCountC <- c'git_tree_entrycount tree
113+ let f = c'git_tree_entry_byindex tree
114+ foldMap (f >=> makeEntryMap'' parentDir) [0 .. (entryCountC - 1 )]
115+ in makeEntryMap' " " root
113116
114117errorCheck r = when (r /= 0 ) $ error " fail"
115118
0 commit comments