diff --git a/include/git2/repository.h b/include/git2/repository.h index 85b7e6861..f7efe0116 100644 --- a/include/git2/repository.h +++ b/include/git2/repository.h @@ -95,11 +95,15 @@ GIT_EXTERN(int) git_repository_discover( * * GIT_REPOSITORY_OPEN_BARE - Open repository as a bare repo regardless * of core.bare config, and defer loading config file for faster setup. * Unlike `git_repository_open_bare`, this can follow gitlinks. + * * GIT_REPOSITORY_OPEN_NO_DOTGIT - Do not check for a repository by + * appending /.git to the start_path; only open the repository if + * start_path itself points to the git directory. */ typedef enum { GIT_REPOSITORY_OPEN_NO_SEARCH = (1 << 0), GIT_REPOSITORY_OPEN_CROSS_FS = (1 << 1), GIT_REPOSITORY_OPEN_BARE = (1 << 2), + GIT_REPOSITORY_OPEN_NO_DOTGIT = (1 << 3), } git_repository_open_flag_t; /** diff --git a/src/repository.c b/src/repository.c index 3ea15b790..5b4346793 100644 --- a/src/repository.c +++ b/src/repository.c @@ -370,11 +370,12 @@ static int find_repo( /* in_dot_git toggles each loop: * /a/b/c/.git, /a/b/c, /a/b/.git, /a/b, /a/.git, /a - * With GIT_REPOSITORY_OPEN_BARE, we assume we started with /a/b/c.git - * and don't append .git the first time through. + * With GIT_REPOSITORY_OPEN_BARE or GIT_REPOSITORY_OPEN_NO_DOTGIT, we + * assume we started with /a/b/c.git and don't append .git the first + * time through. * min_iterations indicates the number of iterations left before going * further counts as a search. */ - if (flags & GIT_REPOSITORY_OPEN_BARE) { + if (flags & (GIT_REPOSITORY_OPEN_BARE | GIT_REPOSITORY_OPEN_NO_DOTGIT)) { in_dot_git = true; min_iterations = 1; } else { @@ -384,10 +385,12 @@ static int find_repo( while (!error && (min_iterations || !(path.ptr[ceiling_offset] == 0 || (flags & GIT_REPOSITORY_OPEN_NO_SEARCH)))) { - if (!in_dot_git) - if ((error = git_buf_joinpath(&path, path.ptr, DOT_GIT)) < 0) - break; - in_dot_git = !in_dot_git; + if (!(flags & GIT_REPOSITORY_OPEN_NO_DOTGIT)) { + if (!in_dot_git) + if ((error = git_buf_joinpath(&path, path.ptr, DOT_GIT)) < 0) + break; + in_dot_git = !in_dot_git; + } if (p_stat(path.ptr, &st) == 0) { /* check that we have not crossed device boundaries */ diff --git a/tests/repo/open.c b/tests/repo/open.c index 7cdd182a7..5197276fb 100644 --- a/tests/repo/open.c +++ b/tests/repo/open.c @@ -206,6 +206,12 @@ void test_repo_open__failures(void) cl_git_fail(git_repository_open_ext(&repo, "alternate", 0, NULL)); cl_git_fail(git_repository_open_ext(&repo, "alternate/.git", 0, NULL)); + /* fail with no searching and no appending .git */ + cl_git_fail(git_repository_open_ext( + &repo, "attr", + GIT_REPOSITORY_OPEN_NO_SEARCH | GIT_REPOSITORY_OPEN_NO_DOTGIT, + NULL)); + git_buf_free(&ceiling); }