From: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
To: git@vger.kernel.org
Cc: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
Subject: [PATCH 6/6] Implement negative pathspec
Date: Wed, 12 Oct 2011 09:44:43 +1100 [thread overview]
Message-ID: <1318373083-13840-7-git-send-email-pclouds@gmail.com> (raw)
In-Reply-To: <1318373083-13840-1-git-send-email-pclouds@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
I really like the mnemonic ^ but it's regex. ":^Documentation" looks
nicer than ":~Documentation". Do we plan on supporting regex in
pathspec too?
We should mention these magic in a less obscure document. Glossary is
mostly for developer discussions. git-diff may be a good place
because it's one of the two frequently used commands (the other one
is grep) that benefit magic the most (with a short reference from
git.txt)
Documentation/glossary-content.txt | 8 +++---
cache.h | 1 +
dir.c | 2 +
setup.c | 1 +
tree-walk.c | 37 +++++++++++++++++++++++++++++++++--
5 files changed, 42 insertions(+), 7 deletions(-)
diff --git a/Documentation/glossary-content.txt b/Documentation/glossary-content.txt
index 3595b58..9a2765d 100644
--- a/Documentation/glossary-content.txt
+++ b/Documentation/glossary-content.txt
@@ -319,12 +319,12 @@ top `/`;;
The magic word `top` (mnemonic: `/`) makes the pattern match
from the root of the working tree, even when you are running
the command from inside a subdirectory.
+
+exclude `~`;;
+ The magic word `exclude` (mnemonic: `~`) excludes paths that
+ match the pattern.
--
+
-Currently only the slash `/` is recognized as the "magic signature",
-but it is envisioned that we will support more types of magic in later
-versions of git.
-+
A pathspec with only a colon means "there is no pathspec". This form
should not be combined with other pathspec.
diff --git a/cache.h b/cache.h
index 719d4a3..75fe589 100644
--- a/cache.h
+++ b/cache.h
@@ -541,6 +541,7 @@ extern int ie_modified(const struct index_state *, struct cache_entry *, struct
*/
#define PATHSPEC_FROMTOP (1<<0)
#define PATHSPEC_NOGLOB (1<<1)
+#define PATHSPEC_NEGATE (1<<2)
struct pathspec {
const char **raw; /* get_pathspec() result, not freed by free_pathspec() */
diff --git a/dir.c b/dir.c
index d38af0f..46dd35f 100644
--- a/dir.c
+++ b/dir.c
@@ -1305,6 +1305,8 @@ int parse_pathspec(struct pathspec *pathspec, const char *prefix,
pitem->magic |= PATHSPEC_NOGLOB;
else
pathspec->magic &= ~PATHSPEC_NOGLOB;
+ if (pitem->magic & PATHSPEC_NEGATE)
+ pathspec->magic |= PATHSPEC_NEGATE;
pitem++;
dst++;
}
diff --git a/setup.c b/setup.c
index b074210..42beb9b 100644
--- a/setup.c
+++ b/setup.c
@@ -111,6 +111,7 @@ static struct pathspec_magic {
const char *name;
} pathspec_magic[] = {
{ PATHSPEC_FROMTOP, '/', "top" },
+ { PATHSPEC_NEGATE, '~', "exclude" },
};
/*
diff --git a/tree-walk.c b/tree-walk.c
index db07fd6..936b5da 100644
--- a/tree-walk.c
+++ b/tree-walk.c
@@ -580,15 +580,17 @@ static int match_dir_prefix(const char *base, int baselen,
* - zero for no
* - negative for "no, and no subsequent entries will be either"
*/
-int tree_entry_interesting(const struct name_entry *entry,
- struct strbuf *base, int base_offset,
- const struct pathspec *ps)
+static int tree_entry_interesting_1(const struct name_entry *entry,
+ struct strbuf *base, int base_offset,
+ const struct pathspec *ps, int negative_magic)
{
int i;
int pathlen, baselen = base->len - base_offset;
int never_interesting = ps->magic & PATHSPEC_NOGLOB ? -1 : 0;
+ int has_effective_pathspec = 0;
if (!ps->nr) {
+no_pathspec:
if (!ps->recursive || ps->max_depth == -1)
return 2;
return !!within_depth(base->buf + base_offset, baselen,
@@ -604,6 +606,12 @@ int tree_entry_interesting(const struct name_entry *entry,
const char *base_str = base->buf + base_offset;
int matchlen = item->len;
+ if ((!negative_magic && !(item->magic & PATHSPEC_NEGATE)) ||
+ ( negative_magic && (item->magic & PATHSPEC_NEGATE)))
+ has_effective_pathspec = 1;
+ else
+ continue;
+
if (baselen >= matchlen) {
/* If it doesn't match, move along... */
if (!match_dir_prefix(base_str, baselen, match, matchlen))
@@ -663,5 +671,28 @@ match_wildcards:
if (ps->recursive && S_ISDIR(entry->mode))
return 1;
}
+
+ /* the same effect with ps->nr == 0 */
+ if (!has_effective_pathspec)
+ goto no_pathspec;
+
return never_interesting; /* No matches */
}
+
+int tree_entry_interesting(const struct name_entry *entry,
+ struct strbuf *base, int base_offset,
+ const struct pathspec *ps)
+{
+ int next_ret, ret;
+
+ ret = tree_entry_interesting_1(entry, base, base_offset, ps, 0);
+ if (ps->magic & PATHSPEC_NEGATE) {
+ next_ret = tree_entry_interesting_1(entry, base, base_offset, ps, 1);
+ switch (next_ret) {
+ case 2: ret = -1; break;
+ case 1: ret = 0; break;
+ default: break;
+ }
+ }
+ return ret;
+}
--
1.7.3.1.256.g2539c.dirty
next prev parent reply other threads:[~2011-10-11 22:45 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-10-11 22:44 [PATCH 0/6] Negation magic pathspec Nguyễn Thái Ngọc Duy
2011-10-11 22:44 ` [PATCH 1/6] Recognize magic pathspec as filenames Nguyễn Thái Ngọc Duy
2011-10-12 20:49 ` Junio C Hamano
2011-10-13 4:23 ` Nguyen Thai Ngoc Duy
2011-10-13 6:06 ` Junio C Hamano
2011-10-11 22:44 ` [PATCH 2/6] Replace has_wildcard with PATHSPEC_NOGLOB Nguyễn Thái Ngọc Duy
2011-10-11 22:44 ` [PATCH 3/6] Convert prefix_pathspec() to produce struct pathspec_item Nguyễn Thái Ngọc Duy
2011-10-11 22:44 ` [PATCH 4/6] Implement parse_pathspec() Nguyễn Thái Ngọc Duy
2011-10-11 22:44 ` [PATCH 5/6] Convert simple init_pathspec() cases to parse_pathspec() Nguyễn Thái Ngọc Duy
2011-10-13 0:29 ` Junio C Hamano
2011-10-11 22:44 ` Nguyễn Thái Ngọc Duy [this message]
2011-10-11 23:17 ` [PATCH 0/6] Negation magic pathspec Junio C Hamano
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1318373083-13840-7-git-send-email-pclouds@gmail.com \
--to=pclouds@gmail.com \
--cc=git@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).