Make :/ accept a regex rather than a fixed pattern
[gitweb.git] / dir.c
diff --git a/dir.c b/dir.c
index 133c333df61be37e7908f77367f63c85cfc9c548..5615f33af187f381f8c2dfe7ab53910fe165fd59 100644 (file)
--- a/dir.c
+++ b/dir.c
@@ -594,13 +594,29 @@ static int simplify_away(const char *path, int pathlen, const struct path_simpli
        return 0;
 }
 
-static int in_pathspec(const char *path, int len, const struct path_simplify *simplify)
+/*
+ * This function tells us whether an excluded path matches a
+ * list of "interesting" pathspecs. That is, whether a path matched
+ * by any of the pathspecs could possibly be ignored by excluding
+ * the specified path. This can happen if:
+ *
+ *   1. the path is mentioned explicitly in the pathspec
+ *
+ *   2. the path is a directory prefix of some element in the
+ *      pathspec
+ */
+static int exclude_matches_pathspec(const char *path, int len,
+               const struct path_simplify *simplify)
 {
        if (simplify) {
                for (; simplify->path; simplify++) {
                        if (len == simplify->len
                            && !memcmp(path, simplify->path, len))
                                return 1;
+                       if (len < simplify->len
+                           && simplify->path[len] == '/'
+                           && !memcmp(path, simplify->path, len))
+                               return 1;
                }
        }
        return 0;
@@ -678,7 +694,7 @@ static enum path_treatment treat_one_path(struct dir_struct *dir,
 {
        int exclude = excluded(dir, path, &dtype);
        if (exclude && (dir->flags & DIR_COLLECT_IGNORED)
-           && in_pathspec(path, *len, simplify))
+           && exclude_matches_pathspec(path, *len, simplify))
                dir_add_ignored(dir, path, *len);
 
        /*
@@ -942,9 +958,14 @@ char *get_relative_cwd(char *buffer, int size, const char *dir)
        }
        if (*dir)
                return NULL;
-       if (*cwd == '/')
+       switch (*cwd) {
+       case '\0':
+               return cwd;
+       case '/':
                return cwd + 1;
-       return cwd;
+       default:
+               return NULL;
+       }
 }
 
 int is_inside_dir(const char *dir)