From: Junio C Hamano <gitster@pobox.com>
To: Joe Perches <joe@perches.com>
Cc: git@vger.kernel.org
Subject: Re: [PATCH] git-apply - Add --include=PATH
Date: Mon, 25 Aug 2008 01:05:31 -0700 [thread overview]
Message-ID: <7vhc99h644.fsf@gitster.siamese.dyndns.org> (raw)
In-Reply-To: 1219615063.18365.141.camel@localhost
Joe Perches <joe@perches.com> writes:
>> > @@ -2996,10 +2996,16 @@ static struct excludes {
>> > const char *path;
>> > } *excludes;
>> >
>> > +static struct includes {
>> > + struct includes *next;
>> > + const char *path;
>> > +} *includes;
>>
>> Now this is ugly. You can just add a new variable "*includes" that is of
>> exactly the same type as existing "*excludes" without introducing a new
>> type.
>
> Yes, it's slightly ugly, but it was less work and much easier for
> a human to parse.
Another consideration is what should happen when you give contradicting
excludes and includes list. For example, it is very plausible you might
want to say "apply to all but header files, except that you want the part
to one specific header file to also get applied). Something like:
$ git apply --include='specific-one.h' --exclude='*.h' --include='*' <patch
It is easy to declare that all the exclude patterns are processed and used
to reject paths, and then only after that include patterns, if any, are
used to limit the remainder. But that is describing how the code does it,
and may not match what the users expect. For example, the users would
expect:
$ git apply --include='specific-one.h' --exclude='s*' <patch
to apply the part for "specific-one.h" but no other paths that begin with "s".
However, that is not what happens.
It would be much easier to explain to the end users if the rule were that
include and exclude patterns are examined in the order they are specified
on the command line, and the first match determines the each path's fate.
In order to support that, you do not want two separate lists. Instead,
you would want to keep a single "static struct string_list limit_by_name",
append both excluded and included items to the list as you encounter with
string_list_append(), but in such a way that you can distinguish which one
is which later. Also remember if you have seen any included item.
Then your use_patch() would:
* first check and ignore patches about paths outside of the prefix if any
is specified via --directory;
* loop over the limit_by_name.items[] array, checking the path with each
element in it with fnmatch(). If you find a match, then you know if it
is excluded (return 0) or included (return 1);
* if no patterns match, return 1 (i.e. modify this path) if you did not
see any "include" pattern. If you had any "include" pattern on the
command line, return 0 (i.e. do not modify this path).
Perhaps something like this, but I did not test it.
builtin-apply.c | 48 +++++++++++++++++++++++++++++++++---------------
1 files changed, 33 insertions(+), 15 deletions(-)
diff --git c/builtin-apply.c w/builtin-apply.c
index 2216a0b..967ebec 100644
--- c/builtin-apply.c
+++ w/builtin-apply.c
@@ -2991,29 +2991,45 @@ static int write_out_results(struct patch *list, int skipped_patch)
static struct lock_file lock_file;
-static struct excludes {
- struct excludes *next;
- const char *path;
-} *excludes;
+static struct string_list limit_by_name;
+static int has_include;
+static void add_name_limit(const char *name, int exclude)
+{
+ struct string_list_item *it;
+
+ it = string_list_append(name, &limit_by_name);
+ it->util = exclude ? NULL : (void *) 1;
+}
static int use_patch(struct patch *p)
{
const char *pathname = p->new_name ? p->new_name : p->old_name;
- struct excludes *x = excludes;
- while (x) {
- if (fnmatch(x->path, pathname, 0) == 0)
- return 0;
- x = x->next;
- }
+ int i;
+
+ /* Paths outside are not touched regardless of "--include" */
if (0 < prefix_length) {
int pathlen = strlen(pathname);
if (pathlen <= prefix_length ||
memcmp(prefix, pathname, prefix_length))
return 0;
}
- return 1;
+
+ /* See if it matches any of exclude/include rule */
+ for (i = 0; i < limit_by_name.nr; i++) {
+ struct string_list_item *it = &limit_by_name.items[i];
+ if (!fnmatch(it->string, pathname, 0))
+ return (it->util != NULL);
+ }
+
+ /*
+ * If we had any include, a path that does not match any rule is
+ * not used. Otherwise, we saw bunch of exclude rules (or none)
+ * and such a path is used.
+ */
+ return !has_include;
}
+
static void prefix_one(char **name)
{
char *old_name = *name;
@@ -3154,10 +3170,12 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix)
continue;
}
if (!prefixcmp(arg, "--exclude=")) {
- struct excludes *x = xmalloc(sizeof(*x));
- x->path = arg + 10;
- x->next = excludes;
- excludes = x;
+ add_name_limit(arg + 10, 1);
+ continue;
+ }
+ if (!prefixcmp(arg, "--include=")) {
+ add_name_limit(arg + 10, 0);
+ has_include = 1;
continue;
}
if (!prefixcmp(arg, "-p")) {
prev parent reply other threads:[~2008-08-25 8:06 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-08-23 20:37 [PATCH] git-apply - Add --include=PATH Joe Perches
2008-08-24 0:54 ` Junio C Hamano
2008-08-24 21:57 ` Joe Perches
2008-08-25 8:05 ` Junio C Hamano [this message]
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=7vhc99h644.fsf@gitster.siamese.dyndns.org \
--to=gitster@pobox.com \
--cc=git@vger.kernel.org \
--cc=joe@perches.com \
/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).