summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Pitre <nico@cam.org>2005-04-28 18:44:04 (GMT)
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-28 18:44:04 (GMT)
commit9ff768e9408b2afac5dbb484eb5c301312bdee80 (patch)
tree8b1c0cc74e6300e00b1578332c12180195dd1daa
parentb836825b55d59ea3dde5c495cc03ff9343c2b485 (diff)
downloadgit-9ff768e9408b2afac5dbb484eb5c301312bdee80.zip
git-9ff768e9408b2afac5dbb484eb5c301312bdee80.tar.gz
git-9ff768e9408b2afac5dbb484eb5c301312bdee80.tar.bz2
[PATCH] Give show-files the ability to process exclusion pattern.
This can be used with the famous dontdiff file as follows to find out about uncommitted files just like dontdiff is used with the diff command: show-files --others --exclude-from=dontdiff and the exclude list can be reversed with the --ignore switch. Signed-off-by: Nicolas Pitre <nico@cam.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--show-files.c105
1 files changed, 97 insertions, 8 deletions
diff --git a/show-files.c b/show-files.c
index afeb635..9bb8fdb 100644
--- a/show-files.c
+++ b/show-files.c
@@ -6,6 +6,7 @@
* Copyright (C) Linus Torvalds, 2005
*/
#include <dirent.h>
+#include <fnmatch.h>
#include "cache.h"
@@ -17,6 +18,70 @@ static int show_stage = 0;
static int show_unmerged = 0;
static int line_terminator = '\n';
+static int nr_excludes;
+static const char **excludes;
+static int excludes_alloc;
+
+static void add_exclude(const char *string)
+{
+ if (nr_excludes == excludes_alloc) {
+ excludes_alloc = alloc_nr(excludes_alloc);
+ excludes = realloc(excludes, excludes_alloc*sizeof(char *));
+ }
+ excludes[nr_excludes++] = string;
+}
+
+static void add_excludes_from_file(const char *fname)
+{
+ int fd, i;
+ long size;
+ char *buf, *entry;
+
+ fd = open(fname, O_RDONLY);
+ if (fd < 0)
+ goto err;
+ size = lseek(fd, 0, SEEK_END);
+ if (size < 0)
+ goto err;
+ lseek(fd, 0, SEEK_SET);
+ if (size == 0) {
+ close(fd);
+ return;
+ }
+ buf = xmalloc(size);
+ if (read(fd, buf, size) != size)
+ goto err;
+ close(fd);
+
+ entry = buf;
+ for (i = 0; i < size; i++) {
+ if (buf[i] == '\n') {
+ if (entry != buf + i) {
+ buf[i] = 0;
+ add_exclude(entry);
+ }
+ entry = buf + i + 1;
+ }
+ }
+ return;
+
+err: perror(fname);
+ exit(1);
+}
+
+static int excluded(const char *pathname)
+{
+ int i;
+ if (nr_excludes) {
+ const char *basename = strrchr(pathname, '/');
+ basename = (basename) ? basename+1 : pathname;
+ for (i = 0; i < nr_excludes; i++)
+ if (fnmatch(excludes[i], basename, 0) == 0)
+ return 1;
+ }
+ return 0;
+}
+
static const char **dir;
static int nr_dir;
static int dir_alloc;
@@ -59,6 +124,8 @@ static void read_directory(const char *path, const char *base, int baselen)
if (de->d_name[0] == '.')
continue;
+ if (excluded(de->d_name) != show_ignored)
+ continue;
len = strlen(de->d_name);
memcpy(fullname + baselen, de->d_name, len+1);
@@ -101,17 +168,17 @@ static void show_files(void)
int i;
/* For cached/deleted files we don't need to even do the readdir */
- if (show_others | show_ignored) {
+ if (show_others) {
read_directory(".", "", 0);
qsort(dir, nr_dir, sizeof(char *), cmp_name);
- }
- if (show_others) {
for (i = 0; i < nr_dir; i++)
printf("%s%c", dir[i], line_terminator);
}
if (show_cached | show_stage) {
for (i = 0; i < active_nr; i++) {
struct cache_entry *ce = active_cache[i];
+ if (excluded(ce->name) != show_ignored)
+ continue;
if (show_unmerged && !ce_stage(ce))
continue;
if (!show_stage)
@@ -130,14 +197,13 @@ static void show_files(void)
for (i = 0; i < active_nr; i++) {
struct cache_entry *ce = active_cache[i];
struct stat st;
+ if (excluded(ce->name) != show_ignored)
+ continue;
if (!stat(ce->name, &st))
continue;
printf("%s%c", ce->name, line_terminator);
}
}
- if (show_ignored) {
- /* We don't have any "ignore" list yet */
- }
}
int main(int argc, char **argv)
@@ -179,11 +245,34 @@ int main(int argc, char **argv)
continue;
}
- usage("show-files [-z] (--[cached|deleted|others|ignored|stage])*");
+ if (!strcmp(arg, "-x") && i+1 < argc) {
+ add_exclude(argv[++i]);
+ continue;
+ }
+ if (!strncmp(arg, "--exclude=", 10)) {
+ add_exclude(arg+10);
+ continue;
+ }
+ if (!strcmp(arg, "-X") && i+1 < argc) {
+ add_excludes_from_file(argv[++i]);
+ continue;
+ }
+ if (!strncmp(arg, "--exclude-from=", 15)) {
+ add_excludes_from_file(arg+15);
+ continue;
+ }
+
+ usage("show-files [-z] (--[cached|deleted|others|stage])* "
+ "[ --ignored [--exclude=<pattern>] [--exclude-from=<file>) ]");
+ }
+
+ if (show_ignored && !nr_excludes) {
+ fprintf(stderr, "%s: --ignored needs some exclude pattern\n", argv[0]);
+ exit(1);
}
/* With no flags, we default to showing the cached files */
- if (!(show_stage | show_deleted | show_others | show_ignored | show_unmerged))
+ if (!(show_stage | show_deleted | show_others | show_unmerged))
show_cached = 1;
read_cache();