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;