[PATCH] Fix a crash when doing rev-tree
[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 static void show_differences(char *name, 
9         void *old_contents, unsigned long long old_size)
10 {
11         static char cmd[1000];
12         FILE *f;
13
14         snprintf(cmd, sizeof(cmd), "diff -L %s -u -N  - %s", name, name);
15         f = popen(cmd, "w");
16         if (old_size)
17                 fwrite(old_contents, old_size, 1, f);
18         pclose(f);
19 }
20
21 static void show_diff_empty(struct cache_entry *ce)
22 {
23         char *old;
24         unsigned long int size;
25         int lines=0;
26         unsigned char type[20], *p, *end;
27
28         old = read_sha1_file(ce->sha1, type, &size);
29         if (size > 0) {
30                 int startline = 1;
31                 int c = 0;
32
33                 printf("--- %s\n", ce->name);
34                 printf("+++ %s\n", ce->name);
35                 p = old;
36                 end = old + size; 
37                 while (p < end)
38                         if (*p++ == '\n')
39                                 lines ++;
40                 printf("@@ -1,%d +0,0 @@\n", lines);
41                 p = old;
42                 while (p < end) {
43                         c = *p++;
44                         if (startline) {
45                                 putchar('-');
46                                 startline = 0;
47                         } 
48                         putchar(c);
49                         if (c == '\n')
50                                 startline = 1;
51                 }
52                 if (c!='\n')
53                         printf("\n");
54                 fflush(stdout);
55         }
56 }
57
58 int main(int argc, char **argv)
59 {
60         int entries = read_cache();
61         int i;
62
63         if (entries < 0) {
64                 perror("read_cache");
65                 exit(1);
66         }
67         for (i = 0; i < entries; i++) {
68                 struct stat st;
69                 struct cache_entry *ce = active_cache[i];
70                 int n, changed;
71                 unsigned long size;
72                 char type[20];
73                 void *new;
74
75                 if (stat(ce->name, &st) < 0) {
76                         printf("%s: %s\n", ce->name, strerror(errno));
77                         if (errno ==  ENOENT)
78                                 show_diff_empty(ce);
79                         continue;
80                 }
81                 changed = cache_match_stat(ce, &st);
82                 if (!changed)
83                         continue;
84                 printf("%.*s:  ", ce->namelen, ce->name);
85                 for (n = 0; n < 20; n++)
86                         printf("%02x", ce->sha1[n]);
87                 printf("\n");
88                 fflush(stdout);
89                 new = read_sha1_file(ce->sha1, type, &size);
90                 show_differences(ce->name, new, size);
91                 free(new);
92         }
93         return 0;
94 }