b8522886a15db861508fb6d03d4d88d6de912a4b
   1#include "cache.h"
   2
   3#define MTIME_CHANGED   0x0001
   4#define CTIME_CHANGED   0x0002
   5#define OWNER_CHANGED   0x0004
   6#define MODE_CHANGED    0x0008
   7#define INODE_CHANGED   0x0010
   8#define DATA_CHANGED    0x0020
   9
  10static int match_stat(struct cache_entry *ce, struct stat *st)
  11{
  12        unsigned int changed = 0;
  13
  14        if (ce->mtime.sec  != (unsigned int)st->st_mtim.tv_sec ||
  15            ce->mtime.nsec != (unsigned int)st->st_mtim.tv_nsec)
  16                changed |= MTIME_CHANGED;
  17        if (ce->ctime.sec  != (unsigned int)st->st_ctim.tv_sec ||
  18            ce->ctime.nsec != (unsigned int)st->st_ctim.tv_nsec)
  19                changed |= CTIME_CHANGED;
  20        if (ce->st_uid != (unsigned int)st->st_uid ||
  21            ce->st_gid != (unsigned int)st->st_gid)
  22                changed |= OWNER_CHANGED;
  23        if (ce->st_mode != (unsigned int)st->st_mode)
  24                changed |= MODE_CHANGED;
  25        if (ce->st_dev != (unsigned int)st->st_dev ||
  26            ce->st_ino != (unsigned int)st->st_ino)
  27                changed |= INODE_CHANGED;
  28        if (ce->st_size != (unsigned int)st->st_size)
  29                changed |= DATA_CHANGED;
  30        return changed;
  31}
  32
  33static void show_differences(struct cache_entry *ce, struct stat *cur,
  34        void *old_contents, unsigned long long old_size)
  35{
  36        static char cmd[1000];
  37        FILE *f;
  38
  39        snprintf(cmd, sizeof(cmd), "diff -u - %s", ce->name);
  40        f = popen(cmd, "w");
  41        fwrite(old_contents, old_size, 1, f);
  42        pclose(f);
  43}
  44
  45int main(int argc, char **argv)
  46{
  47        int entries = read_cache();
  48        int i;
  49
  50        if (entries < 0) {
  51                perror("read_cache");
  52                exit(1);
  53        }
  54        for (i = 0; i < entries; i++) {
  55                struct stat st;
  56                struct cache_entry *ce = active_cache[i];
  57                int n, changed;
  58                unsigned int mode;
  59                unsigned long size;
  60                char type[20];
  61                void *new;
  62
  63                if (stat(ce->name, &st) < 0) {
  64                        printf("%s: %s\n", ce->name, strerror(errno));
  65                        continue;
  66                }
  67                changed = match_stat(ce, &st);
  68                if (!changed) {
  69                        printf("%s: ok\n", ce->name);
  70                        continue;
  71                }
  72                printf("%.*s:  ", ce->namelen, ce->name);
  73                for (n = 0; n < 20; n++)
  74                        printf("%02x", ce->sha1[n]);
  75                printf("\n");
  76                new = read_sha1_file(ce->sha1, type, &size);
  77                show_differences(ce, &st, new, size);
  78                free(new);
  79        }
  80        return 0;
  81}