@@ -56,60 +56,63 @@ getDotGitPath fp = do
56
56
else getDotGitPath dirName
57
57
58
58
func :: String -> CString -> Pointers -> IO (Map FilePath Integer )
59
- func require repoPath pointers = do
59
+ func matchPrefix repoPath pointers = do
60
60
c'git_repository_open (pointers ^. repoP) repoPath >>= errorCheck
61
61
repo <- peek $ pointers ^. repoP
62
62
c'git_repository_head (pointers ^. headP) repo >>= errorCheck
63
63
headOid <- peek (pointers ^. headP) >>= c'git_reference_target
64
64
c'git_commit_lookup (pointers ^. commitP) repo headOid >>= errorCheck
65
65
headCommit <- peek (pointers ^. commitP)
66
66
lineage <- unfoldCommits headCommit
67
- maps <- mapM (makeEntryMap require) lineage
67
+ let constructEntryMap' = constructEntrymap matchPrefix repo
68
+ maps <- mapM (getRootAndTime >=> uncurry constructEntryMap') lineage
68
69
c'git_repository_free repo
69
70
return $ Map. unionsWith min maps
70
71
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
+
71
80
unfoldCommits :: Ptr C'git_commit -> IO [Ptr C'git_commit ]
72
81
unfoldCommits commit = alloca $ \ parentP -> do
73
82
result <- c'git_commit_parent parentP commit 0
74
83
if result == 0
75
84
then peek parentP >>= unfoldCommits <&> (++ [commit])
76
85
else return [commit]
77
86
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
98
109
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
113
116
114
117
errorCheck r = when (r /= 0 ) $ error " fail"
115
118
0 commit comments