Merge branch 'jk/commit-buffer-length' into maint

A handful of code paths had to read the commit object more than
once when showing header fields that are usually not parsed.  The
internal data structure to keep track of the contents of the commit
object has been updated to reduce the need for this double-reading,
and to allow the caller find the length of the object.

* jk/commit-buffer-length:
  reuse cached commit buffer when parsing signatures
  commit: record buffer length in cache
  commit: convert commit->buffer to a slab
  commit-slab: provide a static initializer
  use get_commit_buffer everywhere
  convert logmsg_reencode to get_commit_buffer
  use get_commit_buffer to avoid duplicate code
  use get_cached_commit_buffer where appropriate
  provide helpers to access the commit buffer
  provide a helper to set the commit buffer
  provide a helper to free commit buffer
  sequencer: use logmsg_reencode in get_message
  logmsg_reencode: return const buffer
  do not create "struct commit" with xcalloc
  commit: push commit_index update into alloc_commit_node
  alloc: include any-object allocations in alloc_report
  replace dangerous uses of strbuf_attach
  commit_tree: take a pointer/len pair rather than a const strbuf
This commit is contained in:
Junio C Hamano
2014-07-16 11:16:38 -07:00
27 changed files with 285 additions and 198 deletions

View File

@ -606,29 +606,16 @@ static char *replace_encoding_header(char *buf, const char *encoding)
return strbuf_detach(&tmp, NULL);
}
char *logmsg_reencode(const struct commit *commit,
char **commit_encoding,
const char *output_encoding)
const char *logmsg_reencode(const struct commit *commit,
char **commit_encoding,
const char *output_encoding)
{
static const char *utf8 = "UTF-8";
const char *use_encoding;
char *encoding;
char *msg = commit->buffer;
const char *msg = get_commit_buffer(commit, NULL);
char *out;
if (!msg) {
enum object_type type;
unsigned long size;
msg = read_sha1_file(commit->object.sha1, &type, &size);
if (!msg)
die("Cannot read commit object %s",
sha1_to_hex(commit->object.sha1));
if (type != OBJ_COMMIT)
die("Expected commit for '%s', got %s",
sha1_to_hex(commit->object.sha1), typename(type));
}
if (!output_encoding || !*output_encoding) {
if (commit_encoding)
*commit_encoding =
@ -652,12 +639,13 @@ char *logmsg_reencode(const struct commit *commit,
* Otherwise, we still want to munge the encoding header in the
* result, which will be done by modifying the buffer. If we
* are using a fresh copy, we can reuse it. But if we are using
* the cached copy from commit->buffer, we need to duplicate it
* to avoid munging commit->buffer.
* the cached copy from get_commit_buffer, we need to duplicate it
* to avoid munging the cached copy.
*/
out = msg;
if (out == commit->buffer)
out = xstrdup(out);
if (msg == get_cached_commit_buffer(commit, NULL))
out = xstrdup(msg);
else
out = (char *)msg;
}
else {
/*
@ -667,8 +655,8 @@ char *logmsg_reencode(const struct commit *commit,
* copy, we can free it.
*/
out = reencode_string(msg, output_encoding, use_encoding);
if (out && msg != commit->buffer)
free(msg);
if (out)
unuse_commit_buffer(commit, msg);
}
/*
@ -687,12 +675,6 @@ char *logmsg_reencode(const struct commit *commit,
return out ? out : msg;
}
void logmsg_free(char *msg, const struct commit *commit)
{
if (msg != commit->buffer)
free(msg);
}
static int mailmap_name(const char **email, size_t *email_len,
const char **name, size_t *name_len)
{
@ -796,7 +778,7 @@ struct format_commit_context {
struct signature_check signature_check;
enum flush_type flush_type;
enum trunc_type truncate;
char *message;
const char *message;
char *commit_encoding;
size_t width, indent1, indent2;
int auto_color;
@ -1536,7 +1518,7 @@ void format_commit_message(const struct commit *commit,
}
free(context.commit_encoding);
logmsg_free(context.message, commit);
unuse_commit_buffer(commit, context.message);
free(context.signature_check.gpg_output);
free(context.signature_check.signer);
}
@ -1705,7 +1687,7 @@ void pretty_print_commit(struct pretty_print_context *pp,
unsigned long beginning_of_body;
int indent = 4;
const char *msg;
char *reencoded;
const char *reencoded;
const char *encoding;
int need_8bit_cte = pp->need_8bit_cte;
@ -1772,7 +1754,7 @@ void pretty_print_commit(struct pretty_print_context *pp,
if (pp->fmt == CMIT_FMT_EMAIL && sb->len <= beginning_of_body)
strbuf_addch(sb, '\n');
logmsg_free(reencoded, commit);
unuse_commit_buffer(commit, reencoded);
}
void pp_commit_easy(enum cmit_fmt fmt, const struct commit *commit,