]> git.ipfire.org Git - thirdparty/git.git/blobdiff - pathspec.c
rename field "raw" to "_raw" in struct pathspec
[thirdparty/git.git] / pathspec.c
index 1c07c23fe0e4bb7b9847fca47624b3097a175adf..da802e22a01ca0bc255961c745e14841fa7d2990 100644 (file)
@@ -15,8 +15,8 @@
  * If seen[] has not already been written to, it may make sense
  * to use find_pathspecs_matching_against_index() instead.
  */
-void add_pathspec_matches_against_index(const char **pathspec,
-                                       char *seen, int specs)
+void add_pathspec_matches_against_index(const struct pathspec *pathspec,
+                                       char *seen)
 {
        int num_unmatched = 0, i;
 
@@ -26,14 +26,14 @@ void add_pathspec_matches_against_index(const char **pathspec,
         * mistakenly think that the user gave a pathspec that did not match
         * anything.
         */
-       for (i = 0; i < specs; i++)
+       for (i = 0; i < pathspec->nr; i++)
                if (!seen[i])
                        num_unmatched++;
        if (!num_unmatched)
                return;
        for (i = 0; i < active_nr; i++) {
                struct cache_entry *ce = active_cache[i];
-               match_pathspec(pathspec, ce->name, ce_namelen(ce), 0, seen);
+               match_pathspec_depth(pathspec, ce->name, ce_namelen(ce), 0, seen);
        }
 }
 
@@ -45,61 +45,13 @@ void add_pathspec_matches_against_index(const char **pathspec,
  * nature of the "closest" (i.e. most specific) matches which each of the
  * given pathspecs achieves against all items in the index.
  */
-char *find_pathspecs_matching_against_index(const char **pathspec)
+char *find_pathspecs_matching_against_index(const struct pathspec *pathspec)
 {
-       char *seen;
-       int i;
-
-       for (i = 0; pathspec[i];  i++)
-               ; /* just counting */
-       seen = xcalloc(i, 1);
-       add_pathspec_matches_against_index(pathspec, seen, i);
+       char *seen = xcalloc(pathspec->nr, 1);
+       add_pathspec_matches_against_index(pathspec, seen);
        return seen;
 }
 
-/*
- * Check the index to see whether path refers to a submodule, or
- * something inside a submodule.  If the former, returns the path with
- * any trailing slash stripped.  If the latter, dies with an error
- * message.
- */
-const char *check_path_for_gitlink(const char *path)
-{
-       int i, path_len = strlen(path);
-       for (i = 0; i < active_nr; i++) {
-               struct cache_entry *ce = active_cache[i];
-               if (S_ISGITLINK(ce->ce_mode)) {
-                       int ce_len = ce_namelen(ce);
-                       if (path_len <= ce_len || path[ce_len] != '/' ||
-                           memcmp(ce->name, path, ce_len))
-                               /* path does not refer to this
-                                * submodule or anything inside it */
-                               continue;
-                       if (path_len == ce_len + 1) {
-                               /* path refers to submodule;
-                                * strip trailing slash */
-                               return xstrndup(ce->name, ce_len);
-                       } else {
-                               die (_("Path '%s' is in submodule '%.*s'"),
-                                    path, ce_len, ce->name);
-                       }
-               }
-       }
-       return path;
-}
-
-/*
- * Dies if the given path refers to a file inside a symlinked
- * directory in the index.
- */
-void die_if_path_beyond_symlink(const char *path, const char *prefix)
-{
-       if (has_symlink_leading_path(path, strlen(path))) {
-               int len = prefix ? strlen(prefix) : 0;
-               die(_("'%s' is beyond a symbolic link"), path + len);
-       }
-}
-
 /*
  * Magic pathspec
  *
@@ -203,7 +155,17 @@ static unsigned prefix_pathspec(struct pathspec_item *item,
        else
                match = prefix_path(prefix, prefixlen, copyfrom);
        *raw = item->match = match;
-       item->original = elt;
+       /*
+        * Prefix the pathspec (keep all magic) and assign to
+        * original. Useful for passing to another command.
+        */
+       if (flags & PATHSPEC_PREFIX_ORIGIN) {
+               struct strbuf sb = STRBUF_INIT;
+               strbuf_add(&sb, elt, copyfrom - elt);
+               strbuf_addstr(&sb, match);
+               item->original = strbuf_detach(&sb, NULL);
+       } else
+               item->original = elt;
        item->len = strlen(item->match);
 
        if ((flags & PATHSPEC_STRIP_SUBMODULE_SLASH_CHEAP) &&
@@ -214,6 +176,26 @@ static unsigned prefix_pathspec(struct pathspec_item *item,
                match[item->len] = '\0';
        }
 
+       if (flags & PATHSPEC_STRIP_SUBMODULE_SLASH_EXPENSIVE)
+               for (i = 0; i < active_nr; i++) {
+                       struct cache_entry *ce = active_cache[i];
+                       int ce_len = ce_namelen(ce);
+
+                       if (!S_ISGITLINK(ce->ce_mode))
+                               continue;
+
+                       if (item->len <= ce_len || match[ce_len] != '/' ||
+                           memcmp(ce->name, match, ce_len))
+                               continue;
+                       if (item->len == ce_len + 1) {
+                               /* strip trailing slash */
+                               item->len--;
+                               match[item->len] = '\0';
+                       } else
+                               die (_("Pathspec '%s' is in submodule '%.*s'"),
+                                    elt, ce_len, ce->name);
+               }
+
        if (limit_pathspec_to_literal())
                item->nowildcard_len = item->len;
        else
@@ -305,7 +287,7 @@ void parse_pathspec(struct pathspec *pathspec,
                raw[0] = prefix;
                raw[1] = NULL;
                pathspec->nr = 1;
-               pathspec->raw = raw;
+               pathspec->_raw = raw;
                return;
        }
 
@@ -315,7 +297,7 @@ void parse_pathspec(struct pathspec *pathspec,
 
        pathspec->nr = n;
        pathspec->items = item = xmalloc(sizeof(*item) * n);
-       pathspec->raw = argv;
+       pathspec->_raw = argv;
        prefixlen = prefix ? strlen(prefix) : 0;
 
        for (i = 0; i < n; i++) {
@@ -329,14 +311,24 @@ void parse_pathspec(struct pathspec *pathspec,
                        unsupported_magic(entry,
                                          item[i].magic & magic_mask,
                                          short_magic);
+
+               if ((flags & PATHSPEC_SYMLINK_LEADING_PATH) &&
+                   has_symlink_leading_path(item[i].match, item[i].len)) {
+                       die(_("pathspec '%s' is beyond a symbolic link"), entry);
+               }
+
                if (item[i].nowildcard_len < item[i].len)
                        pathspec->has_wildcard = 1;
                pathspec->magic |= item[i].magic;
        }
 
-       if (pathspec->magic & PATHSPEC_MAXDEPTH)
+
+       if (pathspec->magic & PATHSPEC_MAXDEPTH) {
+               if (flags & PATHSPEC_KEEP_ORDER)
+                       die("BUG: PATHSPEC_MAXDEPTH_VALID and PATHSPEC_KEEP_ORDER are incompatible");
                qsort(pathspec->items, pathspec->nr,
                      sizeof(struct pathspec_item), pathspec_item_cmp);
+       }
 }
 
 /*
@@ -365,7 +357,7 @@ const char **get_pathspec(const char *prefix, const char **pathspec)
                       PATHSPEC_ALL_MAGIC & ~PATHSPEC_FROMTOP,
                       PATHSPEC_PREFER_CWD,
                       prefix, pathspec);
-       return ps.raw;
+       return ps._raw;
 }
 
 void copy_pathspec(struct pathspec *dst, const struct pathspec *src)
@@ -375,3 +367,9 @@ void copy_pathspec(struct pathspec *dst, const struct pathspec *src)
        memcpy(dst->items, src->items,
               sizeof(struct pathspec_item) * dst->nr);
 }
+
+void free_pathspec(struct pathspec *pathspec)
+{
+       free(pathspec->items);
+       pathspec->items = NULL;
+}