setup: introduce the discover_git_directory() function
We modified the setup_git_directory_gently_1() function earlier to make it possible to discover the GIT_DIR without changing global state. However, it is still a bit cumbersome to use if you only need to figure out the (possibly absolute) path of the .git/ directory. Let's just provide a convenient wrapper function with an easier signature that *just* discovers the .git/ directory. We will use it in a subsequent patch to fix the early config. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Johannes Schindelin committed
Mar 13, 2017 at 21:10 UTC
16ac8b8db6ec7400719db6b5c76edaab33c47606
2 files changed
+50
cache.h
+7
@@ -518,6 +518,13 @@ extern void set_git_work_tree(const char *tree);
518
#define ALTERNATE_DB_ENVIRONMENT "GIT_ALTERNATE_OBJECT_DIRECTORIES"
519
520
extern void setup_work_tree(void);
521
+/*
522
+ * Find GIT_DIR of the repository that contains the current working directory,
523
+ * without changing the working directory or other global state. The result is
524
+ * appended to gitdir. The return value is either NULL if no repository was
525
+ * found, or pointing to the path inside gitdir's buffer.
526
+ */
527
+extern const char *discover_git_directory(struct strbuf *gitdir);
528
extern const char *setup_git_directory_gently(int *);
529
extern const char *setup_git_directory(void);
530
extern char *prefix_path(const char *prefix, int len, const char *path);
setup.c
+43
@@ -924,6 +924,49 @@ static enum discovery_result setup_git_directory_gently_1(struct strbuf *dir,
924
}
925
}
926
927
+const char *discover_git_directory(struct strbuf *gitdir)
928
+{
929
+ struct strbuf dir = STRBUF_INIT, err = STRBUF_INIT;
930
+ size_t gitdir_offset = gitdir->len, cwd_len;
931
+ struct repository_format candidate;
932
+
933
+ if (strbuf_getcwd(&dir))
934
+ return NULL;
935
+
936
+ cwd_len = dir.len;
937
+ if (setup_git_directory_gently_1(&dir, gitdir) <= 0) {
938
+ strbuf_release(&dir);
939
+ return NULL;
940
+ }
941
+
942
+ /*
943
+ * The returned gitdir is relative to dir, and if dir does not reflect
944
+ * the current working directory, we simply make the gitdir absolute.
945
+ */
946
+ if (dir.len < cwd_len && !is_absolute_path(gitdir->buf + gitdir_offset)) {
947
+ /* Avoid a trailing "/." */
948
+ if (!strcmp(".", gitdir->buf + gitdir_offset))
949
+ strbuf_setlen(gitdir, gitdir_offset);
950
+ else
951
+ strbuf_addch(&dir, '/');
952
+ strbuf_insert(gitdir, gitdir_offset, dir.buf, dir.len);
953
+ }
954
+
955
+ strbuf_reset(&dir);
956
+ strbuf_addf(&dir, "%s/config", gitdir->buf + gitdir_offset);
957
+ read_repository_format(&candidate, dir.buf);
958
+ strbuf_release(&dir);
959
+
960
+ if (verify_repository_format(&candidate, &err) < 0) {
961
+ warning("ignoring git dir '%s': %s",
962
+ gitdir->buf + gitdir_offset, err.buf);
963
+ strbuf_release(&err);
964
+ return NULL;
965
+ }
966
+
967
+ return gitdir->buf + gitdir_offset;
968
+}
969
+
970
const char *setup_git_directory_gently(int *nongit_ok)
971
{
972
static struct strbuf cwd = STRBUF_INIT;