-
Notifications
You must be signed in to change notification settings - Fork 2.5k
Fix repository discovery with ceiling_dirs at current directory #3727
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
I ran into this issue while writing and testing test cases for #3711. I wrote some test cases for this corner case in The new behavior, and the new tests, match the way the git command-line tools handle |
Any thoughts on this bug? Do the test cases seem reasonable, as expressions of git's own behavior? Does the rewritten logic seem like an improvement in clarity? |
ceiling_dirs = git_buf_cstr(&ceiling_dirs_buf); | ||
|
||
//this must pass as ceiling_directories cannot prevent the current | ||
//working directory to be checked |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We avoid C++-style comments (it seems this file has at least one instance of this already, but let's not let it get out of control)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No problem, I can change all of the new comments to /* C style */
.
git only checks ceiling directories when its search ascends to a parent directory. A ceiling directory matching the starting directory will not prevent git from finding a repository in the starting directory or a parent directory. libgit2 handled the former case correctly, but differed from git in the latter case: given a ceiling directory matching the starting directory, but no repository at the starting directory, libgit2 would stop the search at that point rather than finding a repository in a parent directory. Test case using git command-line tools: /tmp$ git init x Initialized empty Git repository in /tmp/x/.git/ /tmp$ cd x/ /tmp/x$ mkdir subdir /tmp/x$ cd subdir/ /tmp/x/subdir$ GIT_CEILING_DIRECTORIES=/tmp/x git rev-parse --git-dir fatal: Not a git repository (or any of the parent directories): .git /tmp/x/subdir$ GIT_CEILING_DIRECTORIES=/tmp/x/subdir git rev-parse --git-dir /tmp/x/.git Fix the testsuite to test this case (in one case fixing a test that depended on the current behavior), and then fix find_repo to handle this case correctly. In the process, simplify and document the logic in find_repo(): - Separate the concepts of "currently checking a .git directory" and "number of iterations left before going further counts as a search" into two separate variables, in_dot_git and min_iterations. - Move the logic to handle in_dot_git and append /.git to the top of the loop. - Only search ceiling_dirs and find ceiling_offset after running out of min_iterations; since ceiling_offset only tracks the longest matching ceiling directory, if ceiling_dirs contained both the current directory and a parent directory, this change makes find_repo stop the search at the parent directory.
47d263c
to
fb714f6
Compare
Updated to use exclusively |
Following up on this; any issues with the new version of the pull request? |
Sorry about the delay in getting back to you. I think that this is overall a good change, but I'm finding the For example, we Things like It seems like the logic here is correct, but cleaning this up a bit might make it easier to review, if that's something you're willing to do. Thanks! |
👍 It took me quite a while to work through its logic myself, so that sounds good to me.
Sure, I'd be happy to do so. To some extent, I'd tried to reduce the amount of refactoring to the minimal amount needed to make the logic clearer, because I didn't want to make this more difficult to review. If you don't mind, I'd like to make this a two-patch series, with the first patch fixing this logic bug and doing some minimal refactoring, and the second doing some more aggressive refactoring. Does that sound reasonable? |
Awesome, thank you.
Fine with me! Thanks for tackling the refactoring. 😀 |
Included with #3711 |
git only checks ceiling directories when its search ascends to a parent
directory. A ceiling directory matching the starting directory will not
prevent git from finding a repository in the starting directory or a
parent directory. libgit2 handled the former case correctly, but
differed from git in the latter case: given a ceiling directory matching
the starting directory, but no repository at the starting directory,
libgit2 would stop the search at that point rather than finding a
repository in a parent directory.
Test case using git command-line tools:
/tmp$ git init x
Initialized empty Git repository in /tmp/x/.git/
/tmp$ cd x/
/tmp/x$ mkdir subdir
/tmp/x$ cd subdir/
/tmp/x/subdir$ GIT_CEILING_DIRECTORIES=/tmp/x git rev-parse --git-dir
fatal: Not a git repository (or any of the parent directories): .git
/tmp/x/subdir$ GIT_CEILING_DIRECTORIES=/tmp/x/subdir git rev-parse --git-dir
/tmp/x/.git
Fix the testsuite to test this case (in one case fixing a test that
depended on the current behavior), and then fix find_repo to handle this
case correctly.
In the process, simplify and document the logic in find_repo():
"number of iterations left before going further counts as a search"
into two separate variables, in_dot_git and min_iterations.
loop.
min_iterations; since ceiling_offset only tracks the longest matching
ceiling directory, if ceiling_dirs contained both the current
directory and a parent directory, this change makes find_repo stop the
search at the parent directory.