Browse Source

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
maint
Junio C Hamano 18 years ago
parent
commit
9bee7aabcd
  1. 53
      builtin-add.c
  2. 17
      builtin-branch.c
  3. 6
      builtin-log.c
  4. 8
      builtin-rev-list.c
  5. 23
      builtin-show-branch.c
  6. 5
      cache.h
  7. 391
      commit.c
  8. 2
      commit.h
  9. 28
      dir.c
  10. 9
      dir.h
  11. 42
      interpolate.c
  12. 2
      interpolate.h
  13. 35
      log-tree.c

53
builtin-add.c

@ -40,42 +40,29 @@ static void prune_directory(struct dir_struct *dir, const char **pathspec, int p
dir->nr = dst - dir->entries; dir->nr = dst - dir->entries;


for (i = 0; i < specs; i++) { for (i = 0; i < specs; i++) {
struct stat st; if (!seen[i] && !file_exists(pathspec[i]))
const char *match; die("pathspec '%s' did not match any files",
if (seen[i]) pathspec[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);
} }
} }


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; const char *path, *base;
int baselen; int baselen;


/* Set up the default git porcelain excludes */ /* Set up the default git porcelain excludes */
memset(dir, 0, sizeof(*dir)); memset(dir, 0, sizeof(*dir));
if (!ignored_too) {
dir->collect_ignored = 1;
dir->exclude_per_dir = ".gitignore"; dir->exclude_per_dir = ".gitignore";
path = git_path("info/exclude"); path = git_path("info/exclude");
if (!access(path, R_OK)) if (!access(path, R_OK))
add_excludes_from_file(dir, path); add_excludes_from_file(dir, path);
if (!access(excludes_file, R_OK)) if (!access(excludes_file, R_OK))
add_excludes_from_file(dir, excludes_file); add_excludes_from_file(dir, excludes_file);
}


