From: Nguyen Thai Ngoc Duy <pclouds@gmail.com>
To: Kevin Ballard <kevin@sb.org>
Cc: Git Mailing List <git@vger.kernel.org>
Subject: Re: [PROPOSAL] .gitignore syntax modification
Date: Wed, 13 Oct 2010 19:15:52 +0700 [thread overview]
Message-ID: <20101013121552.GA29486@do> (raw)
In-Reply-To: <F06C63D1-26AE-4278-96CE-2F6B2D6DD300@sb.org>
[-- Attachment #1: Type: text/plain, Size: 1202 bytes --]
On Tue, Oct 12, 2010 at 07:32:54PM -0700, Kevin Ballard wrote:
> As soon as I find the time, I'll be working on a patch for this. I
> only wrote up the proposal because I want to make sure that what I
> end up implementing is actually something that will be accepted. At
> this point I'm actually in favor of simply assuming all paths that
> don't start with / can be matched at any level but I recognize that
> this is a change to existing functionality, though I personally
> think that all patterns that are meant to match only at the current
> level should be prefixed with / anyway. Would such a change to
> existing behavior be rejected out-of-hand?
Yes, patterns that only match current level should be prefixed with a
slash. There are also other cases apart from "current level only" and
"any level": foo/a* will match only second level, not any level.
I was thinking of doing like this. It's not complete (not even build)
but it shows the idea. I don't think this way it will change existing
behaviors. Performance is something I haven't thought through.
Anyway, what do you think? I'm afraid I don't have time to work on
this. The pathspec unification work still needs to be done.
--
Duy
[-- Attachment #2: 0001-excluded_from_list-split-the-core-exclude-code-out-a.patch --]
[-- Type: text/plain, Size: 4039 bytes --]
>From 058ed97a52a3a155655193d0ecd94506781c93c1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nguy=E1=BB=85n=20Th=C3=A1i=20Ng=E1=BB=8Dc=20Duy?= <pclouds@gmail.com>
Date: Wed, 13 Oct 2010 19:01:11 +0700
Subject: [PATCH 1/3] excluded_from_list: split the core exclude code out as a separate function
---
dir.c | 114 ++++++++++++++++++++++++++++++++++------------------------------
1 files changed, 61 insertions(+), 53 deletions(-)
diff --git a/dir.c b/dir.c
index a44c7b3..56974e5 100644
--- a/dir.c
+++ b/dir.c
@@ -343,6 +343,64 @@ static void prep_exclude(struct dir_struct *dir, const char *base, int baselen)
dir->basebuf[baselen] = '\0';
}
+static int excluded_from_list_1(const char *pathname, int pathlen, const char *basename, struct exclude *x, int *dtype)
+{
+ const char *exclude = x->pattern;
+ int to_exclude = x->to_exclude;
+
+ if (x->flags & EXC_FLAG_MUSTBEDIR) {
+ if (!dtype) {
+ if (!prefixcmp(pathname, exclude))
+ return to_exclude;
+ else
+ return -1;
+ }
+ if (*dtype == DT_UNKNOWN)
+ *dtype = get_dtype(NULL, pathname, pathlen);
+ if (*dtype != DT_DIR)
+ return -1;
+ }
+
+ if (x->flags & EXC_FLAG_NODIR) {
+ /* match basename */
+ if (x->flags & EXC_FLAG_NOWILDCARD) {
+ if (!strcmp(exclude, basename))
+ return to_exclude;
+ } else if (x->flags & EXC_FLAG_ENDSWITH) {
+ if (x->patternlen - 1 <= pathlen &&
+ !strcmp(exclude + 1, pathname + pathlen - x->patternlen + 1))
+ return to_exclude;
+ } else {
+ if (fnmatch(exclude, basename, 0) == 0)
+ return to_exclude;
+ }
+ }
+ else {
+ /* match with FNM_PATHNAME:
+ * exclude has base (baselen long) implicitly
+ * in front of it.
+ */
+ int baselen = x->baselen;
+ if (*exclude == '/')
+ exclude++;
+
+ if (pathlen < baselen ||
+ (baselen && pathname[baselen-1] != '/') ||
+ strncmp(pathname, x->base, baselen))
+ return -1;
+
+ if (x->flags & EXC_FLAG_NOWILDCARD) {
+ if (!strcmp(exclude, pathname + baselen))
+ return to_exclude;
+ } else {
+ if (fnmatch(exclude, pathname+baselen,
+ FNM_PATHNAME) == 0)
+ return to_exclude;
+ }
+ }
+ return -1;
+}
+
/* Scan the list and let the last match determine the fate.
* Return 1 for exclude, 0 for include and -1 for undecided.
*/
@@ -355,59 +413,9 @@ int excluded_from_list(const char *pathname,
if (el->nr) {
for (i = el->nr - 1; 0 <= i; i--) {
struct exclude *x = el->excludes[i];
- const char *exclude = x->pattern;
- int to_exclude = x->to_exclude;
-
- if (x->flags & EXC_FLAG_MUSTBEDIR) {
- if (!dtype) {
- if (!prefixcmp(pathname, exclude))
- return to_exclude;
- else
- continue;
- }
- if (*dtype == DT_UNKNOWN)
- *dtype = get_dtype(NULL, pathname, pathlen);
- if (*dtype != DT_DIR)
- continue;
- }
-
- if (x->flags & EXC_FLAG_NODIR) {
- /* match basename */
- if (x->flags & EXC_FLAG_NOWILDCARD) {
- if (!strcmp(exclude, basename))
- return to_exclude;
- } else if (x->flags & EXC_FLAG_ENDSWITH) {
- if (x->patternlen - 1 <= pathlen &&
- !strcmp(exclude + 1, pathname + pathlen - x->patternlen + 1))
- return to_exclude;
- } else {
- if (fnmatch(exclude, basename, 0) == 0)
- return to_exclude;
- }
- }
- else {
- /* match with FNM_PATHNAME:
- * exclude has base (baselen long) implicitly
- * in front of it.
- */
- int baselen = x->baselen;
- if (*exclude == '/')
- exclude++;
-
- if (pathlen < baselen ||
- (baselen && pathname[baselen-1] != '/') ||
- strncmp(pathname, x->base, baselen))
- continue;
-
- if (x->flags & EXC_FLAG_NOWILDCARD) {
- if (!strcmp(exclude, pathname + baselen))
- return to_exclude;
- } else {
- if (fnmatch(exclude, pathname+baselen,
- FNM_PATHNAME) == 0)
- return to_exclude;
- }
- }
+ int to_exclude = excluded_from_list_1(pathname, pathlen, basename, x, dtype);
+ if (to_exclude != -1)
+ return to_exclude;
}
}
return -1; /* undecided */
--
1.7.0.2.445.gcbdb3
[-- Attachment #3: 0002-Set-EXC_FLAG_STARSTAR-if-a-pattern-starts-with.patch --]
[-- Type: text/plain, Size: 1335 bytes --]
>From afa6ef0ee1a299aef486367792f6dcc6e4e686d5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nguy=E1=BB=85n=20Th=C3=A1i=20Ng=E1=BB=8Dc=20Duy?= <pclouds@gmail.com>
Date: Wed, 13 Oct 2010 19:10:35 +0700
Subject: [PATCH 2/3] Set EXC_FLAG_STARSTAR if a pattern starts with "**/"
---
dir.c | 8 ++++++--
1 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/dir.c b/dir.c
index 56974e5..241fbce 100644
--- a/dir.c
+++ b/dir.c
@@ -171,6 +171,10 @@ void add_exclude(const char *string, const char *base,
to_exclude = 0;
string++;
}
+ if (*string == '*' && string[1] == '*' && string[2] == '/') {
+ flags |= EXC_FLAG_STARSTAR;
+ string += 3;
+ }
len = strlen(string);
if (len && string[len - 1] == '/') {
char *s;
@@ -180,7 +184,7 @@ void add_exclude(const char *string, const char *base,
s[len - 1] = '\0';
string = s;
x->pattern = s;
- flags = EXC_FLAG_MUSTBEDIR;
+ flags |= EXC_FLAG_MUSTBEDIR;
} else {
x = xmalloc(sizeof(*x));
x->pattern = string;
@@ -190,7 +194,7 @@ void add_exclude(const char *string, const char *base,
x->base = base;
x->baselen = baselen;
x->flags = flags;
- if (!strchr(string, '/'))
+ if (!(x->flags & EXC_FLAG_STARSTAR) && !strchr(string, '/'))
x->flags |= EXC_FLAG_NODIR;
if (no_wildcard(string))
x->flags |= EXC_FLAG_NOWILDCARD;
--
1.7.0.2.445.gcbdb3
[-- Attachment #4: 0003-excluded_from_list-support-EXC_FLAG_STARSTAR.patch --]
[-- Type: text/plain, Size: 1371 bytes --]
>From c11a949328b90aca3398f730a50eab35033f0334 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nguy=E1=BB=85n=20Th=C3=A1i=20Ng=E1=BB=8Dc=20Duy?= <pclouds@gmail.com>
Date: Wed, 13 Oct 2010 19:06:07 +0700
Subject: [PATCH 3/3] excluded_from_list: support EXC_FLAG_STARSTAR
if that flag is set, try to match all full pathname, then skip one
directory and try again until it completely fails.
---
dir.c | 20 +++++++++++++++++---
1 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/dir.c b/dir.c
index 241fbce..11c3e7d 100644
--- a/dir.c
+++ b/dir.c
@@ -417,9 +417,23 @@ int excluded_from_list(const char *pathname,
if (el->nr) {
for (i = el->nr - 1; 0 <= i; i--) {
struct exclude *x = el->excludes[i];
- int to_exclude = excluded_from_list_1(pathname, pathlen, basename, x, dtype);
- if (to_exclude != -1)
- return to_exclude;
+ const char *new_pathname = pathname;
+ int new_pathlen = pathlen;
+
+ while (1) {
+ int to_exclude = excluded_from_list_1(new_pathname, new_pathlen, basename, x, dtype);
+ if (to_exclude != -1)
+ return to_exclude;
+ if (x->flags & EXC_FLAG_STARSTAR) {
+ const char *p = strchr(new_pathname, '/');
+ if (p) {
+ new_pathlen -= p - new_pathname - 1;
+ new_pathname = p + 1;
+ continue;
+ }
+ }
+ break;
+ }
}
}
return -1; /* undecided */
--
1.7.0.2.445.gcbdb3
next prev parent reply other threads:[~2010-10-13 12:16 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-10-08 21:26 [PROPOSAL] .gitignore syntax modification Kevin Ballard
2010-10-08 21:58 ` Maaartin
2010-10-09 0:03 ` Kevin Ballard
2010-10-11 23:46 ` Maaartin
2010-10-13 2:24 ` Nguyen Thai Ngoc Duy
2010-10-13 2:32 ` Kevin Ballard
2010-10-13 2:40 ` Jonathan Nieder
2010-10-13 3:05 ` Kevin Ballard
2010-10-13 16:51 ` Junio C Hamano
2010-10-13 12:15 ` Nguyen Thai Ngoc Duy [this message]
2010-10-15 11:01 ` Kevin Ballard
2010-10-15 12:57 ` Nguyen Thai Ngoc Duy
2010-10-15 20:15 ` Kevin Ballard
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
List information: http://vger.kernel.org/majordomo-info.html
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20101013121552.GA29486@do \
--to=pclouds@gmail.com \
--cc=git@vger.kernel.org \
--cc=kevin@sb.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.
Code repositories for project(s) associated with this public inbox
https://80x24.org/mirrors/git.git
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 read-only IMAP folder(s) and NNTP newsgroup(s).