]> git.ipfire.org Git - thirdparty/git.git/blobdiff - dir.c
Merge branch 'gg/worktree-from-the-above' into maint
[thirdparty/git.git] / dir.c
diff --git a/dir.c b/dir.c
index 6ca2ef5f04e1f551842a9bad06dd771e56b3ebd3..d7cfb08e441825f421f91a982063e00be4168c71 100644 (file)
--- a/dir.c
+++ b/dir.c
@@ -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)) {