X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=show-files.c;h=9bb8fdb000588aa61d1b1abb02de5dea79b8625e;hb=0cc087e3044a7ce19d276f736d983ad8344162f6;hp=7d3797f27e7d022d4504e6847b0deea22bac8063;hpb=aebb2679085d2ecc4d1c943ecfb2e87c699f00d0;p=git.git diff --git a/show-files.c b/show-files.c index 7d3797f2..9bb8fdb0 100644 --- a/show-files.c +++ b/show-files.c @@ -6,7 +6,7 @@ * Copyright (C) Linus Torvalds, 2005 */ #include -#include +#include #include "cache.h" @@ -14,6 +14,73 @@ static int show_deleted = 0; static int show_cached = 0; static int show_others = 0; static int show_ignored = 0; +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; @@ -28,9 +95,9 @@ static void add_name(const char *pathname, int len) if (nr_dir == dir_alloc) { dir_alloc = alloc_nr(dir_alloc); - dir = realloc(dir, dir_alloc*sizeof(char *)); + dir = xrealloc(dir, dir_alloc*sizeof(char *)); } - name = malloc(len + 1); + name = xmalloc(len + 1); memcpy(name, pathname, len + 1); dir[nr_dir++] = name; } @@ -57,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); @@ -99,32 +168,42 @@ 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\n", dir[i]); + printf("%s%c", dir[i], line_terminator); } - if (show_cached) { + if (show_cached | show_stage) { for (i = 0; i < active_nr; i++) { struct cache_entry *ce = active_cache[i]; - printf("%s\n", ce->name); + if (excluded(ce->name) != show_ignored) + continue; + if (show_unmerged && !ce_stage(ce)) + continue; + if (!show_stage) + printf("%s%c", ce->name, line_terminator); + else + printf(/* "%06o %s %d %10d %s%c", */ + "%06o %s %d %s%c", + ntohl(ce->ce_mode), + sha1_to_hex(ce->sha1), + ce_stage(ce), + /* ntohl(ce->ce_size), */ + ce->name, line_terminator); } } if (show_deleted) { 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\n", ce->name); + printf("%s%c", ce->name, line_terminator); } } - if (show_ignored) { - /* We don't have any "ignore" list yet */ - } } int main(int argc, char **argv) @@ -134,6 +213,11 @@ int main(int argc, char **argv) for (i = 1; i < argc; i++) { char *arg = argv[i]; + if (!strcmp(arg, "-z")) { + line_terminator = 0; + continue; + } + if (!strcmp(arg, "--cached")) { show_cached = 1; continue; @@ -150,12 +234,45 @@ int main(int argc, char **argv) show_ignored = 1; continue; } + if (!strcmp(arg, "--stage")) { + show_stage = 1; + continue; + } + if (!strcmp(arg, "--unmerged")) { + // There's no point in showing unmerged unless you also show the stage information + show_stage = 1; + show_unmerged = 1; + continue; + } + + 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=] [--exclude-from=) ]"); + } - usage("show-files (--[cached|deleted|others|ignored])*"); + 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_cached | show_deleted | show_others | show_ignored)) + if (!(show_stage | show_deleted | show_others | show_unmerged)) show_cached = 1; read_cache();