X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=diff-tree-helper.c;h=51bb658be4f73c00016b4ecb82f09d30941998a4;hb=62d046a07b4cd4328d3d40aab097a1d97c4d7b20;hp=bcf89a57892ac3601ac268b08c7f28d443c75108;hpb=be3cfa85f45e32722a65349d023667be906a66b6;p=git.git diff --git a/diff-tree-helper.c b/diff-tree-helper.c index bcf89a57..51bb658b 100644 --- a/diff-tree-helper.c +++ b/diff-tree-helper.c @@ -1,11 +1,12 @@ /* * Copyright (C) 2005 Junio C Hamano */ +#include #include "cache.h" #include "strbuf.h" #include "diff.h" -static int matches_pathspec(const char *name, char **spec, int cnt) +static int matches_pathspec(const char *name, const char **spec, int cnt) { int i; int namelen = strlen(name); @@ -35,7 +36,7 @@ static int parse_oneside_change(const char *cp, struct diff_spec *one, if (strncmp(cp, "\tblob\t", 6)) return -1; cp += 6; - if (get_sha1_hex(cp, one->u.sha1)) + if (get_sha1_hex(cp, one->blob_sha1)) return -1; cp += 40; if (*cp++ != '\t') @@ -45,72 +46,82 @@ static int parse_oneside_change(const char *cp, struct diff_spec *one, } static int parse_diff_tree_output(const char *buf, - struct diff_spec *old, - struct diff_spec *new, - char *path) { + const char **spec, int cnt, int reverse) +{ + struct diff_spec old, new; + char path[PATH_MAX]; const char *cp = buf; int ch; switch (*cp++) { + case 'U': + if (!cnt || matches_pathspec(cp + 1, spec, cnt)) + diff_unmerge(cp + 1); + return 0; case '+': - old->file_valid = 0; - return parse_oneside_change(cp, new, path); + old.file_valid = 0; + parse_oneside_change(cp, &new, path); + break; case '-': - new->file_valid = 0; - return parse_oneside_change(cp, old, path); + new.file_valid = 0; + parse_oneside_change(cp, &old, path); + break; case '*': + old.file_valid = old.sha1_valid = + new.file_valid = new.sha1_valid = 1; + old.mode = new.mode = 0; + while ((ch = *cp) && ('0' <= ch && ch <= '7')) { + old.mode = (old.mode << 3) | (ch - '0'); + cp++; + } + if (strncmp(cp, "->", 2)) + return -1; + cp += 2; + while ((ch = *cp) && ('0' <= ch && ch <= '7')) { + new.mode = (new.mode << 3) | (ch - '0'); + cp++; + } + if (strncmp(cp, "\tblob\t", 6)) + return -1; + cp += 6; + if (get_sha1_hex(cp, old.blob_sha1)) + return -1; + cp += 40; + if (strncmp(cp, "->", 2)) + return -1; + cp += 2; + if (get_sha1_hex(cp, new.blob_sha1)) + return -1; + cp += 40; + if (*cp++ != '\t') + return -1; + strcpy(path, cp); break; default: return -1; } - - /* This is for '*' entries */ - old->file_valid = old->sha1_valid = 1; - new->file_valid = new->sha1_valid = 1; - - old->mode = new->mode = 0; - while ((ch = *cp) && ('0' <= ch && ch <= '7')) { - old->mode = (old->mode << 3) | (ch - '0'); - cp++; - } - if (strncmp(cp, "->", 2)) - return -1; - cp += 2; - while ((ch = *cp) && ('0' <= ch && ch <= '7')) { - new->mode = (new->mode << 3) | (ch - '0'); - cp++; + if (!cnt || matches_pathspec(path, spec, cnt)) { + if (reverse) + run_external_diff(path, &new, &old); + else + run_external_diff(path, &old, &new); } - if (strncmp(cp, "\tblob\t", 6)) - return -1; - cp += 6; - if (get_sha1_hex(cp, old->u.sha1)) - return -1; - cp += 40; - if (strncmp(cp, "->", 2)) - return -1; - cp += 2; - if (get_sha1_hex(cp, new->u.sha1)) - return -1; - cp += 40; - if (*cp++ != '\t') - return -1; - strcpy(path, cp); return 0; } static const char *diff_tree_helper_usage = "diff-tree-helper [-R] [-z] paths..."; -int main(int ac, char **av) { +int main(int ac, const char **av) { struct strbuf sb; - int reverse_diff = 0; + int reverse = 0; int line_termination = '\n'; strbuf_init(&sb); while (1 < ac && av[1][0] == '-') { if (av[1][1] == 'R') - reverse_diff = 1; + reverse = 1; else if (av[1][1] == 'z') line_termination = 0; else @@ -120,19 +131,13 @@ int main(int ac, char **av) { /* the remaining parameters are paths patterns */ while (1) { - struct diff_spec old, new; - char path[PATH_MAX]; + int status; read_line(&sb, stdin, line_termination); if (sb.eof) break; - if (parse_diff_tree_output(sb.buf, &old, &new, path)) { + status = parse_diff_tree_output(sb.buf, av+1, ac-1, reverse); + if (status) fprintf(stderr, "cannot parse %s\n", sb.buf); - continue; - } - if (1 < ac && !matches_pathspec(path, av+1, ac-1)) - continue; - - run_external_diff(path, &old, &new); } return 0; }