/* /*
* Calculate common prefix for the pathspec, and * 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); pathspec = get_pathspec(prefix, argv + i);


fill_directory(&dir, pathspec); fill_directory(&dir, pathspec, ignored_too);


if (show_only) { if (show_only) {
const char *sep = "", *eof = ""; const char *sep = "", *eof = "";
for (i = 0; i < dir.nr; i++) { for (i = 0; i < dir.nr; i++) {
if (!ignored_too && dir.entries[i]->ignored)
continue;
printf("%s%s", sep, dir.entries[i]->name); printf("%s%s", sep, dir.entries[i]->name);
sep = " "; sep = " ";
eof = "\n"; eof = "\n";
@ -237,26 +222,14 @@ int cmd_add(int argc, const char **argv, const char *prefix)
if (read_cache() < 0) if (read_cache() < 0)
die("index file corrupt"); die("index file corrupt");


if (!ignored_too) { if (dir.ignored_nr) {
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); fprintf(stderr, ignore_warning);
for (i = 0; i < dir.nr; i++) { for (i = 0; i < dir.ignored_nr; i++) {
if (!dir.entries[i]->ignored) fprintf(stderr, "%s\n", dir.ignored[i]->name);
continue;
fprintf(stderr, "%s", dir.entries[i]->name);
if (dir.entries[i]->ignored_dir)
fprintf(stderr, " (directory)");
fputc('\n', stderr);
} }
fprintf(stderr, fprintf(stderr, "Use -f if you really want to add them.\n");
"Use -f if you really want to add them.\n");
exit(1); exit(1);
} }
}


for (i = 0; i < dir.nr; i++) for (i = 0; i < dir.nr; i++)
add_file_to_cache(dir.entries[i]->name, verbose); add_file_to_cache(dir.entries[i]->name, verbose);

17
builtin-branch.c

@ -247,7 +247,6 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,
char c; char c;
int color; int color;
struct commit *commit; struct commit *commit;
char subject[256];


switch (item->kind) { switch (item->kind) {
case REF_LOCAL_BRANCH: case REF_LOCAL_BRANCH:
@ -268,17 +267,23 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,
} }


if (verbose) { if (verbose) {
char *subject = NULL;
unsigned long subject_len = 0;
const char *sub = " **** invalid ref ****";

commit = lookup_commit(item->sha1); commit = lookup_commit(item->sha1);
if (commit && !parse_commit(commit)) if (commit && !parse_commit(commit)) {
pretty_print_commit(CMIT_FMT_ONELINE, commit, ~0, pretty_print_commit(CMIT_FMT_ONELINE, commit, ~0,
subject, sizeof(subject), 0, &subject, &subject_len, 0,
NULL, NULL, 0); NULL, NULL, 0);
else sub = subject;
strcpy(subject, " **** invalid ref ****"); }
printf("%c %s%-*s%s %s %s\n", c, branch_get_color(color), printf("%c %s%-*s%s %s %s\n", c, branch_get_color(color),
maxwidth, item->name, maxwidth, item->name,
branch_get_color(COLOR_BRANCH_RESET), 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 { } else {
printf("%c %s%s%s\n", c, branch_get_color(color), item->name, printf("%c %s%s%s\n", c, branch_get_color(color), item->name,
branch_get_color(COLOR_BRANCH_RESET)); branch_get_color(COLOR_BRANCH_RESET));

6
builtin-log.c

@ -742,11 +742,13 @@ int cmd_cherry(int argc, const char **argv, const char *prefix)
sign = '-'; sign = '-';


if (verbose) { if (verbose) {
static char buf[16384]; char *buf = NULL;
unsigned long buflen = 0;
pretty_print_commit(CMIT_FMT_ONELINE, commit, ~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, printf("%c %s %s\n", sign,
sha1_to_hex(commit->object.sha1), buf); sha1_to_hex(commit->object.sha1), buf);
free(buf);
} }
else { else {
printf("%c %s\n", sign, printf("%c %s\n", sign,

8
builtin-rev-list.c

@ -92,11 +92,13 @@ static void show_commit(struct commit *commit)
putchar('\n'); putchar('\n');


if (revs.verbose_header) { 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_print_commit(revs.commit_format, commit, ~0,
pretty_header, sizeof(pretty_header), &buf, &buflen,
revs.abbrev, NULL, NULL, revs.date_mode); revs.abbrev, NULL, NULL, revs.date_mode);
printf("%s%c", pretty_header, hdr_termination); printf("%s%c", buf, hdr_termination);
free(buf);
} }
fflush(stdout); fflush(stdout);
if (commit->parents) { if (commit->parents) {

23
builtin-show-branch.c

@ -259,17 +259,19 @@ static void join_revs(struct commit_list **list_p,


static void show_one_commit(struct commit *commit, int no_name) 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; struct commit_name *name = commit->util;
if (commit->object.parsed)
if (commit->object.parsed) {
pretty_print_commit(CMIT_FMT_ONELINE, commit, ~0, pretty_print_commit(CMIT_FMT_ONELINE, commit, ~0,
pretty, sizeof(pretty), 0, NULL, NULL, 0); &pretty, &pretty_len,
else 0, NULL, NULL, 0);
strcpy(pretty, "(unavailable)"); pretty_str = pretty;
if (!prefixcmp(pretty, "[PATCH] ")) }
cp = pretty + 8; if (!prefixcmp(pretty_str, "[PATCH] "))
else pretty_str += 8;
cp = pretty;


if (!no_name) { if (!no_name) {
if (name && name->head_name) { if (name && name->head_name) {
@ -286,7 +288,8 @@ static void show_one_commit(struct commit *commit, int no_name)
printf("[%s] ", printf("[%s] ",
find_unique_abbrev(commit->object.sha1, 7)); find_unique_abbrev(commit->object.sha1, 7));
} }
puts(cp); puts(pretty_str);
free(pretty);
} }


static char *ref_name[MAX_REVS + 1]; static char *ref_name[MAX_REVS + 1];

5
cache.h

@ -234,7 +234,10 @@ extern void verify_non_filename(const char *prefix, const char *name);
*/ */
#define ALLOC_GROW(x, nr, alloc) \ #define ALLOC_GROW(x, nr, alloc) \
do { \ do { \
if ((nr) >= alloc) { \ if ((nr) > alloc) { \
if (alloc_nr(alloc) < (nr)) \
alloc = (nr); \
else \
alloc = alloc_nr(alloc); \ alloc = alloc_nr(alloc); \
x = xrealloc((x), alloc * sizeof(*(x))); \ x = xrealloc((x), alloc * sizeof(*(x))); \
} \ } \

391
commit.c

@ -529,6 +529,14 @@ static int add_rfc2047(char *buf, const char *line, int len,
return bp - buf; 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, static int add_user_info(const char *what, enum cmit_fmt fmt, char *buf,
const char *line, enum date_mode dmode, const char *line, enum date_mode dmode,
const char *encoding) 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, 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[] = { struct interp table[] = {
{ "%H" }, /* commit hash */ { "%H" }, /* commit hash */
@ -905,31 +913,252 @@ static long format_commit_message(const struct commit *commit,
if (!table[i].value) if (!table[i].value)
interp_set_entry(table, i, "<unknown>"); 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)); 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, unsigned long pretty_print_commit(enum cmit_fmt fmt,
const struct commit *commit, const struct commit *commit,
unsigned long len, unsigned long len,
char *buf, unsigned long space, char **buf_p, unsigned long *space_p,
int abbrev, const char *subject, int abbrev, const char *subject,
const char *after_subject, const char *after_subject,
enum date_mode dmode) enum date_mode dmode)
{ {
int hdr = 1, body = 0, seen_title = 0;
unsigned long offset = 0; unsigned long offset = 0;
unsigned long beginning_of_body;
int indent = 4; int indent = 4;
int parents_shown = 0;
const char *msg = commit->buffer; const char *msg = commit->buffer;
int plain_non_ascii = 0; int plain_non_ascii = 0;
char *reencoded; char *reencoded;
const char *encoding; const char *encoding;
char *buf;


if (fmt == CMIT_FMT_USERFORMAT) 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 encoding = (git_log_output_encoding
? git_log_output_encoding ? git_log_output_encoding
@ -937,8 +1166,10 @@ unsigned long pretty_print_commit(enum cmit_fmt fmt,
if (!encoding) if (!encoding)
encoding = "utf-8"; encoding = "utf-8";
reencoded = logmsg_reencode(commit, encoding); reencoded = logmsg_reencode(commit, encoding);
if (reencoded) if (reencoded) {
msg = reencoded; msg = reencoded;
len = strlen(reencoded);
}


if (fmt == CMIT_FMT_ONELINE || fmt == CMIT_FMT_EMAIL) if (fmt == CMIT_FMT_ONELINE || fmt == CMIT_FMT_EMAIL)
indent = 0; indent = 0;
@ -969,137 +1200,57 @@ unsigned long pretty_print_commit(enum cmit_fmt fmt,
} }
} }


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 (;;) { for (;;) {
const char *line = msg;
int linelen = get_one_line(msg, len); int linelen = get_one_line(msg, len);

int ll = linelen;
if (!linelen) if (!linelen)
break; break;

if (!is_empty_line(msg, &ll))
/*
* 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;
break; break;
}

msg += linelen; msg += linelen;
len -= 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) /* These formats treat the title line specially. */
body = 1; 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);


if (is_empty_line(line, &linelen)) { beginning_of_body = offset;
if (!seen_title) if (fmt != CMIT_FMT_ONELINE)
continue; pp_remainder(fmt, &msg, &len, &offset,
if (!body) buf_p, space_p, indent);
continue;
if (subject)
continue;
if (fmt == CMIT_FMT_SHORT)
break;
}


seen_title = 1; while (offset && isspace((*buf_p)[offset-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]))
offset--; offset--;

ALLOC_GROW(*buf_p, offset + 20, *space_p);
buf = *buf_p;

/* Make sure there is an EOLN for the non-oneline case */ /* Make sure there is an EOLN for the non-oneline case */
if (fmt != CMIT_FMT_ONELINE) if (fmt != CMIT_FMT_ONELINE)
buf[offset++] = '\n'; buf[offset++] = '\n';

/* /*
* make sure there is another EOLN to separate the headers from whatever * The caller may append additional body text in e-mail
* body the caller appends if we haven't already written a body * 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++] = '\n';
buf[offset] = '\0'; buf[offset] = '\0';

free(reencoded); free(reencoded);
return offset; return offset;
} }

2
commit.h

@ -61,7 +61,7 @@ enum cmit_fmt {
}; };


extern enum cmit_fmt get_commit_format(const char *arg); 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 /** Removes the first commit from a list sorted by date, and adds all
* of its parents. * of its parents.

28
dir.c

@ -275,7 +275,6 @@ static struct dir_entry *dir_entry_new(const char *pathname, int len) {
struct dir_entry *ent; struct dir_entry *ent;


ent = xmalloc(sizeof(*ent) + len + 1); ent = xmalloc(sizeof(*ent) + len + 1);
ent->ignored = ent->ignored_dir = 0;
ent->len = len; ent->len = len;
memcpy(ent->name, pathname, len); memcpy(ent->name, pathname, len);
ent->name[len] = 0; 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) if (cache_name_pos(pathname, len) >= 0)
return NULL; 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); 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 { enum exist_status {
index_nonexistent = 0, index_nonexistent = 0,
index_directory, index_directory,
@ -423,6 +431,18 @@ static int simplify_away(const char *path, int pathlen, const struct path_simpli
return 0; 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 * Read a directory tree. We currently ignore anything but
* directories, regular files and symlinks. That's because git * 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; continue;


exclude = excluded(dir, fullname); 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 (exclude != dir->show_ignored) {
if (!dir->show_ignored || DTYPE(de) != DT_DIR) { if (!dir->show_ignored || DTYPE(de) != DT_DIR) {
continue; 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); read_directory_recursive(dir, path, base, baselen, 0, simplify);
free_simplify(simplify); free_simplify(simplify);
qsort(dir->entries, dir->nr, sizeof(struct dir_entry *), cmp_name); 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; return dir->nr;
} }



9
dir.h

@ -13,9 +13,7 @@




struct dir_entry { struct dir_entry {
unsigned int ignored : 1; unsigned int len;
unsigned int ignored_dir : 1;
unsigned int len : 30;
char name[FLEX_ARRAY]; /* more */ char name[FLEX_ARRAY]; /* more */
}; };


@ -31,11 +29,14 @@ struct exclude_list {


struct dir_struct { struct dir_struct {
int nr, alloc; int nr, alloc;
int ignored_nr, ignored_alloc;
unsigned int show_ignored:1, unsigned int show_ignored:1,
show_other_directories:1, show_other_directories:1,
hide_empty_directories:1, hide_empty_directories:1,
no_gitlinks:1; no_gitlinks:1,
collect_ignored:1;
struct dir_entry **entries; struct dir_entry **entries;
struct dir_entry **ignored;


/* Exclude info */ /* Exclude info */
const char *exclude_per_dir; const char *exclude_per_dir;

42
interpolate.c

@ -44,63 +44,59 @@ void interp_clear_table(struct interp *table, int ninterps)
* { "%%", "%"}, * { "%%", "%"},
* } * }
* *
* Returns 1 on a successful substitution pass that fits in result, * Returns 0 on a successful substitution pass that fits in result,
* Returns 0 on a failed or overflowing substitution pass. * 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 char *orig,
const struct interp *interps, int ninterps) const struct interp *interps, int ninterps)
{ {
const char *src = orig; const char *src = orig;
char *dest = result; char *dest = result;
int newlen = 0; unsigned long newlen = 0;
const char *name, *value; const char *name, *value;
int namelen, valuelen; unsigned long namelen, valuelen;
int i; int i;
char c; char c;


memset(result, 0, reslen); memset(result, 0, reslen);


while ((c = *src) && newlen < reslen - 1) { while ((c = *src)) {
if (c == '%') { if (c == '%') {
/* Try to match an interpolation string. */ /* Try to match an interpolation string. */
for (i = 0; i < ninterps; i++) { for (i = 0; i < ninterps; i++) {
name = interps[i].name; name = interps[i].name;
namelen = strlen(name); namelen = strlen(name);
if (strncmp(src, name, namelen) == 0) { if (strncmp(src, name, namelen) == 0)
break; break;
} }
}


/* Check for valid interpolation. */ /* Check for valid interpolation. */
if (i < ninterps) { if (i < ninterps) {
value = interps[i].value; value = interps[i].value;
valuelen = strlen(value); valuelen = strlen(value);


if (newlen + valuelen < reslen - 1) { if (newlen + valuelen + 1 < reslen) {
/* Substitute. */ /* Substitute. */
strncpy(dest, value, valuelen); strncpy(dest, value, valuelen);
newlen += valuelen;
dest += valuelen; dest += valuelen;
}
newlen += valuelen;
src += namelen; src += namelen;
} else { continue;
/* Something's not fitting. */
return 0;
} }

} else {
/* Skip bogus interpolation. */
*dest++ = *src++;
newlen++;
} }

} else {
/* Straight copy one non-interpolation character. */ /* Straight copy one non-interpolation character. */
*dest++ = *src++; if (newlen + 1 < reslen)
*dest++ = *src;
src++;
newlen++; newlen++;
} }
}


return newlen < reslen - 1; if (newlen + 1 < reslen)
return 0;
else
return newlen + 2;
} }

2
interpolate.h

@ -19,7 +19,7 @@ struct interp {
extern void interp_set_entry(struct interp *table, int slot, const char *value); extern void interp_set_entry(struct interp *table, int slot, const char *value);
extern void interp_clear_table(struct interp *table, int ninterps); extern void interp_clear_table(struct interp *table, int ninterps);


extern int interpolate(char *result, int reslen, extern unsigned long interpolate(char *result, unsigned long reslen,
const char *orig, const char *orig,
const struct interp *interps, int ninterps); const struct interp *interps, int ninterps);



35
log-tree.c

@ -79,16 +79,25 @@ static int detect_any_signoff(char *letter, int size)
return seen_head && seen_name; 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: "; static const char signed_off_by[] = "Signed-off-by: ";
int signoff_len = strlen(signoff); size_t signoff_len = strlen(signoff);
int has_signoff = 0; int has_signoff = 0;
char *cp = buf; char *cp;

char *buf;
/* Do we have enough space to add it? */ unsigned long buf_sz;
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 */ /* First see if we already have the sign-off by the signer */
while ((cp = strstr(cp, signed_off_by))) { 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) 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 log_info *log = opt->loginfo;
struct commit *commit = log->commit, *parent = log->parent; struct commit *commit = log->commit, *parent = log->parent;
int abbrev = opt->diffopt.abbrev; 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 * And then the pretty-printed message itself
*/ */
len = pretty_print_commit(opt->commit_format, commit, ~0u, this_header, len = pretty_print_commit(opt->commit_format, commit, ~0u,
sizeof(this_header), abbrev, subject, &msgbuf, &msgbuf_len, abbrev, subject,
extra_headers, opt->date_mode); extra_headers, opt->date_mode);


if (opt->add_signoff) if (opt->add_signoff)
len = append_signoff(this_header, sizeof(this_header), len, len = append_signoff(&msgbuf, &msgbuf_len, len,
opt->add_signoff); 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) int log_tree_diff_flush(struct rev_info *opt)

Loading…
Cancel
Save