diff options
Diffstat (limited to '')
-rw-r--r-- | XD.c | 70 |
1 files changed, 62 insertions, 8 deletions
@@ -6,6 +6,8 @@ #endif #ifdef GIT +#include <sys/stat.h> +#include <dirent.h> #include <git2.h> #endif @@ -35,6 +37,45 @@ l(const char *fmt, ...) #ifdef GIT /** + * @brief search all parent directories for a git repo + * + * @return absolute path to git repo + */ +char +*find_git_repo() +{ + char path[PATH_MAX] = ".", *rpath; + struct stat s; + int i, c; + + + /* find the number of jumps to the root of the fs */ + rpath = realpath(path, NULL); + for (i = c = 0; i < strlen(rpath); i++) { + if (rpath[i] == '/') { + c++; + } + } + free(rpath); + + /* start searching */ + for (i = c; i > 0; i--) { + strcat(path, "/.git"); + + /* if there seems to be a git directory return the directory it was found in */ + if (stat(path, &s) == 0 && S_ISDIR(s.st_mode)) { + return realpath(path, NULL); + } + + /* reset contents of gpath, and go up a directory */ + memset(&path[strlen(path) - 4], '.', 2); + memset(&path[strlen(path) - 2], 0, 2); + } + + return NULL; +} + +/** * @brief open git repo if one is available at the current path * * @return a pointer to the git repo object @@ -42,27 +83,40 @@ l(const char *fmt, ...) git_repository *init_git() { - git_buf buf = GIT_BUF_INIT_CONST(NULL, 0); + char *buf; git_repository *repo; - if (git_libgit2_init() < 0) { - L("Failed to initalize libgit2, proceeding without git functionality enabled."); + /* check for a repo before loading libgit2 */ + if ((buf = find_git_repo()) == NULL) { return NULL; } - if (git_repository_discover(&buf, ".", 0, NULL) < 0) { - L("Failed to discover git repo: %s", git_error_last()->message); + /* disable a bunch of git options to hopefully speed things up */ + git_libgit2_opts(GIT_OPT_ENABLE_CACHING, 0); + git_libgit2_opts(GIT_OPT_SET_MWINDOW_SIZE, 0); + git_libgit2_opts(GIT_OPT_SET_MWINDOW_MAPPED_LIMIT, 0); + + git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, ""); + git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_XDG, ""); + git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_SYSTEM, ""); + git_libgit2_opts(GIT_OPT_SET_TEMPLATE_PATH, ""); + + git_libgit2_opts(GIT_OPT_DISABLE_PACK_KEEP_FILE_CHECKS, 1); + + /* initialize the git library and repository */ + if (git_libgit2_init() < 0) { + L("Failed to initalize libgit2, proceeding without git functionality enabled."); return NULL; } - if (git_repository_open(&repo, buf.ptr) < 0) { + if (git_repository_open(&repo, buf) < 0) { L("Failed to open git repo: %s", git_error_last()->message); - git_buf_dispose(&buf); + free(buf); return NULL; } /* get rid of object containing git repo path and return the repo */ - git_buf_dispose(&buf); + free(buf); return repo; } |