Commit b05fbba3 by Nika Layzell

mailmap: Make everything a bit more style conforming

parent 939d8d57
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
#define INCLUDE_git_mailmap_h__ #define INCLUDE_git_mailmap_h__
#include "common.h" #include "common.h"
#include "tree.h" #include "types.h"
/** /**
* @file git2/mailmap.h * @file git2/mailmap.h
...@@ -19,24 +19,27 @@ ...@@ -19,24 +19,27 @@
*/ */
GIT_BEGIN_DECL GIT_BEGIN_DECL
typedef struct git_mailmap git_mailmap;
/** /**
* A single entry parsed from a 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_name; /**< the real name (may be NULL) */
const char *real_email; /**< the real email (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_name; /**< the name to replace (may be NULL) */
const char *replace_email; /**< the email to replace */ 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. * Create a mailmap object by parsing a mailmap file.
* *
* The mailmap must be freed with 'git_mailmap_free'. * 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 data raw data buffer to parse
* @param size size of the raw data buffer * @param size size of the raw data buffer
* @return 0 on success * @return 0 on success
...@@ -47,35 +50,26 @@ GIT_EXTERN(int) git_mailmap_parse( ...@@ -47,35 +50,26 @@ GIT_EXTERN(int) git_mailmap_parse(
size_t size); 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 * If the repository is bare, the repository's HEAD commit's tree root will be
* @param treeish root object that can be peeled to a tree * searched for the '.mailmap' file to be parsed.
* @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.
* *
* The mailmap must be freed with 'git_mailmap_free'. * The mailmap must be freed with 'git_mailmap_free'.
* *
* @param out pointer to store the mailmap * @param out pointer to store the mailmap
* @param repo repository to find the .mailmap in * @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_EXTERN(int) git_mailmap_from_repo(
git_mailmap **out, git_mailmap **out,
git_repository *repo); git_repository *repo);
/** /**
* Free a mailmap created by 'git_mailmap_parse', 'git_mailmap_from_tree' or * Free a mailmap created by 'git_mailmap_parse' or 'git_mailmap_from_repo'.
* 'git_mailmap_from_repo'.
*/ */
GIT_EXTERN(void) git_mailmap_free(git_mailmap *mailmap); GIT_EXTERN(void) git_mailmap_free(git_mailmap *mailmap);
...@@ -86,38 +80,45 @@ 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. * You should NOT free this value.
* @param email_out either 'email' or the real email to use, * @param email_out either 'email' or the real email to use,
* You should NOT free this value. * 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 name the name to resolve.
* @param email the email to resolve. * @param email the email to resolve.
*/ */
GIT_EXTERN(void) git_mailmap_resolve( GIT_EXTERN(void) git_mailmap_resolve(
const char **name_out, const char **name_out,
const char **email_out, const char **email_out,
git_mailmap *mailmap, const git_mailmap *mailmap,
const char *name, const char *name,
const char *email); 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. * Lookup a mailmap entry by index.
* *
* Do not free the mailmap entry, it is owned by the mailmap. * 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_EXTERN(const git_mailmap_entry *) git_mailmap_entry_byindex(
git_mailmap *mailmap, const git_mailmap *mailmap,
size_t idx); size_t idx);
/** /**
* Lookup a mailmap entry by name/email pair. * Lookup a mailmap entry by name/email pair.
* *
* Do not free the mailmap entry, it is owned by the mailmap. * 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_EXTERN(const git_mailmap_entry *) git_mailmap_entry_lookup(
git_mailmap *mailmap, const git_mailmap *mailmap,
const char *name, const char *name,
const char *email); const char *email);
......
...@@ -135,7 +135,8 @@ static int git_mailmap_parse_single( ...@@ -135,7 +135,8 @@ static int git_mailmap_parse_single(
*real_name = name_a; *real_name = name_a;
if (two_emails) { if (two_emails) {
*real_email = email_a; if (email_a.len > 0)
*real_email = email_a;
*replace_email = email_b; *replace_email = email_b;
if (name_b.len > 0) if (name_b.len > 0)
...@@ -158,6 +159,9 @@ int git_mailmap_parse( ...@@ -158,6 +159,9 @@ int git_mailmap_parse(
git_mailmap_entry* entry = NULL; git_mailmap_entry* entry = NULL;
int error = 0; int error = 0;
if (memchr(data, '\0', size) != NULL)
return -1; /* data may not contain '\0's */
*mailmap = git__calloc(1, sizeof(git_mailmap)); *mailmap = git__calloc(1, sizeof(git_mailmap));
if (!*mailmap) if (!*mailmap)
return -1; return -1;
...@@ -194,6 +198,7 @@ int git_mailmap_parse( ...@@ -194,6 +198,7 @@ int git_mailmap_parse(
error = -1; error = -1;
goto cleanup; goto cleanup;
} }
entry->version = GIT_MAILMAP_ENTRY_VERSION;
buf = (char*)(entry + 1); buf = (char*)(entry + 1);
entry->real_name = range_copyz(&buf, NULL, real_name); entry->real_name = range_copyz(&buf, NULL, real_name);
...@@ -209,9 +214,8 @@ int git_mailmap_parse( ...@@ -209,9 +214,8 @@ int git_mailmap_parse(
} }
cleanup: cleanup:
if (entry) git__free(entry);
git__free(entry); if (error < 0)
if (error < 0 && *mailmap) {
git_mailmap_free(*mailmap); git_mailmap_free(*mailmap);
*mailmap = NULL; *mailmap = NULL;
} }
...@@ -220,6 +224,9 @@ cleanup: ...@@ -220,6 +224,9 @@ cleanup:
void git_mailmap_free(git_mailmap *mailmap) void git_mailmap_free(git_mailmap *mailmap)
{ {
if (!mailmap)
return;
git_vector_free_deep(&mailmap->entries); git_vector_free_deep(&mailmap->entries);
git__free(mailmap); git__free(mailmap);
} }
...@@ -227,15 +234,19 @@ void git_mailmap_free(git_mailmap *mailmap) ...@@ -227,15 +234,19 @@ void git_mailmap_free(git_mailmap *mailmap)
void git_mailmap_resolve( void git_mailmap_resolve(
const char **name_out, const char **name_out,
const char **email_out, const char **email_out,
git_mailmap *mailmap, const git_mailmap *mailmap,
const char *name, const char *name,
const char *email) const char *email)
{ {
git_mailmap_entry *entry = NULL; const git_mailmap_entry *entry = NULL;
assert(name && email);
*name_out = name; *name_out = name;
*email_out = email; *email_out = email;
if (!mailmap)
return;
entry = git_mailmap_entry_lookup(mailmap, name, email); entry = git_mailmap_entry_lookup(mailmap, name, email);
if (entry) { if (entry) {
if (entry->real_name) if (entry->real_name)
...@@ -245,14 +256,17 @@ void git_mailmap_resolve( ...@@ -245,14 +256,17 @@ void git_mailmap_resolve(
} }
} }
git_mailmap_entry *git_mailmap_entry_lookup( const git_mailmap_entry *git_mailmap_entry_lookup(
git_mailmap *mailmap, const git_mailmap *mailmap,
const char *name, const char *name,
const char *email) const char *email)
{ {
size_t i; size_t i;
git_mailmap_entry *entry; git_mailmap_entry *entry;
assert(mailmap && name && email); assert(name && email);
if (!mailmap)
return NULL;
git_vector_foreach(&mailmap->entries, i, entry) { git_vector_foreach(&mailmap->entries, i, entry) {
if (!git__strcmp(email, entry->replace_email) && if (!git__strcmp(email, entry->replace_email) &&
...@@ -264,26 +278,42 @@ git_mailmap_entry *git_mailmap_entry_lookup( ...@@ -264,26 +278,42 @@ git_mailmap_entry *git_mailmap_entry_lookup(
return NULL; 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, git_mailmap **mailmap,
const git_object *treeish) git_repository *repo)
{ {
git_reference *head = NULL;
git_object *tree = NULL;
git_blob *blob = NULL; git_blob *blob = NULL;
const char *content = NULL; const char *content = NULL;
git_off_t size = 0; git_off_t size = 0;
int error; 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( error = git_object_lookup_bypath(
(git_object **) &blob, (git_object **) &blob,
...@@ -297,28 +327,55 @@ int git_mailmap_from_tree( ...@@ -297,28 +327,55 @@ int git_mailmap_from_tree(
size = git_blob_rawsize(blob); size = git_blob_rawsize(blob);
error = git_mailmap_parse(mailmap, content, size); error = git_mailmap_parse(mailmap, content, size);
if (error < 0)
goto cleanup;
cleanup: cleanup:
if (blob != NULL) git_reference_free(head);
git_blob_free(blob); git_object_free(tree);
git_blob_free(blob);
return error; 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; 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) if (error < 0)
goto cleanup; 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: cleanup:
if (head) git_buf_free(&path);
git_object_free(head); git_buf_free(&data);
return error; 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);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment