Skip to content

Instantly share code, notes, and snippets.

@cholin
Created Apr 17, 2012
Embed
What would you like to do?
simple libgit2 tree walker (like tree cli tool)
#include <git2.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
int strocc(char* str, char c) {
int occ = 0, i = 0;
while(str[i] != '\0')
if(str[++i] == c)
++occ;
return occ;
}
int treewalk_cb(const char *dirname, git_tree_entry *entry, void *payload) {
int* count = (int*) payload;
char oid_str[8];
git_oid_tostr(oid_str, 8, git_tree_entry_id(entry));
char path[128];
sprintf(path, "%s%s", dirname, git_tree_entry_name(entry));
path[128] = '\0';
int intend = strocc(path, '/');
if(intend > 0) {
int i;
char intend_str[intend*4];
for(i=0; i < intend*4;++i)
intend_str[i] = ' ';
intend_str[i] = '\0';
char delimiter[2] = " ";
if(count[0] < count[1])
delimiter[0] = '|';
printf("%s%s└─ %s %s\n", delimiter, intend_str, oid_str, path);
} else {
if(++count[0] < count[1])
printf("├─ %s %s\n", oid_str, path);
else
printf("└─ %s %s\n", oid_str, path);
}
}
int main(int argc, char** argv) {
git_repository* repo;
git_reference* head;
git_tree* tree;
git_commit* commit;
git_odb* odb;
char* path;
if(argc == 1) {
printf("Usage: %s path/to/git [commit-sha1]\n", argv[0]);
exit(-1);
}
path = argv[1];
git_repository_init(&repo, path, false);
if(argc > 2) {
git_oid oid;
printf("Commit %s\n\n", argv[2]);
git_oid_fromstr(&oid, argv[2]);
git_commit_lookup(&commit, repo, &oid);
} else {
git_oid* oid;
char oid_str[40];
git_oid_tostr(oid_str, 40, oid);
printf("Commit %s\n\n", oid_str);
git_repository_head(&head, repo);
git_commit_lookup(&commit, repo, git_reference_oid(head));
git_reference_free(head);
}
git_commit_tree(&tree, commit);
int mode = GIT_TREEWALK_POST;
int count[] = { 0, git_tree_entrycount(tree)};
git_tree_walk(tree, &treewalk_cb, mode, (void*) &count);
git_repository_free(repo);
}
@cholin
Copy link
Author

cholin commented Apr 17, 2012

example

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment