summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNika Layzell <nika@thelayzells.com>2018-03-17 18:14:31 -0400
committerNika Layzell <nika@thelayzells.com>2018-06-14 22:43:27 -0700
commitb05fbba394b9f2befea8b50817fd64209538e384 (patch)
tree537073c28c4e7424b91c743e412cadda432f21d4
parent939d8d579dcf722ca56578203df7c3134ba23ac1 (diff)
downloadlibgit2-b05fbba394b9f2befea8b50817fd64209538e384.tar.gz
mailmap: Make everything a bit more style conforming
-rw-r--r--include/git2/mailmap.h61
-rw-r--r--src/mailmap.c107
2 files changed, 113 insertions, 55 deletions
diff --git a/include/git2/mailmap.h b/include/git2/mailmap.h
index 0f582c2a3..a80ecb970 100644
--- a/include/git2/mailmap.h
+++ b/include/git2/mailmap.h
@@ -8,7 +8,7 @@
#define INCLUDE_git_mailmap_h__
#include "common.h"
-#include "tree.h"
+#include "types.h"
/**
* @file git2/mailmap.h
@@ -19,24 +19,27 @@
*/
GIT_BEGIN_DECL
-typedef struct git_mailmap git_mailmap;
-
/**
* A single entry parsed from a mailmap.
*/
-typedef struct git_mailmap_entry {
+struct git_mailmap_entry {
+ unsigned int version;
+
const char *real_name; /**< the real name (may be NULL) */
const char *real_email; /**< the real email (may be NULL) */
const char *replace_name; /**< the name to replace (may be NULL) */
const char *replace_email; /**< the email to replace */
-} git_mailmap_entry;
+};
+
+#define GIT_MAILMAP_ENTRY_VERSION 1
+#define GIT_MAILMAP_ENTRY_INIT {GIT_MAILMAP_ENTRY_VERSION}
/**
* Create a mailmap object by parsing a mailmap file.
*
* The mailmap must be freed with 'git_mailmap_free'.
*
- * @param out Pointer to store the mailmap
+ * @param out pointer to store the mailmap
* @param data raw data buffer to parse
* @param size size of the raw data buffer
* @return 0 on success
@@ -47,35 +50,26 @@ GIT_EXTERN(int) git_mailmap_parse(
size_t size);
/**
- * Create a mailmap object by parsing the ".mailmap" file in the tree root.
+ * Create a mailmap object from the given repository.
*
- * The mailmap must be freed with 'git_mailmap_free'.
+ * If the repository is not bare, the repository's working directory root will
+ * be checked for the '.mailmap' file to be parsed.
*
- * @param out pointer to store the mailmap
- * @param treeish root object that can be peeled to a tree
- * @return 0 on success; GIT_ENOTFOUND if .mailmap does not exist.
- */
-GIT_EXTERN(int) git_mailmap_from_tree(
- git_mailmap **out,
- const git_object *treeish);
-
-/**
- * Create a mailmap object by parsing the ".mailmap" file in the repository's
- * HEAD's tree root.
+ * If the repository is bare, the repository's HEAD commit's tree root will be
+ * searched for the '.mailmap' file to be parsed.
*
* The mailmap must be freed with 'git_mailmap_free'.
*
* @param out pointer to store the mailmap
* @param repo repository to find the .mailmap in
- * @return 0 on success; GIT_ENOTFOUND if .mailmap does not exist.
+ * @return 0 on success; GIT_ENOTFOUND if .mailmap could not be found.
*/
GIT_EXTERN(int) git_mailmap_from_repo(
git_mailmap **out,
git_repository *repo);
/**
- * Free a mailmap created by 'git_mailmap_parse', 'git_mailmap_from_tree' or
- * 'git_mailmap_from_repo'.
+ * Free a mailmap created by 'git_mailmap_parse' or 'git_mailmap_from_repo'.
*/
GIT_EXTERN(void) git_mailmap_free(git_mailmap *mailmap);
@@ -86,38 +80,45 @@ GIT_EXTERN(void) git_mailmap_free(git_mailmap *mailmap);
* You should NOT free this value.
* @param email_out either 'email' or the real email to use,
* You should NOT free this value.
- * @param mailmap the mailmap to perform the lookup in.
+ * @param mailmap the mailmap to perform the lookup in. (may be NULL)
* @param name the name to resolve.
* @param email the email to resolve.
*/
GIT_EXTERN(void) git_mailmap_resolve(
const char **name_out,
const char **email_out,
- git_mailmap *mailmap,
+ const git_mailmap *mailmap,
const char *name,
const char *email);
/**
- * Get the number of mailmap entries.
+ * Get the number of mailmap entries in this mailmap.
*/
-GIT_EXTERN(size_t) git_mailmap_entry_count(git_mailmap *mailmap);
+GIT_EXTERN(size_t) git_mailmap_entry_count(const git_mailmap *mailmap);
/**
* Lookup a mailmap entry by index.
*
* Do not free the mailmap entry, it is owned by the mailmap.
+ *
+ * @return the mailmap entry at index, or NULL if it cannot be found.
*/
-GIT_EXTERN(git_mailmap_entry *) git_mailmap_entry_byindex(
- git_mailmap *mailmap,
+GIT_EXTERN(const git_mailmap_entry *) git_mailmap_entry_byindex(
+ const git_mailmap *mailmap,
size_t idx);
/**
* Lookup a mailmap entry by name/email pair.
*
* Do not free the mailmap entry, it is owned by the mailmap.
+ *
+ * @param mailmap the mailmap to perform the lookup in. (may be NULL)
+ * @param name the name to perform the lookup with.
+ * @param email the email to perform the lookup with.
+ * @return the corresponding mailmap entry, or NULL if it cannot be found.
*/
-GIT_EXTERN(git_mailmap_entry *) git_mailmap_entry_lookup(
- git_mailmap *mailmap,
+GIT_EXTERN(const git_mailmap_entry *) git_mailmap_entry_lookup(
+ const git_mailmap *mailmap,
const char *name,
const char *email);
diff --git a/src/mailmap.c b/src/mailmap.c
index dfff47d3a..aaf5446f2 100644
--- a/src/mailmap.c
+++ b/src/mailmap.c
@@ -135,7 +135,8 @@ static int git_mailmap_parse_single(
*real_name = name_a;
if (two_emails) {
- *real_email = email_a;
+ if (email_a.len > 0)
+ *real_email = email_a;
*replace_email = email_b;
if (name_b.len > 0)
@@ -158,6 +159,9 @@ int git_mailmap_parse(
git_mailmap_entry* entry = NULL;
int error = 0;
+ if (memchr(data, '\0', size) != NULL)
+ return -1; /* data may not contain '\0's */
+
*mailmap = git__calloc(1, sizeof(git_mailmap));
if (!*mailmap)
return -1;
@@ -194,6 +198,7 @@ int git_mailmap_parse(
error = -1;
goto cleanup;
}
+ entry->version = GIT_MAILMAP_ENTRY_VERSION;
buf = (char*)(entry + 1);
entry->real_name = range_copyz(&buf, NULL, real_name);
@@ -209,9 +214,8 @@ int git_mailmap_parse(
}
cleanup:
- if (entry)
- git__free(entry);
- if (error < 0 && *mailmap) {
+ git__free(entry);
+ if (error < 0)
git_mailmap_free(*mailmap);
*mailmap = NULL;
}
@@ -220,6 +224,9 @@ cleanup:
void git_mailmap_free(git_mailmap *mailmap)
{
+ if (!mailmap)
+ return;
+
git_vector_free_deep(&mailmap->entries);
git__free(mailmap);
}
@@ -227,15 +234,19 @@ void git_mailmap_free(git_mailmap *mailmap)
void git_mailmap_resolve(
const char **name_out,
const char **email_out,
- git_mailmap *mailmap,
+ const git_mailmap *mailmap,
const char *name,
const char *email)
{
- git_mailmap_entry *entry = NULL;
+ const git_mailmap_entry *entry = NULL;
+ assert(name && email);
*name_out = name;
*email_out = email;
+ if (!mailmap)
+ return;
+
entry = git_mailmap_entry_lookup(mailmap, name, email);
if (entry) {
if (entry->real_name)
@@ -245,14 +256,17 @@ void git_mailmap_resolve(
}
}
-git_mailmap_entry *git_mailmap_entry_lookup(
- git_mailmap *mailmap,
+const git_mailmap_entry *git_mailmap_entry_lookup(
+ const git_mailmap *mailmap,
const char *name,
const char *email)
{
size_t i;
git_mailmap_entry *entry;
- assert(mailmap && name && email);
+ assert(name && email);
+
+ if (!mailmap)
+ return NULL;
git_vector_foreach(&mailmap->entries, i, entry) {
if (!git__strcmp(email, entry->replace_email) &&
@@ -264,26 +278,42 @@ git_mailmap_entry *git_mailmap_entry_lookup(
return NULL;
}
-git_mailmap_entry *git_mailmap_entry_byindex(git_mailmap *mailmap, size_t idx)
+const git_mailmap_entry *git_mailmap_entry_byindex(
+ const git_mailmap *mailmap, size_t idx)
{
- return git_vector_get(&mailmap->entries, idx);
+ if (mailmap)
+ return git_vector_get(&mailmap->entries, idx);
+ return NULL;
}
-size_t git_mailmap_entry_count(git_mailmap *mailmap)
+size_t git_mailmap_entry_count(const git_mailmap *mailmap)
{
- return git_vector_length(&mailmap->entries);
+ if (mailmap)
+ return git_vector_length(&mailmap->entries);
+ return 0;
}
-int git_mailmap_from_tree(
+static int git_mailmap_from_bare_repo(
git_mailmap **mailmap,
- const git_object *treeish)
+ git_repository *repo)
{
+ git_reference *head = NULL;
+ git_object *tree = NULL;
git_blob *blob = NULL;
const char *content = NULL;
git_off_t size = 0;
int error;
- *mailmap = NULL;
+ assert(git_repository_is_bare(repo));
+
+ /* In bare repositories, fall back to reading from HEAD's tree */
+ error = git_repository_head(&head, repo);
+ if (error < 0)
+ goto cleanup;
+
+ error = git_reference_peel(&tree, head, GIT_OBJ_TREE);
+ if (error < 0)
+ goto cleanup;
error = git_object_lookup_bypath(
(git_object **) &blob,
@@ -297,28 +327,55 @@ int git_mailmap_from_tree(
size = git_blob_rawsize(blob);
error = git_mailmap_parse(mailmap, content, size);
+ if (error < 0)
+ goto cleanup;
cleanup:
- if (blob != NULL)
- git_blob_free(blob);
+ git_reference_free(head);
+ git_object_free(tree);
+ git_blob_free(blob);
+
return error;
}
-int git_mailmap_from_repo(git_mailmap **mailmap, git_repository *repo)
+static int git_mailmap_from_workdir_repo(
+ git_mailmap **mailmap,
+ git_repository *repo)
{
- git_object *head = NULL;
+ git_buf path = GIT_BUF_INIT;
+ git_buf data = GIT_BUF_INIT;
int error;
- *mailmap = NULL;
+ assert(!git_repository_is_bare(repo));
- error = git_revparse_single(&head, repo, "HEAD");
+ /* In non-bare repositories, .mailmap should be read from the workdir */
+ error = git_buf_joinpath(&path, git_repository_workdir(repo), ".mailmap");
if (error < 0)
goto cleanup;
- error = git_mailmap_from_tree(mailmap, head);
+ error = git_futils_readbuffer(&data, git_buf_cstr(&path));
+ if (error < 0)
+ goto cleanup;
+
+ error = git_mailmap_parse(mailmap, data.ptr, data.size);
+ if (error < 0)
+ goto cleanup;
cleanup:
- if (head)
- git_object_free(head);
+ git_buf_free(&path);
+ git_buf_free(&data);
+
return error;
}
+
+int git_mailmap_from_repo(git_mailmap **mailmap, git_repository *repo)
+{
+ assert(mailmap && repo);
+
+ *mailmap = NULL;
+
+ if (git_repository_is_bare(repo))
+ return git_mailmap_from_bare_repo(mailmap, repo);
+ else
+ return git_mailmap_from_workdir_repo(mailmap, repo);
+}