summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWerner Almesberger <werner@almesberger.net>2016-11-29 12:04:01 (GMT)
committerWerner Almesberger <werner@almesberger.net>2016-11-29 12:04:01 (GMT)
commitab36df7fdf40719528f363d8179c7a0531b3480d (patch)
treeff9ef9b044f40576fc7049a74dcd05e7d4ed4a79
parent025d5951aabf6c69109c15ca3a13808820c57125 (diff)
downloadeeshow-try.zip
eeshow-try.tar.gz
eeshow-try.tar.bz2
file/git-util.c (git_repository_open_ext): use directories instead of reg. filestry
Reported by Alvaro Gamez Machado.
-rw-r--r--file/git-util.c49
1 files changed, 47 insertions, 2 deletions
diff --git a/file/git-util.c b/file/git-util.c
index aeeb65f..a1e4dbf 100644
--- a/file/git-util.c
+++ b/file/git-util.c
@@ -12,11 +12,16 @@
#include <stddef.h>
#include <stdbool.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
#include <assert.h>
#include <git2.h>
#include "misc/util.h"
+#include "misc/diag.h"
#include "file/git-util.h"
@@ -67,8 +72,8 @@ bool git_repo_is_dirty(git_repository *repo)
}
-int git_repository_open_ext_caching(git_repository **out, const char *path,
- unsigned int flags, const char *ceiling_dirs)
+static int do_git_repository_open_ext_caching(git_repository **out,
+ const char *path, unsigned int flags, const char *ceiling_dirs)
{
#if LIBGIT2_VER_MAJOR == 0 && LIBGIT2_VER_MINOR < 22
static struct repo_cache {
@@ -100,6 +105,46 @@ int git_repository_open_ext_caching(git_repository **out, const char *path,
#endif
}
+
+/*
+ * In some versions of libgit2 (apparently this can happen with Debian sid's
+ * 0.24), git_repository_open_ext interprets any regular file it is passed as
+ * "gitlink". This may be fixed in 0.25:
+ * https://github.com/libgit2/libgit2/commit/0f316096115513b5a07eb4df3883ba45ada28a07
+ *
+ * Since we depend heavily on git_repository_open_ext_caching being able to
+ * look up repositories when given a regular file, we detect this situation and
+ * use the corresponding directory instead.
+ */
+
+int git_repository_open_ext_caching(git_repository **out, const char *path,
+ unsigned int flags, const char *ceiling_dirs)
+{
+ struct stat st;
+ char *tmp, *slash;
+ int res;
+
+ if (stat(path, &st) == 0 && !S_ISREG(st.st_mode))
+ return do_git_repository_open_ext_caching(out, path, flags,
+ ceiling_dirs);
+ if (!*path) /* just in case this somehow makes sense */
+ return do_git_repository_open_ext_caching(out, ".", flags,
+ ceiling_dirs);
+
+ tmp = realpath(path, NULL);
+ if (!tmp)
+ diag_pfatal(path);
+ slash = strrchr(tmp, '/');
+ if (slash)
+ slash = 0;
+ else
+ strcpy(tmp, ".");
+ res = do_git_repository_open_ext_caching(out, ".", flags, ceiling_dirs);
+ free(tmp);
+ return res;
+}
+
+
/*
* Git documentation says that git_libgit2_init can be called more then once
* but doesn't quite what happens then, e.g., whether references obtained