mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-29 22:25:04 +00:00
Merge pull request #3522 from pks-t/email-format-commit-message
diff: include commit message when formatting patch
This commit is contained in:
commit
6aa06b65cf
@ -127,6 +127,19 @@ GIT_EXTERN(const char *) git_commit_message_raw(const git_commit *commit);
|
|||||||
*/
|
*/
|
||||||
GIT_EXTERN(const char *) git_commit_summary(git_commit *commit);
|
GIT_EXTERN(const char *) git_commit_summary(git_commit *commit);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the long "body" of the git commit message.
|
||||||
|
*
|
||||||
|
* The returned message is the body of the commit, comprising
|
||||||
|
* everything but the first paragraph of the message. Leading and
|
||||||
|
* trailing whitespaces are trimmed.
|
||||||
|
*
|
||||||
|
* @param commit a previously loaded commit.
|
||||||
|
* @return the body of a commit or NULL when no the message only
|
||||||
|
* consists of a summary
|
||||||
|
*/
|
||||||
|
GIT_EXTERN(const char *) git_commit_body(git_commit *commit);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the commit time (i.e. committer time) of a commit.
|
* Get the commit time (i.e. committer time) of a commit.
|
||||||
*
|
*
|
||||||
|
@ -1286,12 +1286,15 @@ typedef struct {
|
|||||||
/** Summary of the change */
|
/** Summary of the change */
|
||||||
const char *summary;
|
const char *summary;
|
||||||
|
|
||||||
|
/** Commit message's body */
|
||||||
|
const char *body;
|
||||||
|
|
||||||
/** Author of the change */
|
/** Author of the change */
|
||||||
const git_signature *author;
|
const git_signature *author;
|
||||||
} git_diff_format_email_options;
|
} git_diff_format_email_options;
|
||||||
|
|
||||||
#define GIT_DIFF_FORMAT_EMAIL_OPTIONS_VERSION 1
|
#define GIT_DIFF_FORMAT_EMAIL_OPTIONS_VERSION 1
|
||||||
#define GIT_DIFF_FORMAT_EMAIL_OPTIONS_INIT {GIT_DIFF_FORMAT_EMAIL_OPTIONS_VERSION, 0, 1, 1, NULL, NULL, NULL}
|
#define GIT_DIFF_FORMAT_EMAIL_OPTIONS_INIT {GIT_DIFF_FORMAT_EMAIL_OPTIONS_VERSION, 0, 1, 1, NULL, NULL, NULL, NULL}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an e-mail ready patch from a diff.
|
* Create an e-mail ready patch from a diff.
|
||||||
|
28
src/commit.c
28
src/commit.c
@ -31,6 +31,7 @@ void git_commit__free(void *_commit)
|
|||||||
git__free(commit->raw_message);
|
git__free(commit->raw_message);
|
||||||
git__free(commit->message_encoding);
|
git__free(commit->message_encoding);
|
||||||
git__free(commit->summary);
|
git__free(commit->summary);
|
||||||
|
git__free(commit->body);
|
||||||
|
|
||||||
git__free(commit);
|
git__free(commit);
|
||||||
}
|
}
|
||||||
@ -472,6 +473,33 @@ const char *git_commit_summary(git_commit *commit)
|
|||||||
return commit->summary;
|
return commit->summary;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *git_commit_body(git_commit *commit)
|
||||||
|
{
|
||||||
|
const char *msg, *end;
|
||||||
|
|
||||||
|
assert(commit);
|
||||||
|
|
||||||
|
if (!commit->body) {
|
||||||
|
/* search for end of summary */
|
||||||
|
for (msg = git_commit_message(commit); *msg; ++msg)
|
||||||
|
if (msg[0] == '\n' && (!msg[1] || msg[1] == '\n'))
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* trim leading and trailing whitespace */
|
||||||
|
for (; *msg; ++msg)
|
||||||
|
if (!git__isspace(*msg))
|
||||||
|
break;
|
||||||
|
for (end = msg + strlen(msg) - 1; msg <= end; --end)
|
||||||
|
if (!git__isspace(*end))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (*msg)
|
||||||
|
commit->body = git__strndup(msg, end - msg + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return commit->body;
|
||||||
|
}
|
||||||
|
|
||||||
int git_commit_tree(git_tree **tree_out, const git_commit *commit)
|
int git_commit_tree(git_tree **tree_out, const git_commit *commit)
|
||||||
{
|
{
|
||||||
assert(commit);
|
assert(commit);
|
||||||
|
@ -28,6 +28,7 @@ struct git_commit {
|
|||||||
char *raw_header;
|
char *raw_header;
|
||||||
|
|
||||||
char *summary;
|
char *summary;
|
||||||
|
char *body;
|
||||||
};
|
};
|
||||||
|
|
||||||
void git_commit__free(void *commit);
|
void git_commit__free(void *commit);
|
||||||
|
11
src/diff.c
11
src/diff.c
@ -1659,6 +1659,7 @@ int git_diff_format_email__append_header_tobuf(
|
|||||||
const git_oid *id,
|
const git_oid *id,
|
||||||
const git_signature *author,
|
const git_signature *author,
|
||||||
const char *summary,
|
const char *summary,
|
||||||
|
const char *body,
|
||||||
size_t patch_no,
|
size_t patch_no,
|
||||||
size_t total_patches,
|
size_t total_patches,
|
||||||
bool exclude_patchno_marker)
|
bool exclude_patchno_marker)
|
||||||
@ -1698,6 +1699,13 @@ int git_diff_format_email__append_header_tobuf(
|
|||||||
|
|
||||||
error = git_buf_printf(out, "%s\n\n", summary);
|
error = git_buf_printf(out, "%s\n\n", summary);
|
||||||
|
|
||||||
|
if (body) {
|
||||||
|
git_buf_puts(out, body);
|
||||||
|
|
||||||
|
if (out->ptr[out->size - 1] != '\n')
|
||||||
|
git_buf_putc(out, '\n');
|
||||||
|
}
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1775,7 +1783,7 @@ int git_diff_format_email(
|
|||||||
|
|
||||||
error = git_diff_format_email__append_header_tobuf(out,
|
error = git_diff_format_email__append_header_tobuf(out,
|
||||||
opts->id, opts->author, summary == NULL ? opts->summary : summary,
|
opts->id, opts->author, summary == NULL ? opts->summary : summary,
|
||||||
opts->patch_no, opts->total_patches, ignore_marker);
|
opts->body, opts->patch_no, opts->total_patches, ignore_marker);
|
||||||
|
|
||||||
if (error < 0)
|
if (error < 0)
|
||||||
goto on_error;
|
goto on_error;
|
||||||
@ -1818,6 +1826,7 @@ int git_diff_commit_as_email(
|
|||||||
opts.total_patches = total_patches;
|
opts.total_patches = total_patches;
|
||||||
opts.id = git_commit_id(commit);
|
opts.id = git_commit_id(commit);
|
||||||
opts.summary = git_commit_summary(commit);
|
opts.summary = git_commit_summary(commit);
|
||||||
|
opts.body = git_commit_body(commit);
|
||||||
opts.author = git_commit_author(commit);
|
opts.author = git_commit_author(commit);
|
||||||
|
|
||||||
if ((error = git_diff__commit(&diff, repo, commit, diff_opts)) < 0)
|
if ((error = git_diff__commit(&diff, repo, commit, diff_opts)) < 0)
|
||||||
|
@ -63,6 +63,18 @@ void assert_commit_summary(const char *expected, const char *given)
|
|||||||
git_commit__free(dummy);
|
git_commit__free(dummy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void assert_commit_body(const char *expected, const char *given)
|
||||||
|
{
|
||||||
|
git_commit *dummy;
|
||||||
|
|
||||||
|
cl_assert(dummy = git__calloc(1, sizeof(struct git_commit)));
|
||||||
|
|
||||||
|
dummy->raw_message = git__strdup(given);
|
||||||
|
cl_assert_equal_s(expected, git_commit_body(dummy));
|
||||||
|
|
||||||
|
git_commit_free(dummy);
|
||||||
|
}
|
||||||
|
|
||||||
void test_commit_commit__summary(void)
|
void test_commit_commit__summary(void)
|
||||||
{
|
{
|
||||||
assert_commit_summary("One-liner with no trailing newline", "One-liner with no trailing newline");
|
assert_commit_summary("One-liner with no trailing newline", "One-liner with no trailing newline");
|
||||||
@ -80,8 +92,35 @@ void test_commit_commit__summary(void)
|
|||||||
assert_commit_summary(" Spaces after newlines are collapsed", "\n Spaces after newlines\n are\n collapsed\n "); /* newlines at the very beginning are ignored and not collapsed */
|
assert_commit_summary(" Spaces after newlines are collapsed", "\n Spaces after newlines\n are\n collapsed\n "); /* newlines at the very beginning are ignored and not collapsed */
|
||||||
assert_commit_summary(" Spaces before newlines are collapsed", " \nSpaces before newlines \nare \ncollapsed \n");
|
assert_commit_summary(" Spaces before newlines are collapsed", " \nSpaces before newlines \nare \ncollapsed \n");
|
||||||
assert_commit_summary(" Spaces around newlines are collapsed", " \n Spaces around newlines \n are \n collapsed \n ");
|
assert_commit_summary(" Spaces around newlines are collapsed", " \n Spaces around newlines \n are \n collapsed \n ");
|
||||||
|
assert_commit_summary(" Trailing newlines are" , " \n Trailing newlines \n are \n\n collapsed \n ");
|
||||||
|
assert_commit_summary(" Trailing spaces are stripped", " \n Trailing spaces \n are stripped \n\n \n \t ");
|
||||||
assert_commit_summary("", "");
|
assert_commit_summary("", "");
|
||||||
assert_commit_summary("", " ");
|
assert_commit_summary("", " ");
|
||||||
assert_commit_summary("", "\n");
|
assert_commit_summary("", "\n");
|
||||||
assert_commit_summary("", "\n \n");
|
assert_commit_summary("", "\n \n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_commit_commit__body(void)
|
||||||
|
{
|
||||||
|
assert_commit_body(NULL, "One-liner with no trailing newline");
|
||||||
|
assert_commit_body(NULL, "One-liner with trailing newline\n");
|
||||||
|
assert_commit_body(NULL, "\n\nTrimmed leading&trailing newlines\n\n");
|
||||||
|
assert_commit_body("(There are more!)", "\nFirst paragraph only\n\n(There are more!)");
|
||||||
|
assert_commit_body("(Yes, unwrapped!)", "\nFirst paragraph\nwith unwrapped\ntrailing\tlines\n\n(Yes, unwrapped!)");
|
||||||
|
assert_commit_body("are preserved", "\tLeading\n\ttabs\n\nare preserved"); /* tabs around newlines are collapsed down to a single space */
|
||||||
|
assert_commit_body("are preserved", " Leading\n Spaces\n\nare preserved"); /* spaces around newlines are collapsed down to a single space */
|
||||||
|
assert_commit_body(NULL, "Trailing tabs\tare removed\t\t");
|
||||||
|
assert_commit_body(NULL, "Trailing spaces are removed ");
|
||||||
|
assert_commit_body("are removed", "Trailing tabs\t\n\nare removed");
|
||||||
|
assert_commit_body("are removed", "Trailing spaces \n\nare removed");
|
||||||
|
assert_commit_body(NULL,"Newlines\nare\nreplaced by spaces\n");
|
||||||
|
assert_commit_body(NULL , "\n Spaces after newlines\n are\n collapsed\n "); /* newlines at the very beginning are ignored and not collapsed */
|
||||||
|
assert_commit_body(NULL , " \nSpaces before newlines \nare \ncollapsed \n");
|
||||||
|
assert_commit_body(NULL , " \n Spaces around newlines \n are \n collapsed \n ");
|
||||||
|
assert_commit_body("collapsed" , " \n Trailing newlines \n are \n\n collapsed \n ");
|
||||||
|
assert_commit_body(NULL, " \n Trailing spaces \n are stripped \n\n \n \t ");
|
||||||
|
assert_commit_body(NULL , "");
|
||||||
|
assert_commit_body(NULL , " ");
|
||||||
|
assert_commit_body(NULL , "\n");
|
||||||
|
assert_commit_body(NULL , "\n \n");
|
||||||
|
}
|
||||||
|
@ -97,6 +97,47 @@ void test_diff_format_email__simple(void)
|
|||||||
email, "9264b96c6d104d0e07ae33d3007b6a48246c6f92", &opts);
|
email, "9264b96c6d104d0e07ae33d3007b6a48246c6f92", &opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_diff_format_email__with_message(void)
|
||||||
|
{
|
||||||
|
git_diff_format_email_options opts = GIT_DIFF_FORMAT_EMAIL_OPTIONS_INIT;
|
||||||
|
const char *email = "From 627e7e12d87e07a83fad5b6bfa25e86ead4a5270 Mon Sep 17 00:00:00 2001\n" \
|
||||||
|
"From: Patrick Steinhardt <ps@pks.im>\n" \
|
||||||
|
"Date: Tue, 24 Nov 2015 13:34:39 +0100\n" \
|
||||||
|
"Subject: [PATCH] Modify content with message\n" \
|
||||||
|
"\n" \
|
||||||
|
"Modify content of file3.txt by appending a new line. Make this\n" \
|
||||||
|
"commit message somewhat longer to test behavior with newlines\n" \
|
||||||
|
"embedded in the message body.\n" \
|
||||||
|
"\n" \
|
||||||
|
"Also test if new paragraphs are included correctly.\n" \
|
||||||
|
"---\n" \
|
||||||
|
" file3.txt | 1 +\n" \
|
||||||
|
" 1 file changed, 1 insertion(+), 0 deletions(-)\n" \
|
||||||
|
"\n" \
|
||||||
|
"diff --git a/file3.txt b/file3.txt\n" \
|
||||||
|
"index 9a2d780..7309653 100644\n" \
|
||||||
|
"--- a/file3.txt\n" \
|
||||||
|
"+++ b/file3.txt\n" \
|
||||||
|
"@@ -3,3 +3,4 @@ file3!\n" \
|
||||||
|
" file3\n" \
|
||||||
|
" file3\n" \
|
||||||
|
" file3\n" \
|
||||||
|
"+file3\n" \
|
||||||
|
"--\n" \
|
||||||
|
"libgit2 0.23.0\n" \
|
||||||
|
"\n";
|
||||||
|
|
||||||
|
opts.body = "Modify content of file3.txt by appending a new line. Make this\n" \
|
||||||
|
"commit message somewhat longer to test behavior with newlines\n" \
|
||||||
|
"embedded in the message body.\n" \
|
||||||
|
"\n" \
|
||||||
|
"Also test if new paragraphs are included correctly.";
|
||||||
|
|
||||||
|
assert_email_match(
|
||||||
|
email, "627e7e12d87e07a83fad5b6bfa25e86ead4a5270", &opts);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void test_diff_format_email__multiple(void)
|
void test_diff_format_email__multiple(void)
|
||||||
{
|
{
|
||||||
git_oid oid;
|
git_oid oid;
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue
Block a user