diff-cache.con commit [PATCH] Allow multiple date-ordered lists (58e28af)
   1#include "cache.h"
   2
   3static int cached_only = 0;
   4static int line_termination = '\n';
   5
   6/* A file entry went away or appeared */
   7static void show_file(const char *prefix, struct cache_entry *ce)
   8{
   9        printf("%s%o\t%s\t%s\t%s%c", prefix, ntohl(ce->ce_mode), "blob",
  10               sha1_to_hex(ce->sha1), ce->name, line_termination);
  11}
  12
  13static int show_modified(struct cache_entry *old, struct cache_entry *new)
  14{
  15        unsigned int mode = ntohl(new->ce_mode), oldmode;
  16        unsigned char *sha1 = new->sha1;
  17        unsigned char old_sha1_hex[60];
  18
  19        if (!cached_only) {
  20                static unsigned char no_sha1[20];
  21                int changed;
  22                struct stat st;
  23                if (stat(new->name, &st) < 0) {
  24                        show_file("-", old);
  25                        return -1;
  26                }
  27                changed = cache_match_stat(new, &st);
  28                if (changed) {
  29                        mode = st.st_mode;
  30                        sha1 = no_sha1;
  31                }
  32        }
  33
  34        oldmode = ntohl(old->ce_mode);
  35        if (mode == oldmode && !memcmp(sha1, old->sha1, 20))
  36                return 0;
  37
  38        strcpy(old_sha1_hex, sha1_to_hex(old->sha1));
  39        printf("*%o->%o\t%s\t%s->%s\t%s%c", oldmode, mode,
  40               "blob",
  41               old_sha1_hex, sha1_to_hex(sha1),
  42               old->name, line_termination);
  43        return 0;
  44}
  45
  46static int diff_cache(struct cache_entry **ac, int entries)
  47{
  48        while (entries) {
  49                struct cache_entry *ce = *ac;
  50
  51                /* No matching 0-stage (current) entry? Show it as deleted */
  52                if (ce_stage(ce)) {
  53                        show_file("-", ce);
  54                        ac++;
  55                        entries--;
  56                        continue;
  57                }
  58                /* No matching 1-stage (tree) entry? Show the current one as added */
  59                if (entries == 1 || !same_name(ce, ac[1])) {
  60                        show_file("+", ce);
  61                        ac++;
  62                        entries--;
  63                        continue;
  64                }
  65                show_modified(ac[1], ce);
  66                ac += 2;
  67                entries -= 2;
  68                continue;
  69        }
  70        return 0;
  71}
  72
  73static void remove_merge_entries(void)
  74{
  75        int i;
  76        for (i = 0; i < active_nr; i++) {
  77                struct cache_entry *ce = active_cache[i];
  78                if (!ce_stage(ce))
  79                        break;
  80                printf("%s: unmerged\n", ce->name);
  81                while (remove_entry_at(i)) {
  82                        if (!ce_stage(active_cache[i]))
  83                                break;
  84                }
  85        }
  86}
  87
  88static char *diff_cache_usage = "diff-cache [-r] [-z] [--cached] <tree sha1>";
  89
  90int main(int argc, char **argv)
  91{
  92        unsigned char tree_sha1[20];
  93        void *tree;
  94        unsigned long size;
  95
  96        read_cache();
  97        while (argc > 2) {
  98                char *arg = argv[1];
  99                argv++;
 100                argc--;
 101                if (!strcmp(arg, "-r")) {
 102                        /* We accept the -r flag just to look like diff-tree */
 103                        continue;
 104                }
 105                if (!strcmp(arg, "-z")) {
 106                        line_termination = '\0';
 107                        continue;
 108                }
 109                if (!strcmp(arg, "--cached")) {
 110                        cached_only = 1;
 111                        continue;
 112                }
 113                usage(diff_cache_usage);
 114        }
 115
 116        if (argc != 2 || get_sha1_hex(argv[1], tree_sha1))
 117                usage(diff_cache_usage);
 118
 119        remove_merge_entries();
 120
 121        tree = read_tree_with_tree_or_commit_sha1(tree_sha1, &size, 0);
 122        if (!tree)
 123                die("bad tree object %s", argv[1]);
 124        if (read_tree(tree, size, 1))
 125                die("unable to read tree object %s", argv[1]);
 126
 127        return diff_cache(active_cache, active_nr);
 128}