Merge branch 'ei/oneline+add-empty'
* ei/oneline+add-empty: Fix ALLOC_GROW calls with obsolete semantics Fix ALLOC_GROW off-by-one builtin-add: simplify (and increase accuracy of) exclude handling dir_struct: add collect_ignored option Extend --pretty=oneline to cover the first paragraph, Lift 16kB limit of log message output
This commit is contained in:
commit
9bee7aabcd
@ -40,42 +40,29 @@ static void prune_directory(struct dir_struct *dir, const char **pathspec, int p
|
||||
dir->nr = dst - dir->entries;
|
||||
|
||||
for (i = 0; i < specs; i++) {
|
||||
struct stat st;
|
||||
const char *match;
|
||||
if (seen[i])
|
||||
continue;
|
||||
|
||||
match = pathspec[i];
|
||||
if (!match[0])
|
||||
continue;
|
||||
|
||||
/* Existing file? We must have ignored it */
|
||||
if (!lstat(match, &st)) {
|
||||
struct dir_entry *ent;
|
||||
|
||||
ent = dir_add_name(dir, match, strlen(match));
|
||||
ent->ignored = 1;
|
||||
if (S_ISDIR(st.st_mode))
|
||||
ent->ignored_dir = 1;
|
||||
continue;
|
||||
}
|
||||
die("pathspec '%s' did not match any files", match);
|
||||
if (!seen[i] && !file_exists(pathspec[i]))
|
||||
die("pathspec '%s' did not match any files",
|
||||
pathspec[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void fill_directory(struct dir_struct *dir, const char **pathspec)
|
||||
static void fill_directory(struct dir_struct *dir, const char **pathspec,
|
||||
int ignored_too)
|
||||
{
|
||||
const char *path, *base;
|
||||
int baselen;
|
||||
|
||||
/* Set up the default git porcelain excludes */
|
||||
memset(dir, 0, sizeof(*dir));
|
||||
dir->exclude_per_dir = ".gitignore";
|
||||
path = git_path("info/exclude");
|
||||
if (!access(path, R_OK))
|
||||
add_excludes_from_file(dir, path);
|
||||
if (!access(excludes_file, R_OK))
|
||||
add_excludes_from_file(dir, excludes_file);
|
||||
if (!ignored_too) {
|
||||
dir->collect_ignored = 1;
|
||||
dir->exclude_per_dir = ".gitignore";
|
||||
path = git_path("info/exclude");
|
||||
if (!access(path, R_OK))
|
||||
add_excludes_from_file(dir, path);
|
||||
if (!access(excludes_file, R_OK))
|
||||
add_excludes_from_file(dir, excludes_file);
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate common prefix for the pathspec, and
|
||||
@ -219,13 +206,11 @@ int cmd_add(int argc, const char **argv, const char *prefix)
|
||||
}
|
||||
pathspec = get_pathspec(prefix, argv + i);
|
||||
|
||||
fill_directory(&dir, pathspec);
|
||||
fill_directory(&dir, pathspec, ignored_too);
|
||||
|
||||
if (show_only) {
|
||||
const char *sep = "", *eof = "";
|
||||
for (i = 0; i < dir.nr; i++) {
|
||||
if (!ignored_too && dir.entries[i]->ignored)
|
||||
continue;
|
||||
printf("%s%s", sep, dir.entries[i]->name);
|
||||
sep = " ";
|
||||
eof = "\n";
|
||||
@ -237,25 +222,13 @@ int cmd_add(int argc, const char **argv, const char *prefix)
|
||||
if (read_cache() < 0)
|
||||
die("index file corrupt");
|
||||
|
||||
if (!ignored_too) {
|
||||
int has_ignored = 0;
|
||||
for (i = 0; i < dir.nr; i++)
|
||||
if (dir.entries[i]->ignored)
|
||||
has_ignored = 1;
|
||||
if (has_ignored) {
|
||||
fprintf(stderr, ignore_warning);
|
||||
for (i = 0; i < dir.nr; i++) {
|
||||
if (!dir.entries[i]->ignored)
|
||||
continue;
|
||||
fprintf(stderr, "%s", dir.entries[i]->name);
|
||||
if (dir.entries[i]->ignored_dir)
|
||||
fprintf(stderr, " (directory)");
|
||||
fputc('\n', stderr);
|
||||
}
|
||||
fprintf(stderr,
|
||||
"Use -f if you really want to add them.\n");
|
||||
exit(1);
|
||||
if (dir.ignored_nr) {
|
||||
fprintf(stderr, ignore_warning);
|
||||
for (i = 0; i < dir.ignored_nr; i++) {
|
||||
fprintf(stderr, "%s\n", dir.ignored[i]->name);
|
||||
}
|
||||
fprintf(stderr, "Use -f if you really want to add them.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (i = 0; i < dir.nr; i++)
|
||||
|
@ -247,7 +247,6 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,
|
||||
char c;
|
||||
int color;
|
||||
struct commit *commit;
|
||||
char subject[256];
|
||||
|
||||
switch (item->kind) {
|
||||
case REF_LOCAL_BRANCH:
|
||||
@ -268,17 +267,23 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,
|
||||
}
|
||||
|
||||
if (verbose) {
|
||||
char *subject = NULL;
|
||||
unsigned long subject_len = 0;
|
||||
const char *sub = " **** invalid ref ****";
|
||||
|
||||
commit = lookup_commit(item->sha1);
|
||||
if (commit && !parse_commit(commit))
|
||||
if (commit && !parse_commit(commit)) {
|
||||
pretty_print_commit(CMIT_FMT_ONELINE, commit, ~0,
|
||||
subject, sizeof(subject), 0,
|
||||
&subject, &subject_len, 0,
|
||||
NULL, NULL, 0);
|
||||
else
|
||||
strcpy(subject, " **** invalid ref ****");
|
||||
sub = subject;
|
||||
}
|
||||
printf("%c %s%-*s%s %s %s\n", c, branch_get_color(color),
|
||||
maxwidth, item->name,
|
||||
branch_get_color(COLOR_BRANCH_RESET),
|
||||
find_unique_abbrev(item->sha1, abbrev), subject);
|
||||
find_unique_abbrev(item->sha1, abbrev), sub);
|
||||
if (subject)
|
||||
free(subject);
|
||||
} else {
|
||||
printf("%c %s%s%s\n", c, branch_get_color(color), item->name,
|
||||
branch_get_color(COLOR_BRANCH_RESET));
|
||||
|
@ -742,11 +742,13 @@ int cmd_cherry(int argc, const char **argv, const char *prefix)
|
||||
sign = '-';
|
||||
|
||||
if (verbose) {
|
||||
static char buf[16384];
|
||||
char *buf = NULL;
|
||||
unsigned long buflen = 0;
|
||||
pretty_print_commit(CMIT_FMT_ONELINE, commit, ~0,
|
||||
buf, sizeof(buf), 0, NULL, NULL, 0);
|
||||
&buf, &buflen, 0, NULL, NULL, 0);
|
||||
printf("%c %s %s\n", sign,
|
||||
sha1_to_hex(commit->object.sha1), buf);
|
||||
free(buf);
|
||||
}
|
||||
else {
|
||||
printf("%c %s\n", sign,
|
||||
|
@ -92,11 +92,13 @@ static void show_commit(struct commit *commit)
|
||||
putchar('\n');
|
||||
|
||||
if (revs.verbose_header) {
|
||||
static char pretty_header[16384];
|
||||
char *buf = NULL;
|
||||
unsigned long buflen = 0;
|
||||
pretty_print_commit(revs.commit_format, commit, ~0,
|
||||
pretty_header, sizeof(pretty_header),
|
||||
&buf, &buflen,
|
||||
revs.abbrev, NULL, NULL, revs.date_mode);
|
||||
printf("%s%c", pretty_header, hdr_termination);
|
||||
printf("%s%c", buf, hdr_termination);
|
||||
free(buf);
|
||||
}
|
||||
fflush(stdout);
|
||||
if (commit->parents) {
|
||||
|
@ -259,17 +259,19 @@ static void join_revs(struct commit_list **list_p,
|
||||
|
||||
static void show_one_commit(struct commit *commit, int no_name)
|
||||
{
|
||||
char pretty[256], *cp;
|
||||
char *pretty = NULL;
|
||||
const char *pretty_str = "(unavailable)";
|
||||
unsigned long pretty_len = 0;
|
||||
struct commit_name *name = commit->util;
|
||||
if (commit->object.parsed)
|
||||
|
||||
if (commit->object.parsed) {
|
||||
pretty_print_commit(CMIT_FMT_ONELINE, commit, ~0,
|
||||
pretty, sizeof(pretty), 0, NULL, NULL, 0);
|
||||
else
|
||||
strcpy(pretty, "(unavailable)");
|
||||
if (!prefixcmp(pretty, "[PATCH] "))
|
||||
cp = pretty + 8;
|
||||
else
|
||||
cp = pretty;
|
||||
&pretty, &pretty_len,
|
||||
0, NULL, NULL, 0);
|
||||
pretty_str = pretty;
|
||||
}
|
||||
if (!prefixcmp(pretty_str, "[PATCH] "))
|
||||
pretty_str += 8;
|
||||
|
||||
if (!no_name) {
|
||||
if (name && name->head_name) {
|
||||
@ -286,7 +288,8 @@ static void show_one_commit(struct commit *commit, int no_name)
|
||||
printf("[%s] ",
|
||||
find_unique_abbrev(commit->object.sha1, 7));
|
||||
}
|
||||
puts(cp);
|
||||
puts(pretty_str);
|
||||
free(pretty);
|
||||
}
|
||||
|
||||
static char *ref_name[MAX_REVS + 1];
|
||||
|
7
cache.h
7
cache.h
@ -234,8 +234,11 @@ extern void verify_non_filename(const char *prefix, const char *name);
|
||||
*/
|
||||
#define ALLOC_GROW(x, nr, alloc) \
|
||||
do { \
|
||||
if ((nr) >= alloc) { \
|
||||
alloc = alloc_nr(alloc); \
|
||||
if ((nr) > alloc) { \
|
||||
if (alloc_nr(alloc) < (nr)) \
|
||||
alloc = (nr); \
|
||||
else \
|
||||
alloc = alloc_nr(alloc); \
|
||||
x = xrealloc((x), alloc * sizeof(*(x))); \
|
||||
} \
|
||||
} while(0)
|
||||
|
399
commit.c
399
commit.c
@ -529,6 +529,14 @@ static int add_rfc2047(char *buf, const char *line, int len,
|
||||
return bp - buf;
|
||||
}
|
||||
|
||||
static unsigned long bound_rfc2047(unsigned long len, const char *encoding)
|
||||
{
|
||||
/* upper bound of q encoded string of length 'len' */
|
||||
unsigned long elen = strlen(encoding);
|
||||
|
||||
return len * 3 + elen + 100;
|
||||
}
|
||||
|
||||
static int add_user_info(const char *what, enum cmit_fmt fmt, char *buf,
|
||||
const char *line, enum date_mode dmode,
|
||||
const char *encoding)
|
||||
@ -776,7 +784,7 @@ static void fill_person(struct interp *table, const char *msg, int len)
|
||||
}
|
||||
|
||||
static long format_commit_message(const struct commit *commit,
|
||||
const char *msg, char *buf, unsigned long space)
|
||||
const char *msg, char **buf_p, unsigned long *space_p)
|
||||
{
|
||||
struct interp table[] = {
|
||||
{ "%H" }, /* commit hash */
|
||||
@ -905,31 +913,252 @@ static long format_commit_message(const struct commit *commit,
|
||||
if (!table[i].value)
|
||||
interp_set_entry(table, i, "<unknown>");
|
||||
|
||||
interpolate(buf, space, user_format, table, ARRAY_SIZE(table));
|
||||
do {
|
||||
char *buf = *buf_p;
|
||||
unsigned long space = *space_p;
|
||||
|
||||
space = interpolate(buf, space, user_format,
|
||||
table, ARRAY_SIZE(table));
|
||||
if (!space)
|
||||
break;
|
||||
buf = xrealloc(buf, space);
|
||||
*buf_p = buf;
|
||||
*space_p = space;
|
||||
} while (1);
|
||||
interp_clear_table(table, ARRAY_SIZE(table));
|
||||
|
||||
return strlen(buf);
|
||||
return strlen(*buf_p);
|
||||
}
|
||||
|
||||
static void pp_header(enum cmit_fmt fmt,
|
||||
int abbrev,
|
||||
enum date_mode dmode,
|
||||
const char *encoding,
|
||||
const struct commit *commit,
|
||||
const char **msg_p,
|
||||
unsigned long *len_p,
|
||||
unsigned long *ofs_p,
|
||||
char **buf_p,
|
||||
unsigned long *space_p)
|
||||
{
|
||||
int parents_shown = 0;
|
||||
|
||||
for (;;) {
|
||||
const char *line = *msg_p;
|
||||
char *dst;
|
||||
int linelen = get_one_line(*msg_p, *len_p);
|
||||
unsigned long len;
|
||||
|
||||
if (!linelen)
|
||||
return;
|
||||
*msg_p += linelen;
|
||||
*len_p -= linelen;
|
||||
|
||||
if (linelen == 1)
|
||||
/* End of header */
|
||||
return;
|
||||
|
||||
ALLOC_GROW(*buf_p, linelen + *ofs_p + 20, *space_p);
|
||||
dst = *buf_p + *ofs_p;
|
||||
|
||||
if (fmt == CMIT_FMT_RAW) {
|
||||
memcpy(dst, line, linelen);
|
||||
*ofs_p += linelen;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!memcmp(line, "parent ", 7)) {
|
||||
if (linelen != 48)
|
||||
die("bad parent line in commit");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!parents_shown) {
|
||||
struct commit_list *parent;
|
||||
int num;
|
||||
for (parent = commit->parents, num = 0;
|
||||
parent;
|
||||
parent = parent->next, num++)
|
||||
;
|
||||
/* with enough slop */
|
||||
num = *ofs_p + num * 50 + 20;
|
||||
ALLOC_GROW(*buf_p, num, *space_p);
|
||||
dst = *buf_p + *ofs_p;
|
||||
*ofs_p += add_merge_info(fmt, dst, commit, abbrev);
|
||||
parents_shown = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* MEDIUM == DEFAULT shows only author with dates.
|
||||
* FULL shows both authors but not dates.
|
||||
* FULLER shows both authors and dates.
|
||||
*/
|
||||
if (!memcmp(line, "author ", 7)) {
|
||||
len = linelen;
|
||||
if (fmt == CMIT_FMT_EMAIL)
|
||||
len = bound_rfc2047(linelen, encoding);
|
||||
ALLOC_GROW(*buf_p, *ofs_p + len, *space_p);
|
||||
dst = *buf_p + *ofs_p;
|
||||
*ofs_p += add_user_info("Author", fmt, dst,
|
||||
line + 7, dmode, encoding);
|
||||
}
|
||||
|
||||
if (!memcmp(line, "committer ", 10) &&
|
||||
(fmt == CMIT_FMT_FULL || fmt == CMIT_FMT_FULLER)) {
|
||||
len = linelen;
|
||||
if (fmt == CMIT_FMT_EMAIL)
|
||||
len = bound_rfc2047(linelen, encoding);
|
||||
ALLOC_GROW(*buf_p, *ofs_p + len, *space_p);
|
||||
dst = *buf_p + *ofs_p;
|
||||
*ofs_p += add_user_info("Commit", fmt, dst,
|
||||
line + 10, dmode, encoding);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void pp_title_line(enum cmit_fmt fmt,
|
||||
const char **msg_p,
|
||||
unsigned long *len_p,
|
||||
unsigned long *ofs_p,
|
||||
char **buf_p,
|
||||
unsigned long *space_p,
|
||||
int indent,
|
||||
const char *subject,
|
||||
const char *after_subject,
|
||||
const char *encoding,
|
||||
int plain_non_ascii)
|
||||
{
|
||||
char *title;
|
||||
unsigned long title_alloc, title_len;
|
||||
unsigned long len;
|
||||
|
||||
title_len = 0;
|
||||
title_alloc = 80;
|
||||
title = xmalloc(title_alloc);
|
||||
for (;;) {
|
||||
const char *line = *msg_p;
|
||||
int linelen = get_one_line(line, *len_p);
|
||||
*msg_p += linelen;
|
||||
*len_p -= linelen;
|
||||
|
||||
if (!linelen || is_empty_line(line, &linelen))
|
||||
break;
|
||||
|
||||
if (title_alloc <= title_len + linelen + 2) {
|
||||
title_alloc = title_len + linelen + 80;
|
||||
title = xrealloc(title, title_alloc);
|
||||
}
|
||||
len = 0;
|
||||
if (title_len) {
|
||||
if (fmt == CMIT_FMT_EMAIL) {
|
||||
len++;
|
||||
title[title_len++] = '\n';
|
||||
}
|
||||
len++;
|
||||
title[title_len++] = ' ';
|
||||
}
|
||||
memcpy(title + title_len, line, linelen);
|
||||
title_len += linelen;
|
||||
}
|
||||
|
||||
/* Enough slop for the MIME header and rfc2047 */
|
||||
len = bound_rfc2047(title_len, encoding)+ 1000;
|
||||
if (subject)
|
||||
len += strlen(subject);
|
||||
if (after_subject)
|
||||
len += strlen(after_subject);
|
||||
if (encoding)
|
||||
len += strlen(encoding);
|
||||
ALLOC_GROW(*buf_p, title_len + *ofs_p + len, *space_p);
|
||||
|
||||
if (subject) {
|
||||
len = strlen(subject);
|
||||
memcpy(*buf_p + *ofs_p, subject, len);
|
||||
*ofs_p += len;
|
||||
*ofs_p += add_rfc2047(*buf_p + *ofs_p,
|
||||
title, title_len, encoding);
|
||||
} else {
|
||||
memcpy(*buf_p + *ofs_p, title, title_len);
|
||||
*ofs_p += title_len;
|
||||
}
|
||||
(*buf_p)[(*ofs_p)++] = '\n';
|
||||
if (plain_non_ascii) {
|
||||
const char *header_fmt =
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=%s\n"
|
||||
"Content-Transfer-Encoding: 8bit\n";
|
||||
*ofs_p += snprintf(*buf_p + *ofs_p,
|
||||
*space_p - *ofs_p,
|
||||
header_fmt, encoding);
|
||||
}
|
||||
if (after_subject) {
|
||||
len = strlen(after_subject);
|
||||
memcpy(*buf_p + *ofs_p, after_subject, len);
|
||||
*ofs_p += len;
|
||||
}
|
||||
free(title);
|
||||
if (fmt == CMIT_FMT_EMAIL) {
|
||||
ALLOC_GROW(*buf_p, *ofs_p + 20, *space_p);
|
||||
(*buf_p)[(*ofs_p)++] = '\n';
|
||||
}
|
||||
}
|
||||
|
||||
static void pp_remainder(enum cmit_fmt fmt,
|
||||
const char **msg_p,
|
||||
unsigned long *len_p,
|
||||
unsigned long *ofs_p,
|
||||
char **buf_p,
|
||||
unsigned long *space_p,
|
||||
int indent)
|
||||
{
|
||||
int first = 1;
|
||||
for (;;) {
|
||||
const char *line = *msg_p;
|
||||
int linelen = get_one_line(line, *len_p);
|
||||
*msg_p += linelen;
|
||||
*len_p -= linelen;
|
||||
|
||||
if (!linelen)
|
||||
break;
|
||||
|
||||
if (is_empty_line(line, &linelen)) {
|
||||
if (first)
|
||||
continue;
|
||||
if (fmt == CMIT_FMT_SHORT)
|
||||
break;
|
||||
}
|
||||
first = 0;
|
||||
|
||||
ALLOC_GROW(*buf_p, *ofs_p + linelen + indent + 20, *space_p);
|
||||
if (indent) {
|
||||
memset(*buf_p + *ofs_p, ' ', indent);
|
||||
*ofs_p += indent;
|
||||
}
|
||||
memcpy(*buf_p + *ofs_p, line, linelen);
|
||||
*ofs_p += linelen;
|
||||
(*buf_p)[(*ofs_p)++] = '\n';
|
||||
}
|
||||
}
|
||||
|
||||
unsigned long pretty_print_commit(enum cmit_fmt fmt,
|
||||
const struct commit *commit,
|
||||
unsigned long len,
|
||||
char *buf, unsigned long space,
|
||||
char **buf_p, unsigned long *space_p,
|
||||
int abbrev, const char *subject,
|
||||
const char *after_subject,
|
||||
enum date_mode dmode)
|
||||
{
|
||||
int hdr = 1, body = 0, seen_title = 0;
|
||||
unsigned long offset = 0;
|
||||
unsigned long beginning_of_body;
|
||||
int indent = 4;
|
||||
int parents_shown = 0;
|
||||
const char *msg = commit->buffer;
|
||||
int plain_non_ascii = 0;
|
||||
char *reencoded;
|
||||
const char *encoding;
|
||||
char *buf;
|
||||
|
||||
if (fmt == CMIT_FMT_USERFORMAT)
|
||||
return format_commit_message(commit, msg, buf, space);
|
||||
return format_commit_message(commit, msg, buf_p, space_p);
|
||||
|
||||
encoding = (git_log_output_encoding
|
||||
? git_log_output_encoding
|
||||
@ -937,8 +1166,10 @@ unsigned long pretty_print_commit(enum cmit_fmt fmt,
|
||||
if (!encoding)
|
||||
encoding = "utf-8";
|
||||
reencoded = logmsg_reencode(commit, encoding);
|
||||
if (reencoded)
|
||||
if (reencoded) {
|
||||
msg = reencoded;
|
||||
len = strlen(reencoded);
|
||||
}
|
||||
|
||||
if (fmt == CMIT_FMT_ONELINE || fmt == CMIT_FMT_EMAIL)
|
||||
indent = 0;
|
||||
@ -969,137 +1200,57 @@ unsigned long pretty_print_commit(enum cmit_fmt fmt,
|
||||
}
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
const char *line = msg;
|
||||
int linelen = get_one_line(msg, len);
|
||||
pp_header(fmt, abbrev, dmode, encoding,
|
||||
commit, &msg, &len,
|
||||
&offset, buf_p, space_p);
|
||||
if (fmt != CMIT_FMT_ONELINE && !subject) {
|
||||
ALLOC_GROW(*buf_p, offset + 20, *space_p);
|
||||
(*buf_p)[offset++] = '\n';
|
||||
}
|
||||
|
||||
/* Skip excess blank lines at the beginning of body, if any... */
|
||||
for (;;) {
|
||||
int linelen = get_one_line(msg, len);
|
||||
int ll = linelen;
|
||||
if (!linelen)
|
||||
break;
|
||||
|
||||
/*
|
||||
* We want some slop for indentation and a possible
|
||||
* final "...". Thus the "+ 20".
|
||||
*/
|
||||
if (offset + linelen + 20 > space) {
|
||||
memcpy(buf + offset, " ...\n", 8);
|
||||
offset += 8;
|
||||
if (!is_empty_line(msg, &ll))
|
||||
break;
|
||||
}
|
||||
|
||||
msg += linelen;
|
||||
len -= linelen;
|
||||
if (hdr) {
|
||||
if (linelen == 1) {
|
||||
hdr = 0;
|
||||
if ((fmt != CMIT_FMT_ONELINE) && !subject)
|
||||
buf[offset++] = '\n';
|
||||
continue;
|
||||
}
|
||||
if (fmt == CMIT_FMT_RAW) {
|
||||
memcpy(buf + offset, line, linelen);
|
||||
offset += linelen;
|
||||
continue;
|
||||
}
|
||||
if (!memcmp(line, "parent ", 7)) {
|
||||
if (linelen != 48)
|
||||
die("bad parent line in commit");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!parents_shown) {
|
||||
offset += add_merge_info(fmt, buf + offset,
|
||||
commit, abbrev);
|
||||
parents_shown = 1;
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* MEDIUM == DEFAULT shows only author with dates.
|
||||
* FULL shows both authors but not dates.
|
||||
* FULLER shows both authors and dates.
|
||||
*/
|
||||
if (!memcmp(line, "author ", 7))
|
||||
offset += add_user_info("Author", fmt,
|
||||
buf + offset,
|
||||
line + 7,
|
||||
dmode,
|
||||
encoding);
|
||||
if (!memcmp(line, "committer ", 10) &&
|
||||
(fmt == CMIT_FMT_FULL || fmt == CMIT_FMT_FULLER))
|
||||
offset += add_user_info("Commit", fmt,
|
||||
buf + offset,
|
||||
line + 10,
|
||||
dmode,
|
||||
encoding);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!subject)
|
||||
body = 1;
|
||||
|
||||
if (is_empty_line(line, &linelen)) {
|
||||
if (!seen_title)
|
||||
continue;
|
||||
if (!body)
|
||||
continue;
|
||||
if (subject)
|
||||
continue;
|
||||
if (fmt == CMIT_FMT_SHORT)
|
||||
break;
|
||||
}
|
||||
|
||||
seen_title = 1;
|
||||
if (subject) {
|
||||
int slen = strlen(subject);
|
||||
memcpy(buf + offset, subject, slen);
|
||||
offset += slen;
|
||||
offset += add_rfc2047(buf + offset, line, linelen,
|
||||
encoding);
|
||||
}
|
||||
else {
|
||||
memset(buf + offset, ' ', indent);
|
||||
memcpy(buf + offset + indent, line, linelen);
|
||||
offset += linelen + indent;
|
||||
}
|
||||
buf[offset++] = '\n';
|
||||
if (fmt == CMIT_FMT_ONELINE)
|
||||
break;
|
||||
if (subject && plain_non_ascii) {
|
||||
int sz;
|
||||
char header[512];
|
||||
const char *header_fmt =
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=%s\n"
|
||||
"Content-Transfer-Encoding: 8bit\n";
|
||||
sz = snprintf(header, sizeof(header), header_fmt,
|
||||
encoding);
|
||||
if (sizeof(header) < sz)
|
||||
die("Encoding name %s too long", encoding);
|
||||
memcpy(buf + offset, header, sz);
|
||||
offset += sz;
|
||||
}
|
||||
if (after_subject) {
|
||||
int slen = strlen(after_subject);
|
||||
if (slen > space - offset - 1)
|
||||
slen = space - offset - 1;
|
||||
memcpy(buf + offset, after_subject, slen);
|
||||
offset += slen;
|
||||
after_subject = NULL;
|
||||
}
|
||||
subject = NULL;
|
||||
}
|
||||
while (offset && isspace(buf[offset-1]))
|
||||
|
||||
/* These formats treat the title line specially. */
|
||||
if (fmt == CMIT_FMT_ONELINE
|
||||
|| fmt == CMIT_FMT_EMAIL)
|
||||
pp_title_line(fmt, &msg, &len, &offset,
|
||||
buf_p, space_p, indent,
|
||||
subject, after_subject, encoding,
|
||||
plain_non_ascii);
|
||||
|
||||
beginning_of_body = offset;
|
||||
if (fmt != CMIT_FMT_ONELINE)
|
||||
pp_remainder(fmt, &msg, &len, &offset,
|
||||
buf_p, space_p, indent);
|
||||
|
||||
while (offset && isspace((*buf_p)[offset-1]))
|
||||
offset--;
|
||||
|
||||
ALLOC_GROW(*buf_p, offset + 20, *space_p);
|
||||
buf = *buf_p;
|
||||
|
||||
/* Make sure there is an EOLN for the non-oneline case */
|
||||
if (fmt != CMIT_FMT_ONELINE)
|
||||
buf[offset++] = '\n';
|
||||
|
||||
/*
|
||||
* make sure there is another EOLN to separate the headers from whatever
|
||||
* body the caller appends if we haven't already written a body
|
||||
* The caller may append additional body text in e-mail
|
||||
* format. Make sure we did not strip the blank line
|
||||
* between the header and the body.
|
||||
*/
|
||||
if (fmt == CMIT_FMT_EMAIL && !body)
|
||||
if (fmt == CMIT_FMT_EMAIL && offset <= beginning_of_body)
|
||||
buf[offset++] = '\n';
|
||||
buf[offset] = '\0';
|
||||
|
||||
free(reencoded);
|
||||
return offset;
|
||||
}
|
||||
|
2
commit.h
2
commit.h
@ -61,7 +61,7 @@ enum cmit_fmt {
|
||||
};
|
||||
|
||||
extern enum cmit_fmt get_commit_format(const char *arg);
|
||||
extern unsigned long pretty_print_commit(enum cmit_fmt fmt, const struct commit *, unsigned long len, char *buf, unsigned long space, int abbrev, const char *subject, const char *after_subject, enum date_mode dmode);
|
||||
extern unsigned long pretty_print_commit(enum cmit_fmt fmt, const struct commit *, unsigned long len, char **buf_p, unsigned long *space_p, int abbrev, const char *subject, const char *after_subject, enum date_mode dmode);
|
||||
|
||||
/** Removes the first commit from a list sorted by date, and adds all
|
||||
* of its parents.
|
||||
|
28
dir.c
28
dir.c
@ -275,7 +275,6 @@ static struct dir_entry *dir_entry_new(const char *pathname, int len) {
|
||||
struct dir_entry *ent;
|
||||
|
||||
ent = xmalloc(sizeof(*ent) + len + 1);
|
||||
ent->ignored = ent->ignored_dir = 0;
|
||||
ent->len = len;
|
||||
memcpy(ent->name, pathname, len);
|
||||
ent->name[len] = 0;
|
||||
@ -287,10 +286,19 @@ struct dir_entry *dir_add_name(struct dir_struct *dir, const char *pathname, int
|
||||
if (cache_name_pos(pathname, len) >= 0)
|
||||
return NULL;
|
||||
|
||||
ALLOC_GROW(dir->entries, dir->nr, dir->alloc);
|
||||
ALLOC_GROW(dir->entries, dir->nr+1, dir->alloc);
|
||||
return dir->entries[dir->nr++] = dir_entry_new(pathname, len);
|
||||
}
|
||||
|
||||
struct dir_entry *dir_add_ignored(struct dir_struct *dir, const char *pathname, int len)
|
||||
{
|
||||
if (cache_name_pos(pathname, len) >= 0)
|
||||
return NULL;
|
||||
|
||||
ALLOC_GROW(dir->ignored, dir->ignored_nr+1, dir->ignored_alloc);
|
||||
return dir->ignored[dir->ignored_nr++] = dir_entry_new(pathname, len);
|
||||
}
|
||||
|
||||
enum exist_status {
|
||||
index_nonexistent = 0,
|
||||
index_directory,
|
||||
@ -423,6 +431,18 @@ static int simplify_away(const char *path, int pathlen, const struct path_simpli
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int in_pathspec(const char *path, int len, const struct path_simplify *simplify)
|
||||
{
|
||||
if (simplify) {
|
||||
for (; simplify->path; simplify++) {
|
||||
if (len == simplify->len
|
||||
&& !memcmp(path, simplify->path, len))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a directory tree. We currently ignore anything but
|
||||
* directories, regular files and symlinks. That's because git
|
||||
@ -463,6 +483,9 @@ static int read_directory_recursive(struct dir_struct *dir, const char *path, co
|
||||
continue;
|
||||
|
||||
exclude = excluded(dir, fullname);
|
||||
if (exclude && dir->collect_ignored
|
||||
&& in_pathspec(fullname, baselen + len, simplify))
|
||||
dir_add_ignored(dir, fullname, baselen + len);
|
||||
if (exclude != dir->show_ignored) {
|
||||
if (!dir->show_ignored || DTYPE(de) != DT_DIR) {
|
||||
continue;
|
||||
@ -609,6 +632,7 @@ int read_directory(struct dir_struct *dir, const char *path, const char *base, i
|
||||
read_directory_recursive(dir, path, base, baselen, 0, simplify);
|
||||
free_simplify(simplify);
|
||||
qsort(dir->entries, dir->nr, sizeof(struct dir_entry *), cmp_name);
|
||||
qsort(dir->ignored, dir->ignored_nr, sizeof(struct dir_entry *), cmp_name);
|
||||
return dir->nr;
|
||||
}
|
||||
|
||||
|
9
dir.h
9
dir.h
@ -13,9 +13,7 @@
|
||||
|
||||
|
||||
struct dir_entry {
|
||||
unsigned int ignored : 1;
|
||||
unsigned int ignored_dir : 1;
|
||||
unsigned int len : 30;
|
||||
unsigned int len;
|
||||
char name[FLEX_ARRAY]; /* more */
|
||||
};
|
||||
|
||||
@ -31,11 +29,14 @@ struct exclude_list {
|
||||
|
||||
struct dir_struct {
|
||||
int nr, alloc;
|
||||
int ignored_nr, ignored_alloc;
|
||||
unsigned int show_ignored:1,
|
||||
show_other_directories:1,
|
||||
hide_empty_directories:1,
|
||||
no_gitlinks:1;
|
||||
no_gitlinks:1,
|
||||
collect_ignored:1;
|
||||
struct dir_entry **entries;
|
||||
struct dir_entry **ignored;
|
||||
|
||||
/* Exclude info */
|
||||
const char *exclude_per_dir;
|
||||
|
@ -44,33 +44,33 @@ void interp_clear_table(struct interp *table, int ninterps)
|
||||
* { "%%", "%"},
|
||||
* }
|
||||
*
|
||||
* Returns 1 on a successful substitution pass that fits in result,
|
||||
* Returns 0 on a failed or overflowing substitution pass.
|
||||
* Returns 0 on a successful substitution pass that fits in result,
|
||||
* Returns a number of bytes needed to hold the full substituted
|
||||
* string otherwise.
|
||||
*/
|
||||
|
||||
int interpolate(char *result, int reslen,
|
||||
unsigned long interpolate(char *result, unsigned long reslen,
|
||||
const char *orig,
|
||||
const struct interp *interps, int ninterps)
|
||||
{
|
||||
const char *src = orig;
|
||||
char *dest = result;
|
||||
int newlen = 0;
|
||||
unsigned long newlen = 0;
|
||||
const char *name, *value;
|
||||
int namelen, valuelen;
|
||||
unsigned long namelen, valuelen;
|
||||
int i;
|
||||
char c;
|
||||
|
||||
memset(result, 0, reslen);
|
||||
|
||||
while ((c = *src) && newlen < reslen - 1) {
|
||||
while ((c = *src)) {
|
||||
if (c == '%') {
|
||||
/* Try to match an interpolation string. */
|
||||
for (i = 0; i < ninterps; i++) {
|
||||
name = interps[i].name;
|
||||
namelen = strlen(name);
|
||||
if (strncmp(src, name, namelen) == 0) {
|
||||
if (strncmp(src, name, namelen) == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for valid interpolation. */
|
||||
@ -78,29 +78,25 @@ int interpolate(char *result, int reslen,
|
||||
value = interps[i].value;
|
||||
valuelen = strlen(value);
|
||||
|
||||
if (newlen + valuelen < reslen - 1) {
|
||||
if (newlen + valuelen + 1 < reslen) {
|
||||
/* Substitute. */
|
||||
strncpy(dest, value, valuelen);
|
||||
newlen += valuelen;
|
||||
dest += valuelen;
|
||||
src += namelen;
|
||||
} else {
|
||||
/* Something's not fitting. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
} else {
|
||||
/* Skip bogus interpolation. */
|
||||
*dest++ = *src++;
|
||||
newlen++;
|
||||
newlen += valuelen;
|
||||
src += namelen;
|
||||
continue;
|
||||
}
|
||||
|
||||
} else {
|
||||
/* Straight copy one non-interpolation character. */
|
||||
*dest++ = *src++;
|
||||
newlen++;
|
||||
}
|
||||
/* Straight copy one non-interpolation character. */
|
||||
if (newlen + 1 < reslen)
|
||||
*dest++ = *src;
|
||||
src++;
|
||||
newlen++;
|
||||
}
|
||||
|
||||
return newlen < reslen - 1;
|
||||
if (newlen + 1 < reslen)
|
||||
return 0;
|
||||
else
|
||||
return newlen + 2;
|
||||
}
|
||||
|
@ -19,8 +19,8 @@ struct interp {
|
||||
extern void interp_set_entry(struct interp *table, int slot, const char *value);
|
||||
extern void interp_clear_table(struct interp *table, int ninterps);
|
||||
|
||||
extern int interpolate(char *result, int reslen,
|
||||
const char *orig,
|
||||
const struct interp *interps, int ninterps);
|
||||
extern unsigned long interpolate(char *result, unsigned long reslen,
|
||||
const char *orig,
|
||||
const struct interp *interps, int ninterps);
|
||||
|
||||
#endif /* INTERPOLATE_H */
|
||||
|
33
log-tree.c
33
log-tree.c
@ -79,16 +79,25 @@ static int detect_any_signoff(char *letter, int size)
|
||||
return seen_head && seen_name;
|
||||
}
|
||||
|
||||
static int append_signoff(char *buf, int buf_sz, int at, const char *signoff)
|
||||
static unsigned long append_signoff(char **buf_p, unsigned long *buf_sz_p,
|
||||
unsigned long at, const char *signoff)
|
||||
{
|
||||
static const char signed_off_by[] = "Signed-off-by: ";
|
||||
int signoff_len = strlen(signoff);
|
||||
size_t signoff_len = strlen(signoff);
|
||||
int has_signoff = 0;
|
||||
char *cp = buf;
|
||||
char *cp;
|
||||
char *buf;
|
||||
unsigned long buf_sz;
|
||||
|
||||
/* Do we have enough space to add it? */
|
||||
if (buf_sz - at <= strlen(signed_off_by) + signoff_len + 3)
|
||||
return at;
|
||||
buf = *buf_p;
|
||||
buf_sz = *buf_sz_p;
|
||||
if (buf_sz <= at + strlen(signed_off_by) + signoff_len + 3) {
|
||||
buf_sz += strlen(signed_off_by) + signoff_len + 3;
|
||||
buf = xrealloc(buf, buf_sz);
|
||||
*buf_p = buf;
|
||||
*buf_sz_p = buf_sz;
|
||||
}
|
||||
cp = buf;
|
||||
|
||||
/* First see if we already have the sign-off by the signer */
|
||||
while ((cp = strstr(cp, signed_off_by))) {
|
||||
@ -133,7 +142,8 @@ static unsigned int digits_in_number(unsigned int number)
|
||||
|
||||
void show_log(struct rev_info *opt, const char *sep)
|
||||
{
|
||||
static char this_header[16384];
|
||||
char *msgbuf = NULL;
|
||||
unsigned long msgbuf_len = 0;
|
||||
struct log_info *log = opt->loginfo;
|
||||
struct commit *commit = log->commit, *parent = log->parent;
|
||||
int abbrev = opt->diffopt.abbrev;
|
||||
@ -278,14 +288,15 @@ void show_log(struct rev_info *opt, const char *sep)
|
||||
/*
|
||||
* And then the pretty-printed message itself
|
||||
*/
|
||||
len = pretty_print_commit(opt->commit_format, commit, ~0u, this_header,
|
||||
sizeof(this_header), abbrev, subject,
|
||||
len = pretty_print_commit(opt->commit_format, commit, ~0u,
|
||||
&msgbuf, &msgbuf_len, abbrev, subject,
|
||||
extra_headers, opt->date_mode);
|
||||
|
||||
if (opt->add_signoff)
|
||||
len = append_signoff(this_header, sizeof(this_header), len,
|
||||
len = append_signoff(&msgbuf, &msgbuf_len, len,
|
||||
opt->add_signoff);
|
||||
printf("%s%s%s", this_header, extra, sep);
|
||||
printf("%s%s%s", msgbuf, extra, sep);
|
||||
free(msgbuf);
|
||||
}
|
||||
|
||||
int log_tree_diff_flush(struct rev_info *opt)
|
||||
|
Loading…
Reference in New Issue
Block a user