@@ -1,3 +1,5 @@
+#include <stdio.h>
+#include <string.h>
#include "cache.h"
#include "config.h"
#include "dir.h"
@@ -5,6 +7,7 @@
#include "attr.h"
#include "strvec.h"
#include "quote.h"
+#include "git-compat-util.h"
/*
* Finds which of the given pathspecs match items in the index.
@@ -586,6 +589,8 @@ void parse_pathspec(struct pathspec *pathspec,
for (i = 0; i < n; i++) {
entry = argv[i];
+ check_mishandled_exclude(entry);
+
init_pathspec_item(item + i, flags, prefix, prefixlen, entry);
if (item[i].magic & PATHSPEC_EXCLUDE)
@@ -739,3 +744,22 @@ int match_pathspec_attrs(const struct index_state *istate,
return 1;
}
+
+void check_mishandled_exclude(const char *entry) {
+ char *flags, *path;
+ size_t entry_len = strlen(entry);
+
+ flags = xstrdup(entry);
+ memset(flags, '\0', entry_len);
+ path = xstrdup(entry);
+ memset(path, '\0', entry_len);
+
+ if (sscanf(entry, ":!(%4096[^)])%4096s", flags, path) == 2) {
+ if (count_slashes(flags) == 0) {
+ warning(_("Pathspec provided matches `:!(...)`\n\tDid you mean `:(exclude,...)`?"));
+ }
+ }
+
+ FREE_AND_NULL(flags);
+ FREE_AND_NULL(path);
+}
@@ -157,5 +157,6 @@ char *find_pathspecs_matching_against_index(const struct pathspec *pathspec,
int match_pathspec_attrs(const struct index_state *istate,
const char *name, int namelen,
const struct pathspec_item *item);
+void check_mishandled_exclude(const char* pathspec_entry);
#endif /* PATHSPEC_H */
@@ -244,4 +244,37 @@ test_expect_success 'grep --untracked PATTERN :(exclude)*FILE' '
test_cmp expect-grep actual-grep
'
+cat > expected_warn <<"EOF"
+Pathspec provided matches `:!(...)`
+EOF
+test_expect_success 'warn pathspec :!(...) skips the parenthesized magics' '
+ git log --oneline --format=%s -- '"'"':!(glob)**/file'"'"' >actual 2>warn &&
+ cat <<EOF >expect &&
+sub2/file
+sub/sub/sub/file
+sub/file2
+sub/sub/file
+sub/file
+file
+EOF
+ cat actual &&
+ cat warn &&
+ test_cmp expect actual &&
+ grep -Ff expected_warn warn
+'
+
+test_expect_success 'do not warn that pathspec :!(...) skips the parenthesized magics (if parenthesis would not be part of the magic)' '
+ git log --oneline --format=%s -- '"'"':!(gl/ob)/file'"'"' >actual 2>warn &&
+ cat <<EOF >expect &&
+sub2/file
+sub/sub/sub/file
+sub/file2
+sub/sub/file
+sub/file
+file
+EOF
+ test_cmp expect actual &&
+ ! grep -Ff expected_warn warn
+'
+
test_done