/* * Copyright (C) 2005 Junio C Hamano */ #include "cache.h" #include "strbuf.h" #include "diff.h" static const char *pickaxe = NULL; static int pickaxe_opts = 0; static const char *orderfile = NULL; static const char *diff_filter = NULL; static int line_termination = '\n'; static int inter_name_termination = '\t'; static void flush_them(int ac, const char **av) { diffcore_std_no_resolve(av + 1, pickaxe, pickaxe_opts, orderfile, diff_filter); diff_flush(DIFF_FORMAT_PATCH, '\n'); } static const char diff_helper_usage[] = "git-diff-helper [-z] [-O] [-S] [--pickaxe-all] [...]"; int main(int ac, const char **av) { struct strbuf sb; const char *garbage_flush_format; strbuf_init(&sb); while (1 < ac && av[1][0] == '-') { if (av[1][1] == 'z') line_termination = inter_name_termination = 0; else if (av[1][1] == 'S') { pickaxe = av[1] + 2; } else if (!strcmp(av[1], "--pickaxe-all")) pickaxe_opts = DIFF_PICKAXE_ALL; else if (!strncmp(av[1], "--diff-filter=", 14)) diff_filter = av[1] + 14; else if (!strncmp(av[1], "-O", 2)) orderfile = av[1] + 2; else usage(diff_helper_usage); ac--; av++; } garbage_flush_format = (line_termination == 0) ? "%s" : "%s\n"; /* the remaining parameters are paths patterns */ diff_setup(0); while (1) { unsigned old_mode, new_mode; unsigned char old_sha1[20], new_sha1[20]; char old_path[PATH_MAX]; int status, score, two_paths; char new_path[PATH_MAX]; int ch; char *cp, *ep; read_line(&sb, stdin, line_termination); if (sb.eof) break; switch (sb.buf[0]) { case ':': /* parse the first part up to the status */ cp = sb.buf + 1; old_mode = new_mode = 0; while ((ch = *cp) && ('0' <= ch && ch <= '7')) { old_mode = (old_mode << 3) | (ch - '0'); cp++; } if (*cp++ != ' ') break; while ((ch = *cp) && ('0' <= ch && ch <= '7')) { new_mode = (new_mode << 3) | (ch - '0'); cp++; } if (*cp++ != ' ') break; if (get_sha1_hex(cp, old_sha1)) break; cp += 40; if (*cp++ != ' ') break; if (get_sha1_hex(cp, new_sha1)) break; cp += 40; if (*cp++ != ' ') break; status = *cp++; if (!strchr("MCRNDU", status)) break; two_paths = score = 0; if (status == DIFF_STATUS_RENAMED || status == DIFF_STATUS_COPIED) two_paths = 1; /* pick up score if exists */ if (sscanf(cp, "%d", &score) != 1) score = 0; cp = strchr(cp, inter_name_termination); if (!cp) break; if (*cp++ != inter_name_termination) break; /* first pathname */ if (!line_termination) { read_line(&sb, stdin, line_termination); if (sb.eof) break; strcpy(old_path, sb.buf); } else if (!two_paths) strcpy(old_path, cp); else { ep = strchr(cp, inter_name_termination); if (!ep) break; strncpy(old_path, cp, ep-cp); old_path[ep-cp] = 0; cp = ep + 1; } /* second pathname */ if (!two_paths) strcpy(new_path, old_path); else { if (!line_termination) { read_line(&sb, stdin, line_termination); if (sb.eof) break; strcpy(new_path, sb.buf); } else strcpy(new_path, cp); } diff_helper_input(old_mode, new_mode, old_sha1, new_sha1, old_path, status, score, new_path); continue; } flush_them(ac, av); printf(garbage_flush_format, sb.buf); } flush_them(ac, av); return 0; }