strbuf_release(&line);
}
+/*
+ * This isn't as simple as passing sb->buf and sb->len, because we
+ * want to transfer ownership of the buffer to the commit (so we
+ * must use detach).
+ */
+static void set_commit_buffer_from_strbuf(struct commit *c, struct strbuf *sb)
+{
+ size_t len;
+ void *buf = strbuf_detach(sb, &len);
+ set_commit_buffer(c, buf, len);
+}
+
/*
* Prepare a dummy commit that represents the work tree (or staged) item.
* Note that annotating work tree item never works in the reverse.
ident, ident, path,
(!contents_from ? path :
(!strcmp(contents_from, "-") ? "standard input" : contents_from)));
- set_commit_buffer(commit, strbuf_detach(&msg, NULL));
+ set_commit_buffer_from_strbuf(commit, &msg);
if (!contents_from || strcmp("-", contents_from)) {
struct stat st;
rev->diffopt.output_format = DIFF_FORMAT_CALLBACK;
parse_commit_or_die(commit);
- commit_buffer = get_commit_buffer(commit);
+ commit_buffer = get_commit_buffer(commit, NULL);
author = strstr(commit_buffer, "\nauthor ");
if (!author)
die ("Could not find author in commit %s",
const char *field;
field = (which == 'a') ? "\nauthor " : "\ncommitter ";
- buffer = get_commit_buffer(commit);
+ buffer = get_commit_buffer(commit, NULL);
name = strstr(buffer, field);
if (!name)
return;
}
if (obj->type == OBJ_COMMIT) {
struct commit *commit = (struct commit *) obj;
- if (detach_commit_buffer(commit) != data)
+ if (detach_commit_buffer(commit, NULL) != data)
die("BUG: parse_object_buffer transmogrified our buffer");
}
obj->flags |= FLAG_CHECKED;
&need_8bit_cte);
for (i = 0; !need_8bit_cte && i < nr; i++) {
- const char *buf = get_commit_buffer(list[i]);
+ const char *buf = get_commit_buffer(list[i], NULL);
if (has_non_ascii(buf))
need_8bit_cte = 1;
unuse_commit_buffer(list[i], buf);
else
putchar('\n');
- if (revs->verbose_header && get_cached_commit_buffer(commit)) {
+ if (revs->verbose_header && get_cached_commit_buffer(commit, NULL)) {
struct strbuf buf = STRBUF_INIT;
struct pretty_print_context ctx = {0};
ctx.abbrev = revs->abbrev;
return 0;
}
-define_commit_slab(buffer_slab, void *);
+struct commit_buffer {
+ void *buffer;
+ unsigned long size;
+};
+define_commit_slab(buffer_slab, struct commit_buffer);
static struct buffer_slab buffer_slab = COMMIT_SLAB_INIT(1, buffer_slab);
-void set_commit_buffer(struct commit *commit, void *buffer)
+void set_commit_buffer(struct commit *commit, void *buffer, unsigned long size)
{
- *buffer_slab_at(&buffer_slab, commit) = buffer;
+ struct commit_buffer *v = buffer_slab_at(&buffer_slab, commit);
+ v->buffer = buffer;
+ v->size = size;
}
-const void *get_cached_commit_buffer(const struct commit *commit)
+const void *get_cached_commit_buffer(const struct commit *commit, unsigned long *sizep)
{
- return *buffer_slab_at(&buffer_slab, commit);
+ struct commit_buffer *v = buffer_slab_at(&buffer_slab, commit);
+ if (sizep)
+ *sizep = v->size;
+ return v->buffer;
}
-const void *get_commit_buffer(const struct commit *commit)
+const void *get_commit_buffer(const struct commit *commit, unsigned long *sizep)
{
- const void *ret = get_cached_commit_buffer(commit);
+ const void *ret = get_cached_commit_buffer(commit, sizep);
if (!ret) {
enum object_type type;
unsigned long size;
if (type != OBJ_COMMIT)
die("expected commit for %s, got %s",
sha1_to_hex(commit->object.sha1), typename(type));
+ if (sizep)
+ *sizep = size;
}
return ret;
}
void unuse_commit_buffer(const struct commit *commit, const void *buffer)
{
- void *cached = *buffer_slab_at(&buffer_slab, commit);
- if (cached != buffer)
+ struct commit_buffer *v = buffer_slab_at(&buffer_slab, commit);
+ if (v->buffer != buffer)
free((void *)buffer);
}
void free_commit_buffer(struct commit *commit)
{
- void **b = buffer_slab_at(&buffer_slab, commit);
- free(*b);
- *b = NULL;
+ struct commit_buffer *v = buffer_slab_at(&buffer_slab, commit);
+ free(v->buffer);
+ v->buffer = NULL;
+ v->size = 0;
}
-const void *detach_commit_buffer(struct commit *commit)
+const void *detach_commit_buffer(struct commit *commit, unsigned long *sizep)
{
- void **b = buffer_slab_at(&buffer_slab, commit);
- void *ret = *b;
- *b = NULL;
+ struct commit_buffer *v = buffer_slab_at(&buffer_slab, commit);
+ void *ret;
+
+ ret = v->buffer;
+ if (sizep)
+ *sizep = v->size;
+
+ v->buffer = NULL;
+ v->size = 0;
return ret;
}
}
ret = parse_commit_buffer(item, buffer, size);
if (save_commit_buffer && !ret) {
- set_commit_buffer(item, buffer);
+ set_commit_buffer(item, buffer, size);
return 0;
}
free(buffer);
struct commit *commit)
{
const char *buf, *line_end, *ident_line;
- const char *buffer = get_commit_buffer(commit);
+ const char *buffer = get_commit_buffer(commit, NULL);
struct ident_split ident;
char *date_end;
unsigned long date;
* Associate an object buffer with the commit. The ownership of the
* memory is handed over to the commit, and must be free()-able.
*/
-void set_commit_buffer(struct commit *, void *buffer);
+void set_commit_buffer(struct commit *, void *buffer, unsigned long size);
/*
* Get any cached object buffer associated with the commit. Returns NULL
* if none. The resulting memory should not be freed.
*/
-const void *get_cached_commit_buffer(const struct commit *);
+const void *get_cached_commit_buffer(const struct commit *, unsigned long *size);
/*
* Get the commit's object contents, either from cache or by reading the object
* from disk. The resulting memory should not be modified, and must be given
* to unuse_commit_buffer when the caller is done.
*/
-const void *get_commit_buffer(const struct commit *);
+const void *get_commit_buffer(const struct commit *, unsigned long *size);
/*
* Tell the commit subsytem that we are done with a particular commit buffer.
* Disassociate any cached object buffer from the commit, but do not free it.
* The buffer (or NULL, if none) is returned.
*/
-const void *detach_commit_buffer(struct commit *);
+const void *detach_commit_buffer(struct commit *, unsigned long *sizep);
/* Find beginning and length of commit subject. */
int find_commit_subject(const char *commit_buffer, const char **subject);
static int fsck_commit(struct commit *commit, fsck_error error_func)
{
- const char *buffer = get_commit_buffer(commit);
+ const char *buffer = get_commit_buffer(commit, NULL);
int ret = fsck_commit_buffer(commit, buffer, error_func);
unuse_commit_buffer(commit, buffer);
return ret;
show_mergetag(opt, commit);
}
- if (!get_cached_commit_buffer(commit))
+ if (!get_cached_commit_buffer(commit, NULL))
return;
if (opt->show_notes) {
printf(_("(bad commit)\n"));
else {
const char *title;
- const char *msg = get_commit_buffer(commit);
+ const char *msg = get_commit_buffer(commit, NULL);
int len = find_commit_subject(msg, &title);
if (len)
printf("%.*s\n", len, title);
DIR *dir;
struct dirent *e;
struct strbuf path = STRBUF_INIT;
- const char *buffer = get_commit_buffer(partial_commit);
+ const char *buffer = get_commit_buffer(partial_commit, NULL);
const char *msg = strstr(buffer, "\n\n");
int baselen;
if (commit) {
if (parse_commit_buffer(commit, buffer, size))
return NULL;
- if (!get_cached_commit_buffer(commit)) {
- set_commit_buffer(commit, buffer);
+ if (!get_cached_commit_buffer(commit, NULL)) {
+ set_commit_buffer(commit, buffer, size);
*eaten_p = 1;
}
obj = &commit->object;
static const char *utf8 = "UTF-8";
const char *use_encoding;
char *encoding;
- const char *msg = get_commit_buffer(commit);
+ const char *msg = get_commit_buffer(commit, NULL);
char *out;
if (!output_encoding || !*output_encoding) {
* the cached copy from get_commit_buffer, we need to duplicate it
* to avoid munging the cached copy.
*/
- if (msg == get_cached_commit_buffer(commit))
+ if (msg == get_cached_commit_buffer(commit, NULL))
out = xstrdup(msg);
else
out = (char *)msg;
int subject_len;
for (cur = todo_list; cur; cur = cur->next) {
- const char *commit_buffer = get_commit_buffer(cur->item);
+ const char *commit_buffer = get_commit_buffer(cur->item, NULL);
sha1_abbrev = find_unique_abbrev(cur->item->object.sha1, DEFAULT_ABBREV);
subject_len = find_commit_subject(commit_buffer, &subject);
strbuf_addf(buf, "%s %s %.*s\n", action_str, sha1_abbrev,
commit = pop_most_recent_commit(&list, ONELINE_SEEN);
if (!parse_object(commit->object.sha1))
continue;
- buf = get_commit_buffer(commit);
+ buf = get_commit_buffer(commit, NULL);
p = strstr(buf, "\n\n");
matches = p && !regexec(®ex, p + 2, 0, NULL, 0);
unuse_commit_buffer(commit, buf);