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>
This commit is contained in:
Johannes Schindelin 2017-03-13 21:10:45 +01:00 committed by Junio C Hamano
parent ce9b8aab5d
commit 16ac8b8db6
2 changed files with 50 additions and 0 deletions

View File

@ -518,6 +518,13 @@ extern void set_git_work_tree(const char *tree);
#define ALTERNATE_DB_ENVIRONMENT "GIT_ALTERNATE_OBJECT_DIRECTORIES"
extern void setup_work_tree(void);
/*
* Find GIT_DIR of the repository that contains the current working directory,
* without changing the working directory or other global state. The result is
* appended to gitdir. The return value is either NULL if no repository was
* found, or pointing to the path inside gitdir's buffer.
*/
extern const char *discover_git_directory(struct strbuf *gitdir);
extern const char *setup_git_directory_gently(int *);
extern const char *setup_git_directory(void);
extern char *prefix_path(const char *prefix, int len, const char *path);

43
setup.c
View File

@ -924,6 +924,49 @@ static enum discovery_result setup_git_directory_gently_1(struct strbuf *dir,
}
}
const char *discover_git_directory(struct strbuf *gitdir)
{
struct strbuf dir = STRBUF_INIT, err = STRBUF_INIT;
size_t gitdir_offset = gitdir->len, cwd_len;
struct repository_format candidate;
if (strbuf_getcwd(&dir))
return NULL;
cwd_len = dir.len;
if (setup_git_directory_gently_1(&dir, gitdir) <= 0) {
strbuf_release(&dir);
return NULL;
}
/*
* The returned gitdir is relative to dir, and if dir does not reflect
* the current working directory, we simply make the gitdir absolute.
*/
if (dir.len < cwd_len && !is_absolute_path(gitdir->buf + gitdir_offset)) {
/* Avoid a trailing "/." */
if (!strcmp(".", gitdir->buf + gitdir_offset))
strbuf_setlen(gitdir, gitdir_offset);
else
strbuf_addch(&dir, '/');
strbuf_insert(gitdir, gitdir_offset, dir.buf, dir.len);
}
strbuf_reset(&dir);
strbuf_addf(&dir, "%s/config", gitdir->buf + gitdir_offset);
read_repository_format(&candidate, dir.buf);
strbuf_release(&dir);
if (verify_repository_format(&candidate, &err) < 0) {
warning("ignoring git dir '%s': %s",
gitdir->buf + gitdir_offset, err.buf);
strbuf_release(&err);
return NULL;
}
return gitdir->buf + gitdir_offset;
}
const char *setup_git_directory_gently(int *nongit_ok)
{
static struct strbuf cwd = STRBUF_INIT;