summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authornulltoken <emeric.fermas@gmail.com>2012-03-01 17:03:32 +0100
committernulltoken <emeric.fermas@gmail.com>2012-05-07 12:16:04 +0200
commit458b94503d023a07247153f44d34bcc65e6f8103 (patch)
tree02a14a37ebde58cdcf7164f0f362c705e510b201 /src
parent9b62e40ecdb92ab7493eac514e1399d791fa6f62 (diff)
downloadlibgit2-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.c14
-rw-r--r--src/message.c54
-rw-r--r--src/message.h14
-rw-r--r--src/tag.c15
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__ */
diff --git a/src/tag.c b/src/tag.c
index aa549fdd0..13481c2a6 100644
--- a/src/tag.c
+++ b/src/tag.c
@@ -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;
}