From: Junio C Hamano <junkio@cox.net>
To: Petr Baudis <pasky@suse.cz>
Cc: Catalin Marinas <catalin.marinas@gmail.com>,
Linus Torvalds <torvalds@osdl.org>,
git@vger.kernel.org, Marco Costalba <mcostalba@yahoo.it>
Subject: [PATCH] ls-files: rework exclude patterns.
Date: Fri, 29 Jul 2005 00:50:34 -0700 [thread overview]
Message-ID: <7vhdeejbjp.fsf_-_@assigned-by-dhcp.cox.net> (raw)
In-Reply-To: <7vack6mcd7.fsf@assigned-by-dhcp.cox.net> (Junio C. Hamano's message of "Thu, 28 Jul 2005 22:04:36 -0700")
Pasky and others raised many valid points on the problems
initial exclude pattern enhancement work had. Based on the
list discussion, rework the exclude logic to use "last match
determines its fate" rule, and order the list by exclude-from
(the fallback default pattern file), exclude-per-directory
(shallower to deeper, so deeper ones can override), and then
command line exclude patterns.
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
ls-files.c | 100 +++++++++++++++++++++++++++++++++++++++++++-----------------
1 files changed, 72 insertions(+), 28 deletions(-)
a908ed1b0fed52bfdcfc8b3ada366ce05e44c887
diff --git a/ls-files.c b/ls-files.c
--- a/ls-files.c
+++ b/ls-files.c
@@ -26,30 +26,45 @@ static const char *tag_other = "";
static const char *tag_killed = "";
static char *exclude_per_dir = NULL;
-static int nr_excludes;
-static int excludes_alloc;
-static struct exclude {
- const char *pattern;
- const char *base;
- int baselen;
-} **excludes;
-static void add_exclude(const char *string, const char *base, int baselen)
+/* We maintain three exclude pattern lists:
+ * EXC_CMDL lists patterns explicitly given on the command line.
+ * EXC_DIRS lists patterns obtained from per-directory ignore files.
+ * EXC_FILE lists patterns from fallback ignore files.
+ */
+#define EXC_CMDL 0
+#define EXC_DIRS 1
+#define EXC_FILE 2
+static struct exclude_list {
+ int nr;
+ int alloc;
+ struct exclude {
+ const char *pattern;
+ const char *base;
+ int baselen;
+ } **excludes;
+} exclude_list[3];
+
+static void add_exclude(const char *string, const char *base,
+ int baselen, struct exclude_list *which)
{
struct exclude *x = xmalloc(sizeof (*x));
x->pattern = string;
x->base = base;
x->baselen = baselen;
- if (nr_excludes == excludes_alloc) {
- excludes_alloc = alloc_nr(excludes_alloc);
- excludes = realloc(excludes, excludes_alloc*sizeof(char *));
+ if (which->nr == which->alloc) {
+ which->alloc = alloc_nr(which->alloc);
+ which->excludes = realloc(which->excludes,
+ which->alloc * sizeof(x));
}
- excludes[nr_excludes++] = x;
+ which->excludes[which->nr++] = x;
}
static int add_excludes_from_file_1(const char *fname,
- const char *base, int baselen)
+ const char *base,
+ int baselen,
+ struct exclude_list *which)
{
int fd, i;
long size;
@@ -76,7 +91,7 @@ static int add_excludes_from_file_1(cons
if (buf[i] == '\n') {
if (entry != buf + i && entry[0] != '#') {
buf[i] = 0;
- add_exclude(entry, base, baselen);
+ add_exclude(entry, base, baselen, which);
}
entry = buf + i + 1;
}
@@ -91,38 +106,45 @@ static int add_excludes_from_file_1(cons
static void add_excludes_from_file(const char *fname)
{
- if (add_excludes_from_file_1(fname, "", 0) < 0)
+ if (add_excludes_from_file_1(fname, "", 0,
+ &exclude_list[EXC_FILE]) < 0)
die("cannot use %s as an exclude file", fname);
}
static int push_exclude_per_directory(const char *base, int baselen)
{
char exclude_file[PATH_MAX];
- int current_nr = nr_excludes;
+ struct exclude_list *el = &exclude_list[EXC_DIRS];
+ int current_nr = el->nr;
if (exclude_per_dir) {
memcpy(exclude_file, base, baselen);
strcpy(exclude_file + baselen, exclude_per_dir);
- add_excludes_from_file_1(exclude_file, base, baselen);
+ add_excludes_from_file_1(exclude_file, base, baselen, el);
}
return current_nr;
}
static void pop_exclude_per_directory(int stk)
{
- while (stk < nr_excludes)
- free(excludes[--nr_excludes]);
+ struct exclude_list *el = &exclude_list[EXC_DIRS];
+
+ while (stk < el->nr)
+ free(el->excludes[--el->nr]);
}
-static int excluded(const char *pathname)
+/* Scan the list and let the last match determines the fate.
+ * Return 1 for exclude, 0 for include and -1 for undecided.
+ */
+static int excluded_1(const char *pathname,
+ int pathlen,
+ struct exclude_list *el)
{
int i;
- if (nr_excludes) {
- int pathlen = strlen(pathname);
-
- for (i = 0; i < nr_excludes; i++) {
- struct exclude *x = excludes[i];
+ 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 = 1;
@@ -158,6 +180,22 @@ static int excluded(const char *pathname
}
}
}
+ return -1; /* undecided */
+}
+
+static int excluded(const char *pathname)
+{
+ int pathlen = strlen(pathname);
+ int st;
+
+ for (st = EXC_CMDL; st <= EXC_FILE; st++) {
+ switch (excluded_1(pathname, pathlen, &exclude_list[st])) {
+ case 0:
+ return 0;
+ case 1:
+ return 1;
+ }
+ }
return 0;
}
@@ -371,6 +409,7 @@ static const char *ls_files_usage =
int main(int argc, char **argv)
{
int i;
+ int exc_given = 0;
for (i = 1; i < argc; i++) {
char *arg = argv[i];
@@ -402,20 +441,25 @@ int main(int argc, char **argv)
show_stage = 1;
show_unmerged = 1;
} else if (!strcmp(arg, "-x") && i+1 < argc) {
- add_exclude(argv[++i], "", 0);
+ exc_given = 1;
+ add_exclude(argv[++i], "", 0, &exclude_list[EXC_CMDL]);
} else if (!strncmp(arg, "--exclude=", 10)) {
- add_exclude(arg+10, "", 0);
+ exc_given = 1;
+ add_exclude(arg+10, "", 0, &exclude_list[EXC_CMDL]);
} else if (!strcmp(arg, "-X") && i+1 < argc) {
+ exc_given = 1;
add_excludes_from_file(argv[++i]);
} else if (!strncmp(arg, "--exclude-from=", 15)) {
+ exc_given = 1;
add_excludes_from_file(arg+15);
} else if (!strncmp(arg, "--exclude-per-directory=", 24)) {
+ exc_given = 1;
exclude_per_dir = arg + 24;
} else
usage(ls_files_usage);
}
- if (show_ignored && !nr_excludes) {
+ if (show_ignored && !exc_given) {
fprintf(stderr, "%s: --ignored needs some exclude pattern\n",
argv[0]);
exit(1);
next prev parent reply other threads:[~2005-07-29 7:54 UTC|newest]
Thread overview: 55+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-07-21 20:23 [PATCH 1/1] Tell vim the textwidth is 75 Bryan larsen
2005-07-22 2:50 ` Junio C Hamano
2005-07-22 10:37 ` Catalin Marinas
2005-07-22 19:24 ` Sam Ravnborg
2005-07-22 20:39 ` Junio C Hamano
2005-07-22 20:59 ` Petr Baudis
2005-07-24 22:49 ` [RFC] extending git-ls-files --exclude Junio C Hamano
2005-07-24 22:50 ` [PATCH] git-ls-files: --exclude mechanism updates Junio C Hamano
2005-07-24 22:51 ` [PATCH] Documentation: describe git-ls-files --exclude patterns Junio C Hamano
2005-07-25 9:19 ` [RFC] extending git-ls-files --exclude Catalin Marinas
2005-07-25 19:58 ` Junio C Hamano
2005-07-25 20:09 ` Linus Torvalds
2005-07-25 20:27 ` Junio C Hamano
2005-07-25 20:51 ` Catalin Marinas
2005-07-28 15:57 ` Petr Baudis
2005-07-25 20:59 ` Catalin Marinas
2005-07-28 15:52 ` Petr Baudis
2005-07-28 16:04 ` A Large Angry SCM
2005-07-28 19:25 ` Matthias Urlichs
2005-07-29 7:21 ` Petr Baudis
2005-07-29 7:37 ` Matthias Urlichs
2005-07-29 13:49 ` A Large Angry SCM
2005-07-29 5:04 ` Junio C Hamano
2005-07-29 7:36 ` Petr Baudis
2005-07-29 8:24 ` Junio C Hamano
2005-07-29 8:41 ` Petr Baudis
2005-08-01 16:14 ` Wayne Scott
2005-07-29 7:50 ` Junio C Hamano [this message]
2005-07-29 7:51 ` [PATCH] Documentation and tests: ls-files exclude pattern Junio C Hamano
2005-07-22 21:43 ` [PATCH 1/1] Tell vim the textwidth is 75 Catalin Marinas
2005-07-22 23:07 ` Junio C Hamano
2005-07-23 8:41 ` Catalin Marinas
2005-07-23 9:30 ` Petr Baudis
2005-07-23 10:27 ` Catalin Marinas
2005-07-23 16:33 ` Bryan Larsen
2005-07-23 20:52 ` Catalin Marinas
2005-07-28 19:47 ` Petr Baudis
2005-07-29 2:24 ` Junio C Hamano
2005-07-29 2:59 ` Linus Torvalds
2005-07-29 9:55 ` Catalin Marinas
2005-07-29 11:10 ` Petr Baudis
2005-07-29 12:34 ` Catalin Marinas
2005-07-30 2:11 ` Junio C Hamano
2005-07-23 9:04 ` Petr Baudis
2005-07-24 1:13 ` Junio C Hamano
2005-07-22 21:00 ` Catalin Marinas
2005-07-22 20:41 ` Petr Baudis
2005-07-22 21:16 ` Junio C Hamano
2005-07-22 21:27 ` Petr Baudis
2005-07-22 23:24 ` Junio C Hamano
2005-07-22 23:50 ` Petr Baudis
2005-07-23 10:32 ` Catalin Marinas
2005-07-26 0:18 ` Updating diff-raw status letter to 'A' for added files Junio C Hamano
2005-07-26 0:20 ` [PATCH 1/2] Use symbolic constants for diff-raw status indicators Junio C Hamano
2005-07-26 0:21 ` [PATCH 2/2] diff-raw: Use 'A' instead of 'N' for added files 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=7vhdeejbjp.fsf_-_@assigned-by-dhcp.cox.net \
--to=junkio@cox.net \
--cc=catalin.marinas@gmail.com \
--cc=git@vger.kernel.org \
--cc=mcostalba@yahoo.it \
--cc=pasky@suse.cz \
--cc=torvalds@osdl.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).