Skip to content

Commit 1756efd

Browse files
derrickstoleedscho
authored andcommitted
setup: add discover_git_directory_reason()
There are many reasons why discovering a Git directory may fail. In particular, 8959555 (setup_git_directory(): add an owner check for the top-level directory, 2022-03-02) added ownership checks as a security precaution. Callers attempting to set up a Git directory may want to inform the user about the reason for the failure. For that, expose the enum discovery_result from within setup.c and into cache.h where discover_git_directory() is defined. I initially wanted to change the return type of discover_git_directory() to be this enum, but several callers rely upon the "zero means success". The two problems with this are: 1. The zero value of the enum is actually GIT_DIR_NONE, so nonpositive results are errors. 2. There are multiple successful states, so some positive results are successful. Instead of updating all callers immediately, add a new method, discover_git_directory_reason(), and convert discover_git_directory() to be a thin shim on top of it. Because there are extra checks that discover_git_directory_reason() does after setup_git_directory_gently_1(), there are other modes that can be returned for failure states. Add these modes to the enum, but be sure to explicitly add them as BUG() states in the switch of setup_git_directory_gently(). Signed-off-by: Derrick Stolee <derrickstolee@github.com>
1 parent 2a0a8d7 commit 1756efd

File tree

2 files changed

+41
-23
lines changed

2 files changed

+41
-23
lines changed

cache.h

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -631,6 +631,30 @@ void set_git_work_tree(const char *tree);
631631
#define ALTERNATE_DB_ENVIRONMENT "GIT_ALTERNATE_OBJECT_DIRECTORIES"
632632

633633
void setup_work_tree(void);
634+
635+
/*
636+
* discover_git_directory_reason() is similar to discover_git_directory(),
637+
* except it returns an enum value instead. It is important to note that
638+
* a zero-valued return here is actually GIT_DIR_NONE, which is different
639+
* from discover_git_directory.
640+
*/
641+
enum discovery_result {
642+
GIT_DIR_NONE = 0,
643+
GIT_DIR_EXPLICIT,
644+
GIT_DIR_DISCOVERED,
645+
GIT_DIR_BARE,
646+
/* these are errors */
647+
GIT_DIR_HIT_CEILING = -1,
648+
GIT_DIR_HIT_MOUNT_POINT = -2,
649+
GIT_DIR_INVALID_GITFILE = -3,
650+
GIT_DIR_INVALID_OWNERSHIP = -4,
651+
GIT_DIR_DISALLOWED_BARE = -5,
652+
GIT_DIR_INVALID_FORMAT = -6,
653+
GIT_DIR_CWD_FAILURE = -7,
654+
};
655+
enum discovery_result discover_git_directory_reason(struct strbuf *commondir,
656+
struct strbuf *gitdir);
657+
634658
/*
635659
* Find the commondir and gitdir of the repository that contains the current
636660
* working directory, without changing the working directory or other global
@@ -639,8 +663,12 @@ void setup_work_tree(void);
639663
* both have the same result appended to the buffer. The return value is
640664
* either 0 upon success and non-zero if no repository was found.
641665
*/
642-
int discover_git_directory(struct strbuf *commondir,
643-
struct strbuf *gitdir);
666+
static inline int discover_git_directory(struct strbuf *commondir,
667+
struct strbuf *gitdir)
668+
{
669+
return discover_git_directory_reason(commondir, gitdir) <= 0;
670+
}
671+
644672
const char *setup_git_directory_gently(int *);
645673
const char *setup_git_directory(void);
646674
char *prefix_path(const char *prefix, int len, const char *path);

setup.c

Lines changed: 11 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1205,19 +1205,6 @@ static const char *allowed_bare_repo_to_string(
12051205
return NULL;
12061206
}
12071207

1208-
enum discovery_result {
1209-
GIT_DIR_NONE = 0,
1210-
GIT_DIR_EXPLICIT,
1211-
GIT_DIR_DISCOVERED,
1212-
GIT_DIR_BARE,
1213-
/* these are errors */
1214-
GIT_DIR_HIT_CEILING = -1,
1215-
GIT_DIR_HIT_MOUNT_POINT = -2,
1216-
GIT_DIR_INVALID_GITFILE = -3,
1217-
GIT_DIR_INVALID_OWNERSHIP = -4,
1218-
GIT_DIR_DISALLOWED_BARE = -5,
1219-
};
1220-
12211208
/*
12221209
* We cannot decide in this function whether we are in the work tree or
12231210
* not, since the config can only be read _after_ this function was called.
@@ -1368,21 +1355,22 @@ static enum discovery_result setup_git_directory_gently_1(struct strbuf *dir,
13681355
}
13691356
}
13701357

1371-
int discover_git_directory(struct strbuf *commondir,
1372-
struct strbuf *gitdir)
1358+
enum discovery_result discover_git_directory_reason(struct strbuf *commondir,
1359+
struct strbuf *gitdir)
13731360
{
13741361
struct strbuf dir = STRBUF_INIT, err = STRBUF_INIT;
13751362
size_t gitdir_offset = gitdir->len, cwd_len;
13761363
size_t commondir_offset = commondir->len;
13771364
struct repository_format candidate = REPOSITORY_FORMAT_INIT;
1365+
enum discovery_result result;
13781366

13791367
if (strbuf_getcwd(&dir))
1380-
return -1;
1368+
return GIT_DIR_CWD_FAILURE;
13811369

13821370
cwd_len = dir.len;
1383-
if (setup_git_directory_gently_1(&dir, gitdir, NULL, 0) <= 0) {
1371+
if ((result = setup_git_directory_gently_1(&dir, gitdir, NULL, 0)) <= 0) {
13841372
strbuf_release(&dir);
1385-
return -1;
1373+
return result;
13861374
}
13871375

13881376
/*
@@ -1412,7 +1400,7 @@ int discover_git_directory(struct strbuf *commondir,
14121400
strbuf_setlen(commondir, commondir_offset);
14131401
strbuf_setlen(gitdir, gitdir_offset);
14141402
clear_repository_format(&candidate);
1415-
return -1;
1403+
return GIT_DIR_INVALID_FORMAT;
14161404
}
14171405

14181406
/* take ownership of candidate.partial_clone */
@@ -1421,7 +1409,7 @@ int discover_git_directory(struct strbuf *commondir,
14211409
candidate.partial_clone = NULL;
14221410

14231411
clear_repository_format(&candidate);
1424-
return 0;
1412+
return result;
14251413
}
14261414

14271415
const char *setup_git_directory_gently(int *nongit_ok)
@@ -1513,9 +1501,11 @@ const char *setup_git_directory_gently(int *nongit_ok)
15131501
*nongit_ok = 1;
15141502
break;
15151503
case GIT_DIR_NONE:
1504+
case GIT_DIR_CWD_FAILURE:
1505+
case GIT_DIR_INVALID_FORMAT:
15161506
/*
15171507
* As a safeguard against setup_git_directory_gently_1 returning
1518-
* this value, fallthrough to BUG. Otherwise it is possible to
1508+
* these values, fallthrough to BUG. Otherwise it is possible to
15191509
* set startup_info->have_repository to 1 when we did nothing to
15201510
* find a repository.
15211511
*/

0 commit comments

Comments
 (0)