#include "pkt-line.h"
#include "utf8.h"
#include "interpolate.h"
+#include "diff.h"
+#include "revision.h"
int save_commit_buffer = 1;
struct commit *lookup_commit(const unsigned char *sha1)
{
struct object *obj = lookup_object(sha1);
- if (!obj) {
- struct commit *ret = alloc_commit_node();
- created_object(sha1, &ret->object);
- ret->object.type = OBJ_COMMIT;
- return ret;
- }
+ if (!obj)
+ return create_object(sha1, OBJ_COMMIT, alloc_commit_node());
if (!obj->type)
obj->type = OBJ_COMMIT;
return check_commit(obj, sha1, 0);
int parse_commit(struct commit *item)
{
- char type[20];
+ enum object_type type;
void *buffer;
unsigned long size;
int ret;
if (item->object.parsed)
return 0;
- buffer = read_sha1_file(item->object.sha1, type, &size);
+ buffer = read_sha1_file(item->object.sha1, &type, &size);
if (!buffer)
return error("Could not read %s",
sha1_to_hex(item->object.sha1));
- if (strcmp(type, commit_type)) {
+ if (type != OBJ_COMMIT) {
free(buffer);
return error("Object %s not a commit",
sha1_to_hex(item->object.sha1));
}
}
-static char *replace_encoding_header(char *buf, char *encoding)
+static char *replace_encoding_header(char *buf, const char *encoding)
{
char *encoding_header = strstr(buf, "\nencoding ");
+ char *header_end = strstr(buf, "\n\n");
char *end_of_encoding_header;
int encoding_header_pos;
int encoding_header_len;
int need_len;
int buflen = strlen(buf) + 1;
- if (!encoding_header)
- return buf; /* should not happen but be defensive */
+ if (!header_end)
+ header_end = buf + buflen;
+ if (!encoding_header || encoding_header >= header_end)
+ return buf;
encoding_header++;
end_of_encoding_header = strchr(encoding_header, '\n');
if (!end_of_encoding_header)
}
static char *logmsg_reencode(const struct commit *commit,
- char *output_encoding)
+ const char *output_encoding)
{
+ static const char *utf8 = "utf-8";
+ const char *use_encoding;
char *encoding;
char *out;
- char *utf8 = "utf-8";
if (!*output_encoding)
return NULL;
encoding = get_header(commit, "encoding");
- if (!encoding)
- encoding = utf8;
- if (!strcmp(encoding, output_encoding))
- out = strdup(commit->buffer);
+ use_encoding = encoding ? encoding : utf8;
+ if (!strcmp(use_encoding, output_encoding))
+ out = xstrdup(commit->buffer);
else
out = reencode_string(commit->buffer,
- output_encoding, encoding);
+ output_encoding, use_encoding);
if (out)
out = replace_encoding_header(out, output_encoding);
- if (encoding != utf8)
- free(encoding);
- if (!out)
- return NULL;
+ free(encoding);
return out;
}
if (msg + start == ep)
return;
- table[5].value = xstrndup(msg + start, ep - msg + start);
+ table[5].value = xstrndup(msg + start, ep - (msg + start));
/* parse tz */
for (start = ep - msg + 1; start < len && isspace(msg[start]); start++)
{ "%Cgreen" }, /* green */
{ "%Cblue" }, /* blue */
{ "%Creset" }, /* reset color */
- { "%n" } /* newline */
+ { "%n" }, /* newline */
+ { "%m" }, /* left/right/bottom */
};
enum interp_index {
IHASH = 0, IHASH_ABBREV,
ISUBJECT,
IBODY,
IRED, IGREEN, IBLUE, IRESET_COLOR,
- INEWLINE
+ INEWLINE,
+ ILEFT_RIGHT,
};
struct commit_list *p;
char parents[1024];
int i;
enum { HEADER, SUBJECT, BODY } state;
- if (INEWLINE + 1 != ARRAY_SIZE(table))
+ if (ILEFT_RIGHT + 1 != ARRAY_SIZE(table))
die("invalid interp table!");
/* these are independent of the commit */
interp_set_entry(table, ITREE_ABBREV,
find_unique_abbrev(commit->tree->object.sha1,
DEFAULT_ABBREV));
+ interp_set_entry(table, ILEFT_RIGHT,
+ (commit->object.flags & BOUNDARY)
+ ? "-"
+ : (commit->object.flags & SYMMETRIC_LEFT)
+ ? "<"
+ : ">");
+
+ parents[1] = 0;
for (i = 0, p = commit->parents;
p && i < sizeof(parents) - 1;
p = p->next)
- i += snprintf(parents + i, sizeof(parents) - i - 1, "%s ",
+ i += snprintf(parents + i, sizeof(parents) - i - 1, " %s",
sha1_to_hex(p->item->object.sha1));
- interp_set_entry(table, IPARENTS, parents);
+ interp_set_entry(table, IPARENTS, parents + 1);
+
+ parents[1] = 0;
for (i = 0, p = commit->parents;
p && i < sizeof(parents) - 1;
p = p->next)
- i += snprintf(parents + i, sizeof(parents) - i - 1, "%s ",
+ i += snprintf(parents + i, sizeof(parents) - i - 1, " %s",
find_unique_abbrev(p->item->object.sha1,
DEFAULT_ABBREV));
- interp_set_entry(table, IPARENTS_ABBREV, parents);
+ interp_set_entry(table, IPARENTS_ABBREV, parents + 1);
for (i = 0, state = HEADER; msg[i] && state < BODY; i++) {
int eol;
fill_person(table + ICOMMITTER_NAME,
msg + i + 10, eol - i - 10);
else if (!prefixcmp(msg + i, "encoding "))
- table[IENCODING].value = xstrndup(msg + i, eol - i);
+ table[IENCODING].value =
+ xstrndup(msg + i + 9, eol - i - 9);
i = eol;
}
if (msg[i])
const char *msg = commit->buffer;
int plain_non_ascii = 0;
char *reencoded;
- char *encoding;
+ const char *encoding;
if (fmt == CMIT_FMT_USERFORMAT)
return format_commit_message(commit, msg, buf, space);
return result;
}
-int in_merge_bases(struct commit *rev1, struct commit *rev2)
+int in_merge_bases(struct commit *commit, struct commit **reference, int num)
{
struct commit_list *bases, *b;
int ret = 0;
- bases = get_merge_bases(rev1, rev2, 1);
+ if (num == 1)
+ bases = get_merge_bases(commit, *reference, 1);
+ else
+ die("not yet");
for (b = bases; b; b = b->next) {
- if (!hashcmp(rev1->object.sha1, b->item->object.sha1)) {
+ if (!hashcmp(commit->object.sha1, b->item->object.sha1)) {
ret = 1;
break;
}