Skip to content

Commit 16ac8b8

Browse files
dschogitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent ce9b8aa commit 16ac8b8

File tree

2 files changed

+50
-0
lines changed

2 files changed

+50
-0
lines changed

cache.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,13 @@ extern void set_git_work_tree(const char *tree);
518518
#define ALTERNATE_DB_ENVIRONMENT "GIT_ALTERNATE_OBJECT_DIRECTORIES"
519519

520520
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);
521528
extern const char *setup_git_directory_gently(int *);
522529
extern const char *setup_git_directory(void);
523530
extern char *prefix_path(const char *prefix, int len, const char *path);

setup.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -924,6 +924,49 @@ static enum discovery_result setup_git_directory_gently_1(struct strbuf *dir,
924924
}
925925
}
926926

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+
927970
const char *setup_git_directory_gently(int *nongit_ok)
928971
{
929972
static struct strbuf cwd = STRBUF_INIT;

0 commit comments

Comments
 (0)