Add "merge-tree" helper program. Maybe it's retarded, maybe it's helpful.
[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("+++ /dev/null\n");
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 silent = 0;
61         int entries = read_cache();
62         int i;
63
64         while (argc-- > 1) {
65                 if (!strcmp(argv[1], "-s")) {
66                         silent = 1;
67                         continue;
68                 }
69                 usage("show-diff [-s]");
70         }
71
72         if (entries < 0) {
73                 perror("read_cache");
74                 exit(1);
75         }
76         for (i = 0; i < entries; i++) {
77                 struct stat st;
78                 struct cache_entry *ce = active_cache[i];
79                 int n, changed;
80                 unsigned long size;
81                 char type[20];
82                 void *new;
83
84                 if (stat(ce->name, &st) < 0) {
85                         printf("%s: %s\n", ce->name, strerror(errno));
86                         if (errno == ENOENT && !silent)
87                                 show_diff_empty(ce);
88                         continue;
89                 }
90                 changed = cache_match_stat(ce, &st);
91                 if (!changed)
92                         continue;
93                 printf("%.*s:  ", ce->namelen, ce->name);
94                 for (n = 0; n < 20; n++)
95                         printf("%02x", ce->sha1[n]);
96                 printf("\n");
97                 fflush(stdout);
98                 if (silent)
99                         continue;
100
101                 new = read_sha1_file(ce->sha1, type, &size);
102                 show_differences(ce->name, new, size);
103                 free(new);
104         }
105         return 0;
106 }