10 static int proc_tree(git_repository *repo, git_tree *tree, const char *path);
12 static struct repofile *files;
13 static int num_files, max_files;
15 int repo_init(const char *path)
18 git_repository *repo = 0;
23 if(git_repository_open_ext(&repo, path, GIT_REPOSITORY_OPEN_NO_SEARCH, 0) != 0) {
24 fprintf(stderr, "repo_init: failed to open repository: %s: %s\n", path,
25 git_error_last()->message);
30 num_files = max_files = 0;
32 if(git_revparse_single((git_object**)&tree, repo, "HEAD^{tree}") != 0) {
33 fprintf(stderr, "repo_init: %s\n", git_error_last()->message);
36 if(proc_tree(repo, tree, 0) == -1) {
45 num_files = max_files = 0;
47 if(repo) git_repository_free(repo);
48 git_libgit2_shutdown();
52 void repo_cleanup(void)
56 num_files = max_files = 0;
59 int repo_num_files(void)
64 const char *repo_file(int idx)
66 if(idx < 0 || idx >= num_files) return 0;
67 return files[idx].path;
70 static int add_file(const char *name, const char *path)
72 struct repofile *file;
75 if(num_files >= max_files) {
76 int newmax = max_files ? max_files * 2 : 16;
77 void *newfiles = realloc(files, newmax * sizeof *files);
79 fprintf(stderr, "repo_init: failed to add file\n");
86 pathlen = strlen(name);
88 pathlen += strlen(path) + 1;
91 file = files + num_files;
92 if(!(file->path = malloc(pathlen + 1))) {
93 fprintf(stderr, "repo_init: failed to allocate file path buffer\n");
97 sprintf(file->path, "%s/%s", path, name);
99 strcpy(file->path, name);
106 static int proc_tree(git_repository *repo, git_tree *tree, const char *path)
108 int i, count = git_tree_entrycount(tree);
109 const git_tree_entry *ent;
114 for(i=0; i<count; i++) {
115 ent = git_tree_entry_byindex(tree, i);
116 type = git_tree_entry_type(ent);
117 name = git_tree_entry_name(ent);
120 case GIT_OBJECT_BLOB:
121 if(add_file(name, path) == -1) {
126 case GIT_OBJECT_TREE:
127 git_tree_entry_to_object(&obj, repo, ent);
129 char *pathbuf = malloc(strlen(path) + strlen(name) + 1);
131 fprintf(stderr, "repo_init: failed to allocate memory\n");
134 sprintf(pathbuf, "%s/%s", path, name);
135 proc_tree(repo, (git_tree*)obj, pathbuf);
138 proc_tree(repo, (git_tree*)obj, name);
140 git_object_free(obj);