]>
Commit | Line | Data |
---|---|---|
be3cfa85 JH |
1 | /* |
2 | * Copyright (C) 2005 Junio C Hamano | |
3 | */ | |
d1df5743 JH |
4 | #include "cache.h" |
5 | #include "strbuf.h" | |
6 | #include "diff.h" | |
7 | ||
91a6eaa0 | 8 | static int matches_pathspec(const char *name, const char **spec, int cnt) |
d1df5743 JH |
9 | { |
10 | int i; | |
11 | int namelen = strlen(name); | |
12 | for (i = 0; i < cnt; i++) { | |
13 | int speclen = strlen(spec[i]); | |
14 | if (! strncmp(spec[i], name, speclen) && | |
15 | speclen <= namelen && | |
16 | (name[speclen] == 0 || | |
17 | name[speclen] == '/')) | |
18 | return 1; | |
19 | } | |
20 | return 0; | |
21 | } | |
22 | ||
be3cfa85 JH |
23 | static int parse_oneside_change(const char *cp, struct diff_spec *one, |
24 | char *path) | |
25 | { | |
d1df5743 | 26 | int ch; |
be3cfa85 JH |
27 | |
28 | one->file_valid = one->sha1_valid = 1; | |
29 | one->mode = 0; | |
30 | while ((ch = *cp) && '0' <= ch && ch <= '7') { | |
31 | one->mode = (one->mode << 3) | (ch - '0'); | |
32 | cp++; | |
33 | } | |
34 | ||
d1df5743 JH |
35 | if (strncmp(cp, "\tblob\t", 6)) |
36 | return -1; | |
37 | cp += 6; | |
be3cfa85 | 38 | if (get_sha1_hex(cp, one->u.sha1)) |
d1df5743 JH |
39 | return -1; |
40 | cp += 40; | |
41 | if (*cp++ != '\t') | |
42 | return -1; | |
43 | strcpy(path, cp); | |
44 | return 0; | |
45 | } | |
46 | ||
a6f3f3b1 JH |
47 | static int parse_diff_tree_output(const char *buf, |
48 | const char **spec, int cnt, int reverse) | |
91a6eaa0 JH |
49 | { |
50 | struct diff_spec old, new; | |
51 | char path[PATH_MAX]; | |
d1df5743 JH |
52 | const char *cp = buf; |
53 | int ch; | |
d1df5743 JH |
54 | |
55 | switch (*cp++) { | |
0b32ff0d | 56 | case 'U': |
91a6eaa0 JH |
57 | if (!cnt || matches_pathspec(cp + 1, spec, cnt)) |
58 | diff_unmerge(cp + 1); | |
59 | return 0; | |
d1df5743 | 60 | case '+': |
91a6eaa0 JH |
61 | old.file_valid = 0; |
62 | parse_oneside_change(cp, &new, path); | |
63 | break; | |
d1df5743 | 64 | case '-': |
91a6eaa0 JH |
65 | new.file_valid = 0; |
66 | parse_oneside_change(cp, &old, path); | |
67 | break; | |
d1df5743 | 68 | case '*': |
91a6eaa0 JH |
69 | old.file_valid = old.sha1_valid = |
70 | new.file_valid = new.sha1_valid = 1; | |
71 | old.mode = new.mode = 0; | |
72 | while ((ch = *cp) && ('0' <= ch && ch <= '7')) { | |
73 | old.mode = (old.mode << 3) | (ch - '0'); | |
74 | cp++; | |
75 | } | |
76 | if (strncmp(cp, "->", 2)) | |
77 | return -1; | |
78 | cp += 2; | |
79 | while ((ch = *cp) && ('0' <= ch && ch <= '7')) { | |
80 | new.mode = (new.mode << 3) | (ch - '0'); | |
81 | cp++; | |
82 | } | |
83 | if (strncmp(cp, "\tblob\t", 6)) | |
84 | return -1; | |
85 | cp += 6; | |
86 | if (get_sha1_hex(cp, old.u.sha1)) | |
87 | return -1; | |
88 | cp += 40; | |
89 | if (strncmp(cp, "->", 2)) | |
90 | return -1; | |
91 | cp += 2; | |
92 | if (get_sha1_hex(cp, new.u.sha1)) | |
93 | return -1; | |
94 | cp += 40; | |
95 | if (*cp++ != '\t') | |
96 | return -1; | |
97 | strcpy(path, cp); | |
d1df5743 JH |
98 | break; |
99 | default: | |
91a6eaa0 | 100 | return -1; |
be3cfa85 | 101 | } |
a6f3f3b1 JH |
102 | if (!cnt || matches_pathspec(path, spec, cnt)) { |
103 | if (reverse) | |
104 | run_external_diff(path, &new, &old); | |
105 | else | |
106 | run_external_diff(path, &old, &new); | |
107 | } | |
d1df5743 JH |
108 | return 0; |
109 | } | |
110 | ||
111 | static const char *diff_tree_helper_usage = | |
112 | "diff-tree-helper [-R] [-z] paths..."; | |
113 | ||
91a6eaa0 | 114 | int main(int ac, const char **av) { |
d1df5743 | 115 | struct strbuf sb; |
a6f3f3b1 | 116 | int reverse = 0; |
d1df5743 JH |
117 | int line_termination = '\n'; |
118 | ||
119 | strbuf_init(&sb); | |
120 | ||
121 | while (1 < ac && av[1][0] == '-') { | |
122 | if (av[1][1] == 'R') | |
a6f3f3b1 | 123 | reverse = 1; |
d1df5743 JH |
124 | else if (av[1][1] == 'z') |
125 | line_termination = 0; | |
126 | else | |
127 | usage(diff_tree_helper_usage); | |
128 | ac--; av++; | |
129 | } | |
130 | /* the remaining parameters are paths patterns */ | |
131 | ||
d1df5743 | 132 | while (1) { |
0b32ff0d | 133 | int status; |
d1df5743 JH |
134 | read_line(&sb, stdin, line_termination); |
135 | if (sb.eof) | |
136 | break; | |
a6f3f3b1 | 137 | status = parse_diff_tree_output(sb.buf, av+1, ac-1, reverse); |
91a6eaa0 JH |
138 | if (status) |
139 | fprintf(stderr, "cannot parse %s\n", sb.buf); | |
d1df5743 JH |
140 | } |
141 | return 0; | |
142 | } |