PATHSPEC_SYMLINK_LEADING_PATH and _STRIP_SUBMODULE_SLASH_EXPENSIVE are
respectively the alternate implementation of
builtin/add.c:validate_pathspec() and
builtin/add.c:treat_gitlinks(). They are intended to replace those
functions when builtin/add.c is converted to use parse_pathspec.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclo...@gmail.com>
---
 cache.h |  2 ++
 setup.c | 26 ++++++++++++++++++++++++++
 2 files changed, 28 insertions(+)

diff --git a/cache.h b/cache.h
index 611a410..a49496e 100644
--- a/cache.h
+++ b/cache.h
@@ -506,6 +506,8 @@ struct pathspec {
 /* parse_pathspec flags */
 #define PATHSPEC_EMPTY_MATCH_ALL (1<<0) /* No args means match everything */
 #define PATHSPEC_STRIP_SUBMODULE_SLASH_CHEAP (1<<1)
+#define PATHSPEC_SYMLINK_LEADING_PATH (1<<2) /* has_symlink_leading_path */
+#define PATHSPEC_STRIP_SUBMODULE_SLASH_EXPENSIVE (1<<3)
 
 extern int init_pathspec(struct pathspec *, const char **);
 extern void parse_pathspec(struct pathspec *pathspec, unsigned magic_mask,
diff --git a/setup.c b/setup.c
index a1aabc2..b6f419d 100644
--- a/setup.c
+++ b/setup.c
@@ -259,6 +259,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);
+               }
+
        item->flags = 0;
        if (limit_pathspec_to_literal())
                item->nowildcard_len = item->len;
@@ -333,6 +353,12 @@ void parse_pathspec(struct pathspec *pathspec,
                if (item[i].magic & ~magic_mask)
                        die(_("pathspec magic in '%s' is not supported"
                              " by this command"), arg);
+
+               if ((flags & PATHSPEC_SYMLINK_LEADING_PATH) &&
+                   has_symlink_leading_path(item[i].match, item[i].len)) {
+                       die(_("pathspec '%s' is beyond a symbolic link"), arg);
+               }
+
                if (item[i].nowildcard_len < item[i].len)
                        pathspec->has_wildcard = 1;
                pathspec->magic |= item[i].magic;
-- 
1.8.0.rc2.23.g1fb49df

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to