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