diff options
| author | nulltoken <emeric.fermas@gmail.com> | 2012-03-01 17:03:32 +0100 | 
|---|---|---|
| committer | nulltoken <emeric.fermas@gmail.com> | 2012-05-07 12:16:04 +0200 | 
| commit | 458b94503d023a07247153f44d34bcc65e6f8103 (patch) | |
| tree | 02a14a37ebde58cdcf7164f0f362c705e510b201 /src | |
| parent | 9b62e40ecdb92ab7493eac514e1399d791fa6f62 (diff) | |
| download | libgit2-458b94503d023a07247153f44d34bcc65e6f8103.tar.gz | |
commit/tag: ensure the message is cleaned up
'git commit' and 'git tag -a' enforce some conventions, like cleaning up excess whitespace and making sure that the last line ends with a '\n'. This fix replicates this behavior.
Fix libgit2/libgit2sharp#117
Diffstat (limited to 'src')
| -rw-r--r-- | src/commit.c | 14 | ||||
| -rw-r--r-- | src/message.c | 54 | ||||
| -rw-r--r-- | src/message.h | 14 | ||||
| -rw-r--r-- | src/tag.c | 15 | 
4 files changed, 91 insertions, 6 deletions
diff --git a/src/commit.c b/src/commit.c index 04f37fe16..2bf12f3a5 100644 --- a/src/commit.c +++ b/src/commit.c @@ -14,6 +14,7 @@  #include "odb.h"  #include "commit.h"  #include "signature.h" +#include "message.h"  #include <stdarg.h> @@ -161,7 +162,7 @@ int git_commit_create(  		int parent_count,  		const git_commit *parents[])  { -	git_buf commit = GIT_BUF_INIT; +	git_buf commit = GIT_BUF_INIT, cleaned_message = GIT_BUF_INIT;  	int i;  	git_odb *odb; @@ -181,11 +182,16 @@ int git_commit_create(  		git_buf_printf(&commit, "encoding %s\n", message_encoding);  	git_buf_putc(&commit, '\n'); -	git_buf_puts(&commit, message); -	if (git_buf_oom(&commit)) +	/* Remove comments by default */ +	if (git_message_prettify(&cleaned_message, message, 1) < 0)  		goto on_error; +	if (git_buf_puts(&commit, git_buf_cstr(&cleaned_message)) < 0) +		goto on_error; + +	git_buf_free(&cleaned_message); +  	if (git_repository_odb__weakptr(&odb, repo) < 0)  		goto on_error; @@ -201,6 +207,8 @@ int git_commit_create(  on_error:  	git_buf_free(&commit); +	git_buf_free(&cleaned_message); +	giterr_set(GITERR_OBJECT, "Failed to create commit.");  	return -1;  } diff --git a/src/message.c b/src/message.c new file mode 100644 index 000000000..94745ea81 --- /dev/null +++ b/src/message.c @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2009-2012 the libgit2 contributors + * + * This file is part of libgit2, distributed under the GNU GPL v2 with + * a Linking Exception. For full terms see the included COPYING file. + */ + +#include "message.h" + +static size_t line_length_without_trailing_spaces(const char *line, size_t len) +{ +	while (len) { +		unsigned char c = line[len - 1]; +		if (!isspace(c)) +			break; +		len--; +	} + +	return len; +} + +/* Greatly inspired from git.git "stripspace" */ +/* see https://github.com/git/git/blob/497215d8811ac7b8955693ceaad0899ecd894ed2/builtin/stripspace.c#L4-67 */ +int git_message_prettify(git_buf *message_out, const char *message, int strip_comments) +{ +	int consecutive_empty_lines = 0; +	size_t i, line_length, rtrimmed_line_length; +	char *next_newline; + +	for (i = 0; i < strlen(message); i += line_length) { +		next_newline = memchr(message + i, '\n', strlen(message) - i); +		line_length = next_newline ? next_newline - (message + i) + 1 : strlen(message) - i; + +		if (strip_comments && line_length && message[i] == '#') +			continue; + +		rtrimmed_line_length = line_length_without_trailing_spaces(message + i, line_length); + +		if (!rtrimmed_line_length) { +			consecutive_empty_lines++; +			continue; +		} + +		if (consecutive_empty_lines > 0 && message_out->size > 0) +			if (git_buf_putc(message_out, '\n') < 0) +				return -1; + +		consecutive_empty_lines = 0; +		git_buf_put(message_out, message + i, rtrimmed_line_length); +		git_buf_putc(message_out, '\n'); +	} + +	return 0; +} diff --git a/src/message.h b/src/message.h new file mode 100644 index 000000000..ddfa13e18 --- /dev/null +++ b/src/message.h @@ -0,0 +1,14 @@ +/* + * Copyright (C) 2009-2012 the libgit2 contributors + * + * This file is part of libgit2, distributed under the GNU GPL v2 with + * a Linking Exception. For full terms see the included COPYING file. + */ +#ifndef INCLUDE_message_h__ +#define INCLUDE_message_h__ + +#include "buffer.h" + +int git_message_prettify(git_buf *message_out, const char *message, int strip_comments); + +#endif /* INCLUDE_message_h__ */ @@ -9,6 +9,7 @@  #include "commit.h"  #include "tag.h"  #include "signature.h" +#include "message.h"  #include "git2/object.h"  #include "git2/repository.h"  #include "git2/signature.h" @@ -195,7 +196,7 @@ static int write_tag_annotation(  		const git_signature *tagger,  		const char *message)  { -	git_buf tag = GIT_BUF_INIT; +	git_buf tag = GIT_BUF_INIT, cleaned_message = GIT_BUF_INIT;  	git_odb *odb;  	git_oid__writebuf(&tag, "object ", git_object_id(target)); @@ -203,11 +204,16 @@ static int write_tag_annotation(  	git_buf_printf(&tag, "tag %s\n", tag_name);  	git_signature__writebuf(&tag, "tagger ", tagger);  	git_buf_putc(&tag, '\n'); -	git_buf_puts(&tag, message); -	if (git_buf_oom(&tag)) +	/* Remove comments by default */ +	if (git_message_prettify(&cleaned_message, message, 1) < 0)  		goto on_error; +	if (git_buf_puts(&tag, git_buf_cstr(&cleaned_message)) < 0) +		goto on_error; + +	git_buf_free(&cleaned_message); +  	if (git_repository_odb__weakptr(&odb, repo) < 0)  		goto on_error; @@ -216,8 +222,11 @@ static int write_tag_annotation(  	git_buf_free(&tag);  	return 0; +  on_error:  	git_buf_free(&tag); +	git_buf_free(&cleaned_message); +	giterr_set(GITERR_OBJECT, "Failed to create tag annotation.");  	return -1;  }  | 
