diff options
author | Junio C Hamano <gitster@pobox.com> | 2022-07-27 20:00:29 (GMT) |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2022-07-27 20:00:29 (GMT) |
commit | f070ec4cb5c4959faab1fdfc68e9e368c38ba493 (patch) | |
tree | 1d350cf4c245a3b1a245ec2a4460135a4288bb2e /dir.c | |
parent | 0263e6bc037058f5acd70f70ecfbe7137012fd12 (diff) | |
parent | d6c9a717558a5ec36516026e68dcad3cbc4df1ff (diff) | |
download | git-f070ec4cb5c4959faab1fdfc68e9e368c38ba493.zip git-f070ec4cb5c4959faab1fdfc68e9e368c38ba493.tar.gz git-f070ec4cb5c4959faab1fdfc68e9e368c38ba493.tar.bz2 |
Merge branch 'gg/worktree-from-the-above' into maint
In a non-bare repository, the behavior of Git when the
core.worktree configuration variable points at a directory that has
a repository as its subdirectory, regressed in Git 2.27 days.
source: <20220616234433.225-1-gg.oss@outlook.com>
source: <20220616231956.154-1-gg.oss@outlook.com>
* gg/worktree-from-the-above:
dir: minor refactoring / clean-up
dir: traverse into repository
Diffstat (limited to 'dir.c')
-rw-r--r-- | dir.c | 35 |
1 files changed, 28 insertions, 7 deletions
@@ -1861,7 +1861,7 @@ static enum path_treatment treat_directory(struct dir_struct *dir, */ enum path_treatment state; int matches_how = 0; - int nested_repo = 0, check_only, stop_early; + int check_only, stop_early; int old_ignored_nr, old_untracked_nr; /* The "len-1" is to strip the final '/' */ enum exist_status status = directory_exists_in_index(istate, dirname, len-1); @@ -1893,16 +1893,37 @@ static enum path_treatment treat_directory(struct dir_struct *dir, if ((dir->flags & DIR_SKIP_NESTED_GIT) || !(dir->flags & DIR_NO_GITLINKS)) { + /* + * Determine if `dirname` is a nested repo by confirming that: + * 1) we are in a nonbare repository, and + * 2) `dirname` is not an immediate parent of `the_repository->gitdir`, + * which could occur if the git_dir or worktree location was + * manually configured by the user; see t2205 testcases 1-3 for + * examples where this matters + */ + int nested_repo; struct strbuf sb = STRBUF_INIT; strbuf_addstr(&sb, dirname); nested_repo = is_nonbare_repository_dir(&sb); + + if (nested_repo) { + char *real_dirname, *real_gitdir; + strbuf_addstr(&sb, ".git"); + real_dirname = real_pathdup(sb.buf, 1); + real_gitdir = real_pathdup(the_repository->gitdir, 1); + + nested_repo = !!strcmp(real_dirname, real_gitdir); + free(real_gitdir); + free(real_dirname); + } strbuf_release(&sb); - } - if (nested_repo) { - if ((dir->flags & DIR_SKIP_NESTED_GIT) || - (matches_how == MATCHED_RECURSIVELY_LEADING_PATHSPEC)) - return path_none; - return excluded ? path_excluded : path_untracked; + + if (nested_repo) { + if ((dir->flags & DIR_SKIP_NESTED_GIT) || + (matches_how == MATCHED_RECURSIVELY_LEADING_PATHSPEC)) + return path_none; + return excluded ? path_excluded : path_untracked; + } } if (!(dir->flags & DIR_SHOW_OTHER_DIRECTORIES)) { |