From 05058d81676bf8ce5da4979402558b5a12e3754e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=2E=20David=20Ib=C3=A1=C3=B1ez?= <jdavid.ibp@gmail.com>
Date: Wed, 24 Aug 2011 08:52:41 +0200
Subject: [PATCH] Commit messages with non-ascii chars now work

And so do author & committers names
---
 pygit2.c            | 52 ++++++++++++++++++++++++++++++---------------
 test/test_commit.py |  6 +++---
 2 files changed, 38 insertions(+), 20 deletions(-)

diff --git a/pygit2.c b/pygit2.c
index bba2470..2b24ef8 100644
--- a/pygit2.c
+++ b/pygit2.c
@@ -566,23 +566,30 @@ Repository_walk(Repository *self, PyObject *args)
 }
 
 static PyObject *
-build_person(const git_signature *signature)
+build_person(const git_signature *signature, const char *encoding)
 {
-    return Py_BuildValue("(ssLi)", signature->name, signature->email,
+    PyObject *name;
+
+    name = PyUnicode_Decode(signature->name, strlen(signature->name),
+                            encoding, "strict");
+    return Py_BuildValue("(NsLi)", name, signature->email,
                          signature->when.time, signature->when.offset);
 }
 
 static int
 signature_converter(PyObject *value, git_signature **signature)
 {
+    PyObject *py_name;
     char *name, *email;
     long long time;
     int offset;
     int err;
 
-    if (!PyArg_ParseTuple(value, "ssLi", &name, &email, &time, &offset))
+    if (!PyArg_ParseTuple(value, "OsLi", &py_name, &email, &time, &offset))
         return 0;
 
+    name = py_str_to_c_str(py_name);
+
     err = git_signature_new(signature, name, email, time, offset);
     if (err < 0) {
         Error_set(err);
@@ -610,20 +617,22 @@ Repository_create_commit(Repository *self, PyObject *args)
     char *message, *update_ref;
     git_oid oid;
     git_tree *tree;
-    PyObject *py_parents, *py_parent;
+    PyObject *py_message, *py_parents, *py_parent;
     int parent_count;
     git_commit **parents;
     int err, i;
 
-    if (!PyArg_ParseTuple(args, "zO&O&sO&O!",
+    if (!PyArg_ParseTuple(args, "zO&O&OO&O!",
                           &update_ref,
                           signature_converter, &author,
                           signature_converter, &committer,
-                          &message,
+                          &py_message,
                           py_str_to_git_oid, &oid,
                           &PyList_Type, &py_parents))
         return NULL;
 
+    message = py_str_to_c_str(py_message);
+
     err = git_tree_lookup(&tree, self->repo, &oid);
     if (err < 0)
         return Error_set(err);
@@ -1062,14 +1071,13 @@ Commit_get_message_encoding(Commit *commit)
 static PyObject *
 Commit_get_message(Commit *commit)
 {
-    const char *encoding;
-    const char *message;
-    int len;
+    const char *message, *encoding;
 
-    encoding = git_commit_message_encoding(commit->commit);
     message = git_commit_message(commit->commit);
-    len = strlen(message);
-    return PyUnicode_Decode(message, (Py_ssize_t)len, encoding, "strict");
+    encoding = git_commit_message_encoding(commit->commit);
+    if (encoding == NULL)
+        encoding = "utf-8";
+    return PyUnicode_Decode(message, strlen(message), encoding, "strict");
 }
 
 static PyObject *
@@ -1087,17 +1095,27 @@ Commit_get_commit_time_offset(Commit *commit)
 static PyObject *
 Commit_get_committer(Commit *commit)
 {
-    const git_signature *signature = git_commit_committer(commit->commit);
+    const git_signature *signature;
+    const char *encoding;
 
-    return build_person(signature);
+    signature = git_commit_committer(commit->commit);
+    encoding = git_commit_message_encoding(commit->commit);
+    if (encoding == NULL)
+        encoding = "utf-8";
+    return build_person(signature, encoding);
 }
 
 static PyObject *
 Commit_get_author(Commit *commit)
 {
-    const git_signature *signature = git_commit_author(commit->commit);
+    const git_signature *signature;
+    const char *encoding;
 
-    return build_person(signature);
+    signature = git_commit_author(commit->commit);
+    encoding = git_commit_message_encoding(commit->commit);
+    if (encoding == NULL)
+        encoding = "utf-8";
+    return build_person(signature, encoding);
 }
 
 static PyObject *
@@ -1613,7 +1631,7 @@ Tag_get_tagger(Tag *tag)
     const git_signature *signature = git_tag_tagger(tag->tag);
     if (!signature)
         Py_RETURN_NONE;
-    return build_person(signature);
+    return build_person(signature, "utf-8");
 }
 
 static PyObject *
diff --git a/test/test_commit.py b/test/test_commit.py
index 7fd2989..6520ec1 100644
--- a/test/test_commit.py
+++ b/test/test_commit.py
@@ -67,9 +67,9 @@ class CommitTest(utils.BareRepoTestCase):
 
     def test_new_commit(self):
         repo = self.repo
-        message = 'New commit.\n\nMessage.\n'
+        message = 'New commit.\n\nMessage with non-ascii chars: ééé.\n'
         committer = ('John Doe', 'jdoe@example.com', 12346, 0)
-        author = ('Jane Doe', 'jdoe2@example.com', 12345, 0)
+        author = ('J. David Ibáñez', 'jdavid@example.com', 12345, 0)
         tree = '967fce8df97cc71722d3c2a5930ef3e6f1d27b12'
 
         parents = [COMMIT_SHA]
@@ -78,7 +78,7 @@ class CommitTest(utils.BareRepoTestCase):
         commit = repo[sha]
 
         self.assertEqual(GIT_OBJ_COMMIT, commit.type)
-        self.assertEqual('30bb126a4959290987fc07ea49f92be276dce9d6',
+        self.assertEqual('98286caaab3f1fde5bf52c8369b2b0423bad743b',
                          commit.sha)
         self.assertEqual(None, commit.message_encoding)
         self.assertEqual(message, commit.message)