diff --git a/setup.c b/setup.c index 65f4ac95a8..911e80988f 100644 --- a/setup.c +++ b/setup.c @@ -960,8 +960,14 @@ void read_gitfile_error_die(int error_code, const char *path, const char *dir) * will be set to an error code and NULL will be returned. If * return_error_code is NULL the function will die instead (for most * cases). + * + * If the code is READ_GITFILE_ERR_NOT_A_REPO and return_error_dir is + * non-NULL, the directory to which the gitfile points will be returned + * there. The caller is responsible for freeing the resulting string. */ -const char *read_gitfile_gently(const char *path, int *return_error_code) +const char *read_gitfile_gently_with_error_dir(const char *path, + int *return_error_code, + char **return_error_dir) { const int max_file_size = 1 << 20; /* 1MB */ int error_code = 0; @@ -1026,6 +1032,8 @@ const char *read_gitfile_gently(const char *path, int *return_error_code) } if (!is_git_directory(dir)) { error_code = READ_GITFILE_ERR_NOT_A_REPO; + if (return_error_dir) + *return_error_dir = xstrdup(dir); goto cleanup_return; } @@ -1609,11 +1617,12 @@ static enum discovery_result setup_git_directory_gently_1(struct strbuf *dir, int offset = dir->len, error_code = 0; char *gitdir_path = NULL; char *gitfile = NULL; + char *error_dst = NULL; if (offset > min_offset) strbuf_addch(dir, '/'); strbuf_addstr(dir, DEFAULT_GIT_DIR_ENVIRONMENT); - gitdirenv = read_gitfile_gently(dir->buf, &error_code); + gitdirenv = read_gitfile_gently_with_error_dir(dir->buf, &error_code, &error_dst); if (!gitdirenv) { switch (error_code) { case READ_GITFILE_ERR_MISSING: @@ -1637,9 +1646,11 @@ static enum discovery_result setup_git_directory_gently_1(struct strbuf *dir, return GIT_DIR_INVALID_GITFILE; default: if (die_on_error) - read_gitfile_error_die(error_code, dir->buf, NULL); - else + read_gitfile_error_die(error_code, dir->buf, error_dst); + else { + free(error_dst); return GIT_DIR_INVALID_GITFILE; + } } } else { gitfile = xstrdup(dir->buf); diff --git a/setup.h b/setup.h index b9fd96bea6..0b99fab962 100644 --- a/setup.h +++ b/setup.h @@ -39,7 +39,8 @@ int is_nonbare_repository_dir(struct strbuf *path); #define READ_GITFILE_ERR_MISSING 9 #define READ_GITFILE_ERR_IS_A_DIR 10 void read_gitfile_error_die(int error_code, const char *path, const char *dir); -const char *read_gitfile_gently(const char *path, int *return_error_code); +const char *read_gitfile_gently_with_error_dir(const char *path, int *return_error_code, char **return_error_dir); +#define read_gitfile_gently(path, err) read_gitfile_gently_with_error_dir((path), (err), NULL) #define read_gitfile(path) read_gitfile_gently((path), NULL) const char *resolve_gitdir_gently(const char *suspect, int *return_error_code); #define resolve_gitdir(path) resolve_gitdir_gently((path), NULL) diff --git a/t/t0002-gitfile.sh b/t/t0002-gitfile.sh index dfbcdddbcc..6967e12b9f 100755 --- a/t/t0002-gitfile.sh +++ b/t/t0002-gitfile.sh @@ -27,7 +27,7 @@ test_expect_success 'bad setup: invalid .git file format' ' test_expect_success 'bad setup: invalid .git file path' ' echo "gitdir: $REAL.not" >.git && test_must_fail git rev-parse 2>.err && - test_grep "not a git repository" .err + test_grep "not a git repository: $REAL.not" .err ' test_expect_success 'final setup + check rev-parse --git-dir' '