@ -17,6 +17,7 @@
#include "diffcore.h"
#include "diffcore.h"
#include "revision.h"
#include "revision.h"
#include "xdiff-interface.h"
#include "xdiff-interface.h"
#include "quote.h"
#define DEBUG 0
#define DEBUG 0
@ -40,6 +41,7 @@ struct util_info {
unsigned long size;
unsigned long size;
int num_lines;
int num_lines;
const char *pathname;
const char *pathname;
unsigned meta_given:1;
void *topo_data;
void *topo_data;
};
};
@ -332,12 +334,8 @@ static struct util_info *get_util(struct commit *commit)
if (util)
if (util)
return util;
return util;
util = xmalloc(sizeof(struct util_info));
util = xcalloc(1, sizeof(struct util_info));
util->buf = NULL;
util->size = 0;
util->line_map = NULL;
util->num_lines = -1;
util->num_lines = -1;
util->pathname = NULL;
commit->util = util;
commit->util = util;
return util;
return util;
}
}
@ -642,39 +640,99 @@ struct commit_info
char *author_mail;
char *author_mail;
unsigned long author_time;
unsigned long author_time;
char *author_tz;
char *author_tz;
/* filled only when asked for details */
char *committer;
char *committer_mail;
unsigned long committer_time;
char *committer_tz;
char *summary;
};
};
static void get_commit_info(struct commit *commit, struct commit_info *ret)
static void get_ac_line(const char *inbuf, const char *what,
int bufsz, char *person, char **mail,
unsigned long *time, char **tz)
{
{
int len;
int len;
char *tmp;
char *tmp, *endp;
static char author_buf[1024];
tmp = strstr(inbuf, what);
tmp = strstr(commit->buffer, "\nauthor ") + 8;
if (!tmp)
len = strchr(tmp, '\n') - tmp;
goto error_out;
ret->author = author_buf;
tmp += strlen(what);
memcpy(ret->author, tmp, len);
endp = strchr(tmp, '\n');
if (!endp)
len = strlen(tmp);
else
len = endp - tmp;
if (bufsz <= len) {
error_out:
/* Ugh */
person = *mail = *tz = "(unknown)";
*time = 0;
return;
}
memcpy(person, tmp, len);
tmp = ret->author;
tmp = person;
tmp += len;
tmp += len;
*tmp = 0;
*tmp = 0;
while (*tmp != ' ')
while (*tmp != ' ')
tmp--;
tmp--;
ret->author_tz = tmp+1;
*tz = tmp+1;
*tmp = 0;
*tmp = 0;
while (*tmp != ' ')
while (*tmp != ' ')
tmp--;
tmp--;
ret->author_time = strtoul(tmp, NULL, 10);
*time = strtoul(tmp, NULL, 10);
*tmp = 0;
*tmp = 0;
while (*tmp != ' ')
while (*tmp != ' ')
tmp--;
tmp--;
ret->author_mail = tmp + 1;
*mail = tmp + 1;
*tmp = 0;
*tmp = 0;
}
}
static void get_commit_info(struct commit *commit, struct commit_info *ret, int detailed)
{
int len;
char *tmp, *endp;
static char author_buf[1024];
static char committer_buf[1024];
static char summary_buf[1024];
ret->author = author_buf;
get_ac_line(commit->buffer, "\nauthor ",
sizeof(author_buf), author_buf, &ret->author_mail,
&ret->author_time, &ret->author_tz);
if (!detailed)
return;
ret->committer = committer_buf;
get_ac_line(commit->buffer, "\ncommitter ",
sizeof(committer_buf), committer_buf, &ret->committer_mail,
&ret->committer_time, &ret->committer_tz);
ret->summary = summary_buf;
tmp = strstr(commit->buffer, "\n\n");
if (!tmp) {
error_out:
sprintf(summary_buf, "(%s)", sha1_to_hex(commit->object.sha1));
return;
}
tmp += 2;
endp = strchr(tmp, '\n');
if (!endp)
goto error_out;
len = endp - tmp;
if (len >= sizeof(summary_buf))
goto error_out;
memcpy(summary_buf, tmp, len);
summary_buf[len] = 0;
}
static const char *format_time(unsigned long time, const char *tz_str,
static const char *format_time(unsigned long time, const char *tz_str,
int show_raw_time)
int show_raw_time)
{
{
@ -751,7 +809,7 @@ static int find_orig_linenum(struct util_info *u, int lineno)
}
}
static void emit_meta(struct commit *c, int lno,
static void emit_meta(struct commit *c, int lno,
int sha1_len, int compatibility,
int sha1_len, int compatibility, int porcelain,
int show_name, int show_number, int show_raw_time,
int show_name, int show_number, int show_raw_time,
int longest_file, int longest_author,
int longest_file, int longest_author,
int max_digits, int max_orig_digits)
int max_digits, int max_orig_digits)
@ -763,7 +821,47 @@ static void emit_meta(struct commit *c, int lno,
u = c->util;
u = c->util;
lineno = find_orig_linenum(u, lno);
lineno = find_orig_linenum(u, lno);
get_commit_info(c, &ci);
if (porcelain) {
int group_size = -1;
struct commit *cc = (lno == 0) ? NULL : blame_lines[lno-1];
if (cc != c) {
/* This is the beginning of this group */
int i;
for (i = lno + 1; i < num_blame_lines; i++)
if (blame_lines[i] != c)
break;
group_size = i - lno;
}
if (0 < group_size)
printf("%s %d %d %d\n", sha1_to_hex(c->object.sha1),
lineno, lno + 1, group_size);
else
printf("%s %d %d\n", sha1_to_hex(c->object.sha1),
lineno, lno + 1);
if (!u->meta_given) {
get_commit_info(c, &ci, 1);
printf("author %s\n", ci.author);
printf("author-mail %s\n", ci.author_mail);
printf("author-time %lu\n", ci.author_time);
printf("author-tz %s\n", ci.author_tz);
printf("committer %s\n", ci.committer);
printf("committer-mail %s\n", ci.committer_mail);
printf("committer-time %lu\n", ci.committer_time);
printf("committer-tz %s\n", ci.committer_tz);
printf("filename ");
if (quote_c_style(u->pathname, NULL, NULL, 0))
quote_c_style(u->pathname, NULL, stdout, 0);
else
fputs(u->pathname, stdout);
printf("\nsummary %s\n", ci.summary);
u->meta_given = 1;
}
putchar('\t');
return;
}
get_commit_info(c, &ci, 0);
fwrite(sha1_to_hex(c->object.sha1), sha1_len, 1, stdout);
fwrite(sha1_to_hex(c->object.sha1), sha1_len, 1, stdout);
if (compatibility) {
if (compatibility) {
printf("\t(%10s\t%10s\t%d)", ci.author,
printf("\t(%10s\t%10s\t%d)", ci.author,
@ -809,6 +907,7 @@ int main(int argc, const char **argv)
int longest_file, longest_author, longest_file_lines;
int longest_file, longest_author, longest_file_lines;
int show_name = 0;
int show_name = 0;
int show_number = 0;
int show_number = 0;
int porcelain = 0;
const char *prefix = setup_git_directory();
const char *prefix = setup_git_directory();
git_config(git_default_config);
git_config(git_default_config);
@ -852,6 +951,12 @@ int main(int argc, const char **argv)
show_number = 1;
show_number = 1;
continue;
continue;
}
}
if (!strcmp(argv[i], "--porcelain")) {
porcelain = 1;
sha1_len = 40;
show_raw_time = 1;
continue;
}
if (!strcmp(argv[i], "--")) {
if (!strcmp(argv[i], "--")) {
options = 0;
options = 0;
continue;
continue;
@ -934,7 +1039,7 @@ int main(int argc, const char **argv)
longest_file = strlen(u->pathname);
longest_file = strlen(u->pathname);
if (longest_file_lines < u->num_lines)
if (longest_file_lines < u->num_lines)
longest_file_lines = u->num_lines;
longest_file_lines = u->num_lines;
get_commit_info(c, &ci);
get_commit_info(c, &ci, 0);
if (longest_author < strlen(ci.author))
if (longest_author < strlen(ci.author))
longest_author = strlen(ci.author);
longest_author = strlen(ci.author);
}
}
@ -943,7 +1048,7 @@ int main(int argc, const char **argv)
for (i = 0; i < num_blame_lines; i++) {
for (i = 0; i < num_blame_lines; i++) {
emit_meta(blame_lines[i], i,
emit_meta(blame_lines[i], i,
sha1_len, compatibility,
sha1_len, compatibility, porcelain,
show_name, show_number, show_raw_time,
show_name, show_number, show_raw_time,
longest_file, longest_author,
longest_file, longest_author,
max_digits, max_orig_digits);
max_digits, max_orig_digits);