X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=show-diff.c;h=4557bd82f302eb951e02281a67a84c959122031b;hb=b8a55ce71d0d46204d64fe35787956e994d2a802;hp=a15e9b4cf0be5f67373d08fb5c833dd5c1d3eeb8;hpb=ccc4feb579265266d0a4a73c0c9443ecc0c26ce3;p=git.git diff --git a/show-diff.c b/show-diff.c index a15e9b4c..4557bd82 100644 --- a/show-diff.c +++ b/show-diff.c @@ -5,102 +5,103 @@ */ #include "cache.h" -static void show_differences(char *name, - void *old_contents, unsigned long long old_size) -{ - static char cmd[1000]; - FILE *f; +static const char *show_diff_usage = "show-diff [-q] [-s] [-z] [paths...]"; - snprintf(cmd, sizeof(cmd), "diff -L %s -u -N - %s", name, name); - f = popen(cmd, "w"); - if (old_size) - fwrite(old_contents, old_size, 1, f); - pclose(f); -} +static int recursive = 0; +static int line_termination = '\n'; +static int silent = 0; +static int silent_on_nonexisting_files = 0; -static void show_diff_empty(struct cache_entry *ce) +static int matches_pathspec(struct cache_entry *ce, char **spec, int cnt) { - char *old; - unsigned long int size; - int lines=0; - unsigned char type[20], *p, *end; - - old = read_sha1_file(ce->sha1, type, &size); - if (size > 0) { - int startline = 1; - int c = 0; - - printf("--- %s\n", ce->name); - printf("+++ /dev/null\n"); - p = old; - end = old + size; - while (p < end) - if (*p++ == '\n') - lines ++; - printf("@@ -1,%d +0,0 @@\n", lines); - p = old; - while (p < end) { - c = *p++; - if (startline) { - putchar('-'); - startline = 0; - } - putchar(c); - if (c == '\n') - startline = 1; - } - if (c!='\n') - printf("\n"); - fflush(stdout); + int i; + int namelen = ce_namelen(ce); + for (i = 0; i < cnt; i++) { + int speclen = strlen(spec[i]); + if (! strncmp(spec[i], ce->name, speclen) && + speclen <= namelen && + (ce->name[speclen] == 0 || + ce->name[speclen] == '/')) + return 1; } + return 0; +} + +static void show_file(const char *prefix, struct cache_entry *ce) +{ + printf("%s%o\t%s\t%s\t%s%c", prefix, ntohl(ce->ce_mode), "blob", + sha1_to_hex(ce->sha1), ce->name, line_termination); } int main(int argc, char **argv) { - int silent = 0; + static const char null_sha1_hex[] = "0000000000000000000000000000000000000000"; int entries = read_cache(); int i; - while (argc-- > 1) { - if (!strcmp(argv[1], "-s")) { - silent = 1; - continue; - } - usage("show-diff [-s]"); + while (1 < argc && argv[1][0] == '-') { + if (!strcmp(argv[1], "-s")) + silent_on_nonexisting_files = silent = 1; + else if (!strcmp(argv[1], "-q")) + silent_on_nonexisting_files = 1; + else if (!strcmp(argv[1], "-z")) + line_termination = 0; + else if (!strcmp(argv[1], "-r")) + recursive = 1; /* No-op */ + else + usage(show_diff_usage); + argv++; argc--; } + /* At this point, if argc == 1, then we are doing everything. + * Otherwise argv[1] .. argv[argc-1] have the explicit paths. + */ if (entries < 0) { perror("read_cache"); exit(1); } + for (i = 0; i < entries; i++) { struct stat st; + unsigned int oldmode, mode; struct cache_entry *ce = active_cache[i]; - int n, changed; - unsigned long size; - char type[20]; - void *new; + int changed; + + if (1 < argc && + ! matches_pathspec(ce, argv+1, argc-1)) + continue; + if (ce_stage(ce)) { + printf("U %s%c", ce->name, line_termination); + + while (i < entries && + !strcmp(ce->name, active_cache[i]->name)) + i++; + i--; /* compensate for loop control increments */ + continue; + } + if (stat(ce->name, &st) < 0) { - printf("%s: %s\n", ce->name, strerror(errno)); - if (errno == ENOENT && !silent) - show_diff_empty(ce); + if (errno != ENOENT) { + perror(ce->name); + continue; + } + if (silent_on_nonexisting_files) + continue; + show_file("-", ce); continue; } changed = cache_match_stat(ce, &st); if (!changed) continue; - printf("%.*s: ", ce_namelen(ce), ce->name); - for (n = 0; n < 20; n++) - printf("%02x", ce->sha1[n]); - printf("\n"); - fflush(stdout); - if (silent) - continue; - new = read_sha1_file(ce->sha1, type, &size); - show_differences(ce->name, new, size); - free(new); + oldmode = ntohl(ce->ce_mode); + mode = S_IFREG | ce_permissions(st.st_mode); + + printf("*%o->%o\t%s\t%s->%s\t%s%c", + oldmode, mode, "blob", + sha1_to_hex(ce->sha1), null_sha1_hex, + ce->name, line_termination); } return 0; }