mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-29 08:11:58 +00:00
commit: Add support for Encoding header
This commit is contained in:
parent
b2e60e4eb5
commit
5ae2f0c013
@ -97,12 +97,16 @@ GIT_INLINE(void) git_commit_close(git_commit *commit)
|
|||||||
GIT_EXTERN(const git_oid *) git_commit_id(git_commit *commit);
|
GIT_EXTERN(const git_oid *) git_commit_id(git_commit *commit);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the short (one line) message of a commit.
|
* Get the encoding for the message of a commit,
|
||||||
|
* as a string representing a standard encoding name.
|
||||||
|
*
|
||||||
|
* The encoding may be NULL if the `encoding` header
|
||||||
|
* in the commit is missing; in that case UTF-8 is assumed.
|
||||||
*
|
*
|
||||||
* @param commit a previously loaded commit.
|
* @param commit a previously loaded commit.
|
||||||
* @return the short message of a commit
|
* @return NULL, or the encoding
|
||||||
*/
|
*/
|
||||||
GIT_EXTERN(const char *) git_commit_message_short(git_commit *commit);
|
GIT_EXTERN(const char *) git_commit_message_encoding(git_commit *commit);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the full message of a commit.
|
* Get the full message of a commit.
|
||||||
@ -213,6 +217,11 @@ GIT_EXTERN(const git_oid *) git_commit_parent_oid(git_commit *commit, unsigned i
|
|||||||
* @param committer Signature representing the committer and the
|
* @param committer Signature representing the committer and the
|
||||||
* commit time of this commit
|
* commit time of this commit
|
||||||
*
|
*
|
||||||
|
* @param message_encoding The encoding for the message in the
|
||||||
|
* commit, represented with a standard encoding name.
|
||||||
|
* E.g. "UTF-8". If NULL, no encoding header is written and
|
||||||
|
* UTF-8 is assumed.
|
||||||
|
*
|
||||||
* @param message Full message for this commit
|
* @param message Full message for this commit
|
||||||
*
|
*
|
||||||
* @param tree An instance of a `git_tree` object that will
|
* @param tree An instance of a `git_tree` object that will
|
||||||
@ -236,6 +245,7 @@ GIT_EXTERN(int) git_commit_create(
|
|||||||
const char *update_ref,
|
const char *update_ref,
|
||||||
const git_signature *author,
|
const git_signature *author,
|
||||||
const git_signature *committer,
|
const git_signature *committer,
|
||||||
|
const char *message_encoding,
|
||||||
const char *message,
|
const char *message,
|
||||||
const git_tree *tree,
|
const git_tree *tree,
|
||||||
int parent_count,
|
int parent_count,
|
||||||
@ -260,6 +270,7 @@ GIT_EXTERN(int) git_commit_create_v(
|
|||||||
const char *update_ref,
|
const char *update_ref,
|
||||||
const git_signature *author,
|
const git_signature *author,
|
||||||
const git_signature *committer,
|
const git_signature *committer,
|
||||||
|
const char *message_encoding,
|
||||||
const char *message,
|
const char *message,
|
||||||
const git_tree *tree,
|
const git_tree *tree,
|
||||||
int parent_count,
|
int parent_count,
|
||||||
|
60
src/commit.c
60
src/commit.c
@ -65,7 +65,7 @@ void git_commit__free(git_commit *commit)
|
|||||||
git_signature_free(commit->committer);
|
git_signature_free(commit->committer);
|
||||||
|
|
||||||
free(commit->message);
|
free(commit->message);
|
||||||
free(commit->message_short);
|
free(commit->message_encoding);
|
||||||
free(commit);
|
free(commit);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,6 +80,7 @@ int git_commit_create_v(
|
|||||||
const char *update_ref,
|
const char *update_ref,
|
||||||
const git_signature *author,
|
const git_signature *author,
|
||||||
const git_signature *committer,
|
const git_signature *committer,
|
||||||
|
const char *message_encoding,
|
||||||
const char *message,
|
const char *message,
|
||||||
const git_tree *tree,
|
const git_tree *tree,
|
||||||
int parent_count,
|
int parent_count,
|
||||||
@ -97,7 +98,8 @@ int git_commit_create_v(
|
|||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
error = git_commit_create(
|
error = git_commit_create(
|
||||||
oid, repo, update_ref, author, committer, message,
|
oid, repo, update_ref, author, committer,
|
||||||
|
message_encoding, message,
|
||||||
tree, parent_count, parents);
|
tree, parent_count, parents);
|
||||||
|
|
||||||
free((void *)parents);
|
free((void *)parents);
|
||||||
@ -111,6 +113,7 @@ int git_commit_create(
|
|||||||
const char *update_ref,
|
const char *update_ref,
|
||||||
const git_signature *author,
|
const git_signature *author,
|
||||||
const git_signature *committer,
|
const git_signature *committer,
|
||||||
|
const char *message_encoding,
|
||||||
const char *message,
|
const char *message,
|
||||||
const git_tree *tree,
|
const git_tree *tree,
|
||||||
int parent_count,
|
int parent_count,
|
||||||
@ -136,6 +139,9 @@ int git_commit_create(
|
|||||||
git_signature__writebuf(&commit, "author ", author);
|
git_signature__writebuf(&commit, "author ", author);
|
||||||
git_signature__writebuf(&commit, "committer ", committer);
|
git_signature__writebuf(&commit, "committer ", committer);
|
||||||
|
|
||||||
|
if (message_encoding != NULL)
|
||||||
|
git_buf_printf(&commit, "encoding %s\n", message_encoding);
|
||||||
|
|
||||||
git_buf_putc(&commit, '\n');
|
git_buf_putc(&commit, '\n');
|
||||||
git_buf_puts(&commit, message);
|
git_buf_puts(&commit, message);
|
||||||
|
|
||||||
@ -210,42 +216,36 @@ int commit_parse_buffer(git_commit *commit, const void *data, size_t len)
|
|||||||
|
|
||||||
commit->author = git__malloc(sizeof(git_signature));
|
commit->author = git__malloc(sizeof(git_signature));
|
||||||
if ((error = git_signature__parse(commit->author, &buffer, buffer_end, "author ", '\n')) < GIT_SUCCESS)
|
if ((error = git_signature__parse(commit->author, &buffer, buffer_end, "author ", '\n')) < GIT_SUCCESS)
|
||||||
return git__rethrow(error, "Failed to parse buffer");
|
return git__rethrow(error, "Failed to parse commit");
|
||||||
|
|
||||||
/* Always parse the committer; we need the commit time */
|
/* Always parse the committer; we need the commit time */
|
||||||
commit->committer = git__malloc(sizeof(git_signature));
|
commit->committer = git__malloc(sizeof(git_signature));
|
||||||
if ((error = git_signature__parse(commit->committer, &buffer, buffer_end, "committer ", '\n')) < GIT_SUCCESS)
|
if ((error = git_signature__parse(commit->committer, &buffer, buffer_end, "committer ", '\n')) < GIT_SUCCESS)
|
||||||
return git__rethrow(error, "Failed to parse buffer");
|
return git__rethrow(error, "Failed to parse commit");
|
||||||
|
|
||||||
|
if (git__prefixcmp(buffer, "encoding ") == 0) {
|
||||||
|
const char *encoding_end;
|
||||||
|
buffer += STRLEN("encoding ");
|
||||||
|
|
||||||
|
encoding_end = buffer;
|
||||||
|
while (encoding_end < buffer_end && *encoding_end != '\n')
|
||||||
|
encoding_end++;
|
||||||
|
|
||||||
|
commit->message_encoding = git__strndup(buffer, encoding_end - buffer);
|
||||||
|
if (!commit->message_encoding)
|
||||||
|
return GIT_ENOMEM;
|
||||||
|
|
||||||
|
buffer = encoding_end;
|
||||||
|
}
|
||||||
|
|
||||||
/* parse commit message */
|
/* parse commit message */
|
||||||
while (buffer <= buffer_end && *buffer == '\n')
|
while (buffer < buffer_end && *buffer == '\n')
|
||||||
buffer++;
|
buffer++;
|
||||||
|
|
||||||
if (buffer < buffer_end) {
|
if (buffer < buffer_end) {
|
||||||
const char *line_end;
|
commit->message = git__strndup(buffer, buffer_end - buffer);
|
||||||
unsigned int i;
|
if (!commit->message)
|
||||||
size_t message_len;
|
return GIT_ENOMEM;
|
||||||
|
|
||||||
/* Long message */
|
|
||||||
message_len = buffer_end - buffer;
|
|
||||||
commit->message = git__malloc(message_len + 1);
|
|
||||||
memcpy(commit->message, buffer, message_len);
|
|
||||||
commit->message[message_len] = 0;
|
|
||||||
|
|
||||||
/* Short message */
|
|
||||||
if((line_end = strstr(buffer, "\n\n")) == NULL) {
|
|
||||||
/* Cut the last '\n' if there is one */
|
|
||||||
if (message_len && buffer[message_len - 1] == '\n')
|
|
||||||
line_end = buffer_end - 1;
|
|
||||||
else
|
|
||||||
line_end = buffer_end;
|
|
||||||
}
|
|
||||||
message_len = line_end - buffer;
|
|
||||||
commit->message_short = git__malloc(message_len + 1);
|
|
||||||
for (i = 0; i < message_len; ++i) {
|
|
||||||
commit->message_short[i] = (buffer[i] == '\n') ? ' ' : buffer[i];
|
|
||||||
}
|
|
||||||
commit->message_short[message_len] = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return GIT_SUCCESS;
|
return GIT_SUCCESS;
|
||||||
@ -267,7 +267,7 @@ int git_commit__parse(git_commit *commit, git_odb_object *obj)
|
|||||||
GIT_COMMIT_GETTER(const git_signature *, author, commit->author)
|
GIT_COMMIT_GETTER(const git_signature *, author, commit->author)
|
||||||
GIT_COMMIT_GETTER(const git_signature *, committer, commit->committer)
|
GIT_COMMIT_GETTER(const git_signature *, committer, commit->committer)
|
||||||
GIT_COMMIT_GETTER(const char *, message, commit->message)
|
GIT_COMMIT_GETTER(const char *, message, commit->message)
|
||||||
GIT_COMMIT_GETTER(const char *, message_short, commit->message_short)
|
GIT_COMMIT_GETTER(const char *, message_encoding, commit->message_encoding)
|
||||||
GIT_COMMIT_GETTER(git_time_t, time, commit->committer->when.time)
|
GIT_COMMIT_GETTER(git_time_t, time, commit->committer->when.time)
|
||||||
GIT_COMMIT_GETTER(int, time_offset, commit->committer->when.offset)
|
GIT_COMMIT_GETTER(int, time_offset, commit->committer->when.offset)
|
||||||
GIT_COMMIT_GETTER(unsigned int, parentcount, commit->parent_oids.length)
|
GIT_COMMIT_GETTER(unsigned int, parentcount, commit->parent_oids.length)
|
||||||
|
@ -17,8 +17,8 @@ struct git_commit {
|
|||||||
git_signature *author;
|
git_signature *author;
|
||||||
git_signature *committer;
|
git_signature *committer;
|
||||||
|
|
||||||
|
char *message_encoding;
|
||||||
char *message;
|
char *message;
|
||||||
char *message_short;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void git_commit__free(git_commit *c);
|
void git_commit__free(git_commit *c);
|
||||||
|
@ -578,7 +578,7 @@ BEGIN_TEST(details0, "query the details on a parsed commit")
|
|||||||
git_commit *commit;
|
git_commit *commit;
|
||||||
|
|
||||||
const git_signature *author, *committer;
|
const git_signature *author, *committer;
|
||||||
const char *message, *message_short;
|
const char *message;
|
||||||
git_time_t commit_time;
|
git_time_t commit_time;
|
||||||
unsigned int parents, p;
|
unsigned int parents, p;
|
||||||
git_commit *parent = NULL, *old_parent = NULL;
|
git_commit *parent = NULL, *old_parent = NULL;
|
||||||
@ -588,7 +588,6 @@ BEGIN_TEST(details0, "query the details on a parsed commit")
|
|||||||
must_pass(git_commit_lookup(&commit, repo, &id));
|
must_pass(git_commit_lookup(&commit, repo, &id));
|
||||||
|
|
||||||
message = git_commit_message(commit);
|
message = git_commit_message(commit);
|
||||||
message_short = git_commit_message_short(commit);
|
|
||||||
author = git_commit_author(commit);
|
author = git_commit_author(commit);
|
||||||
committer = git_commit_committer(commit);
|
committer = git_commit_committer(commit);
|
||||||
commit_time = git_commit_time(commit);
|
commit_time = git_commit_time(commit);
|
||||||
@ -599,7 +598,6 @@ BEGIN_TEST(details0, "query the details on a parsed commit")
|
|||||||
must_be_true(strcmp(committer->name, "Scott Chacon") == 0);
|
must_be_true(strcmp(committer->name, "Scott Chacon") == 0);
|
||||||
must_be_true(strcmp(committer->email, "schacon@gmail.com") == 0);
|
must_be_true(strcmp(committer->email, "schacon@gmail.com") == 0);
|
||||||
must_be_true(strchr(message, '\n') != NULL);
|
must_be_true(strchr(message, '\n') != NULL);
|
||||||
must_be_true(strchr(message_short, '\n') == NULL);
|
|
||||||
must_be_true(commit_time > 0);
|
must_be_true(commit_time > 0);
|
||||||
must_be_true(parents <= 2);
|
must_be_true(parents <= 2);
|
||||||
for (p = 0;p < parents;p++) {
|
for (p = 0;p < parents;p++) {
|
||||||
@ -655,6 +653,7 @@ BEGIN_TEST(write0, "write a new commit object from memory to disk")
|
|||||||
NULL, /* do not update the HEAD */
|
NULL, /* do not update the HEAD */
|
||||||
author,
|
author,
|
||||||
committer,
|
committer,
|
||||||
|
NULL,
|
||||||
COMMIT_MESSAGE,
|
COMMIT_MESSAGE,
|
||||||
tree,
|
tree,
|
||||||
1, parent));
|
1, parent));
|
||||||
@ -727,6 +726,7 @@ BEGIN_TEST(root0, "create a root commit")
|
|||||||
"HEAD",
|
"HEAD",
|
||||||
author,
|
author,
|
||||||
committer,
|
committer,
|
||||||
|
NULL,
|
||||||
ROOT_COMMIT_MESSAGE,
|
ROOT_COMMIT_MESSAGE,
|
||||||
tree,
|
tree,
|
||||||
0));
|
0));
|
||||||
|
Loading…
Reference in New Issue
Block a user