git/diff-helper.c
Junio C Hamano e7baa4f45f Use symbolic constants for diff-raw status indicators.
Both Cogito and StGIT prefer to see 'A' for new files.  The
current 'N' is visually harder to distinguish from 'M', which is
used for modified files.  Prepare the internals to use symbolic
constants to make the change easier.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-07-25 17:15:34 -07:00

155 lines
3.4 KiB
C

/*
* 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<orderfile>] [-S<string>] [--pickaxe-all] [<path>...]";
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;
}