]>
Commit | Line | Data |
---|---|---|
be3cfa85 JH |
1 | /* |
2 | * Copyright (C) 2005 Junio C Hamano | |
3 | */ | |
a1df57ab | 4 | #include <limits.h> |
d1df5743 JH |
5 | #include "cache.h" |
6 | #include "strbuf.h" | |
7 | #include "diff.h" | |
8 | ||
915838c3 | 9 | static int detect_rename = 0; |
57fe64a4 | 10 | static int diff_score_opt = 0; |
427dcb4b | 11 | static int generate_patch = 1; |
057c7d30 | 12 | static const char *pickaxe = NULL; |
915838c3 | 13 | |
5c97558c JH |
14 | static int parse_oneside_change(const char *cp, int *mode, |
15 | unsigned char *sha1, char *path) | |
be3cfa85 | 16 | { |
5c97558c | 17 | int ch, m; |
be3cfa85 | 18 | |
5c97558c | 19 | m = 0; |
be3cfa85 | 20 | while ((ch = *cp) && '0' <= ch && ch <= '7') { |
5c97558c | 21 | m = (m << 3) | (ch - '0'); |
be3cfa85 JH |
22 | cp++; |
23 | } | |
5c97558c | 24 | *mode = m; |
427dcb4b JH |
25 | if (strncmp(cp, "\tblob\t", 6) && strncmp(cp, " blob ", 6) && |
26 | strncmp(cp, "\ttree\t", 6) && strncmp(cp, " tree ", 6)) | |
d1df5743 JH |
27 | return -1; |
28 | cp += 6; | |
5c97558c | 29 | if (get_sha1_hex(cp, sha1)) |
d1df5743 JH |
30 | return -1; |
31 | cp += 40; | |
57fe64a4 | 32 | if ((*cp != '\t') && *cp != ' ') |
d1df5743 | 33 | return -1; |
57fe64a4 | 34 | strcpy(path, ++cp); |
d1df5743 JH |
35 | return 0; |
36 | } | |
37 | ||
5c97558c | 38 | static int parse_diff_raw_output(const char *buf) |
91a6eaa0 | 39 | { |
91a6eaa0 | 40 | char path[PATH_MAX]; |
5c97558c | 41 | unsigned char old_sha1[20], new_sha1[20]; |
d1df5743 | 42 | const char *cp = buf; |
5c97558c | 43 | int ch, old_mode, new_mode; |
d1df5743 JH |
44 | |
45 | switch (*cp++) { | |
0b32ff0d | 46 | case 'U': |
5c97558c JH |
47 | diff_unmerge(cp + 1); |
48 | break; | |
d1df5743 | 49 | case '+': |
427dcb4b JH |
50 | if (parse_oneside_change(cp, &new_mode, new_sha1, path)) |
51 | return -1; | |
5c97558c | 52 | diff_addremove('+', new_mode, new_sha1, path, NULL); |
91a6eaa0 | 53 | break; |
d1df5743 | 54 | case '-': |
427dcb4b JH |
55 | if (parse_oneside_change(cp, &old_mode, old_sha1, path)) |
56 | return -1; | |
5c97558c | 57 | diff_addremove('-', old_mode, old_sha1, path, NULL); |
91a6eaa0 | 58 | break; |
d1df5743 | 59 | case '*': |
5c97558c | 60 | old_mode = new_mode = 0; |
91a6eaa0 | 61 | while ((ch = *cp) && ('0' <= ch && ch <= '7')) { |
5c97558c | 62 | old_mode = (old_mode << 3) | (ch - '0'); |
91a6eaa0 JH |
63 | cp++; |
64 | } | |
65 | if (strncmp(cp, "->", 2)) | |
66 | return -1; | |
67 | cp += 2; | |
68 | while ((ch = *cp) && ('0' <= ch && ch <= '7')) { | |
5c97558c | 69 | new_mode = (new_mode << 3) | (ch - '0'); |
91a6eaa0 JH |
70 | cp++; |
71 | } | |
427dcb4b JH |
72 | if (strncmp(cp, "\tblob\t", 6) && strncmp(cp, " blob ", 6) && |
73 | strncmp(cp, "\ttree\t", 6) && strncmp(cp, " tree ", 6)) | |
91a6eaa0 JH |
74 | return -1; |
75 | cp += 6; | |
5c97558c | 76 | if (get_sha1_hex(cp, old_sha1)) |
91a6eaa0 JH |
77 | return -1; |
78 | cp += 40; | |
79 | if (strncmp(cp, "->", 2)) | |
80 | return -1; | |
81 | cp += 2; | |
5c97558c | 82 | if (get_sha1_hex(cp, new_sha1)) |
91a6eaa0 JH |
83 | return -1; |
84 | cp += 40; | |
57fe64a4 | 85 | if ((*cp != '\t') && *cp != ' ') |
91a6eaa0 | 86 | return -1; |
57fe64a4 | 87 | strcpy(path, ++cp); |
e99d59ff | 88 | diff_change(old_mode, new_mode, old_sha1, new_sha1, path, NULL); |
d1df5743 JH |
89 | break; |
90 | default: | |
91a6eaa0 | 91 | return -1; |
be3cfa85 | 92 | } |
d1df5743 JH |
93 | return 0; |
94 | } | |
95 | ||
902b92e0 | 96 | static const char *diff_helper_usage = |
52e95789 | 97 | "git-diff-helper [-z] [-R] [-M] [-C] [-S<string>] paths..."; |
d1df5743 | 98 | |
91a6eaa0 | 99 | int main(int ac, const char **av) { |
d1df5743 | 100 | struct strbuf sb; |
a6f3f3b1 | 101 | int reverse = 0; |
d1df5743 JH |
102 | int line_termination = '\n'; |
103 | ||
104 | strbuf_init(&sb); | |
105 | ||
106 | while (1 < ac && av[1][0] == '-') { | |
107 | if (av[1][1] == 'R') | |
a6f3f3b1 | 108 | reverse = 1; |
d1df5743 JH |
109 | else if (av[1][1] == 'z') |
110 | line_termination = 0; | |
427dcb4b JH |
111 | else if (av[1][1] == 'p') /* hidden from the help */ |
112 | generate_patch = 0; | |
57fe64a4 | 113 | else if (av[1][1] == 'M') { |
915838c3 | 114 | detect_rename = 1; |
57fe64a4 JH |
115 | diff_score_opt = diff_scoreopt_parse(av[1]); |
116 | } | |
427dcb4b JH |
117 | else if (av[1][1] == 'C') { |
118 | detect_rename = 2; | |
119 | diff_score_opt = diff_scoreopt_parse(av[1]); | |
120 | } | |
52e95789 JH |
121 | else if (av[1][1] == 'S') { |
122 | pickaxe = av[1] + 2; | |
123 | } | |
d1df5743 | 124 | else |
902b92e0 | 125 | usage(diff_helper_usage); |
d1df5743 JH |
126 | ac--; av++; |
127 | } | |
128 | /* the remaining parameters are paths patterns */ | |
129 | ||
38c6f780 | 130 | diff_setup(reverse, (generate_patch ? -1 : line_termination)); |
d1df5743 | 131 | while (1) { |
0b32ff0d | 132 | int status; |
d1df5743 JH |
133 | read_line(&sb, stdin, line_termination); |
134 | if (sb.eof) | |
135 | break; | |
5c97558c | 136 | status = parse_diff_raw_output(sb.buf); |
e11b29c5 | 137 | if (status) { |
38c6f780 | 138 | diff_flush(av+1, ac-1); |
e11b29c5 LT |
139 | printf("%s%c", sb.buf, line_termination); |
140 | } | |
d1df5743 | 141 | } |
915838c3 | 142 | |
38c6f780 JH |
143 | if (detect_rename) |
144 | diff_detect_rename(detect_rename, diff_score_opt); | |
145 | if (pickaxe) | |
146 | diff_pickaxe(pickaxe); | |
147 | diff_flush(av+1, ac-1); | |
d1df5743 JH |
148 | return 0; |
149 | } |