summaryrefslogtreecommitdiffstats
path: root/XD.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--XD.c70
1 files changed, 62 insertions, 8 deletions
diff --git a/XD.c b/XD.c
index 20add73..c44fe3f 100644
--- a/XD.c
+++ b/XD.c
@@ -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;
}