Commit 8ff0504d by Nika Layzell

mailmap: Rewrite API to support accurate mailmap resolution

parent 18ff9bab
...@@ -21,103 +21,93 @@ ...@@ -21,103 +21,93 @@
GIT_BEGIN_DECL GIT_BEGIN_DECL
/** /**
* A single entry parsed from a mailmap. * Allocate a new mailmap object.
*/
typedef 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. Malformed entries in the
* mailmap are ignored.
* *
* The mailmap must be freed with 'git_mailmap_free'. * This object is empty, so you'll have to add a mailmap file before you can do
* anything with it. The mailmap must be freed with 'git_mailmap_free'.
* *
* @param out pointer to store the mailmap * @param out pointer to store the new mailmap
* @param buffer buffer to parse the mailmap from * @return 0 on success, or an error code
* @return 0 on success, otherwise an error code
*/ */
GIT_EXTERN(int) git_mailmap_from_buffer(git_mailmap **out, git_buf *buffer); GIT_EXTERN(int) git_mailmap_new(git_mailmap **out);
/** /**
* Create a mailmap object from the given repository. Malformed entries in the * Free the mailmap and its associated memory.
* mailmap are ignored.
*
* If the repository is not bare, the repository's working directory root will
* be checked for the '.mailmap' file to be parsed.
*
* 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 mm the mailmap to free
* @param repo repository to find the .mailmap in
* @return 0 on success; GIT_ENOTFOUND if .mailmap could not be found,
* otherwise an error code.
*/ */
GIT_EXTERN(int) git_mailmap_from_repo(git_mailmap **out, git_repository *repo); GIT_EXTERN(void) git_mailmap_free(git_mailmap *mm);
/** /**
* Free a mailmap created by 'git_mailmap_from_buffer' or * Add a single entry to the given mailmap object. If the entry already exists,
* 'git_mailmap_from_repo'. * it will be replaced with the new entry.
*
* @param mm mailmap to add the entry to
* @param real_name the real name to use, or NULL
* @param real_email the real email to use, or NULL
* @param replace_name the name to replace, or NULL
* @param replace_email the email to replace
* @return 0 if it was added, EEXISTS if it replaced an entry, or an error code
*/ */
GIT_EXTERN(void) git_mailmap_free(git_mailmap *mailmap); GIT_EXTERN(int) git_mailmap_add_entry(
git_mailmap *mm, const char *real_name, const char *real_email,
const char *replace_name, const char *replace_email);
/** /**
* Resolve a name and email to the corresponding real name and email. * Parse mailmap entries from a buffer.
* *
* The lifetime of the string results is tied to the `mailmap`, `name`, and * @param mm mailmap to add the entries to
* `email` parameters. * @param buf the buffer to read the mailmap file from
* * @return 0 on success, or an error code
* @param name_out either 'name', or the real name to use.
* 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. (may be NULL)
* @param name the name to resolve.
* @param email the email to resolve.
* @return 0 on success, otherwise an error code.
*/ */
GIT_EXTERN(int) git_mailmap_resolve( GIT_EXTERN(int) git_mailmap_add_buffer(git_mailmap *mm, const git_buf *buf);
const char **name_out, const char **email_out,
const git_mailmap *mailmap, const char *name, const char *email);
/** /**
* Get the number of mailmap entries in this mailmap. * Create a new mailmap instance containing a single mailmap file
*
* This method is a simple utility wrapper for the following sequence
* of calls:
* - git_mailmap_new
* - git_mailmap_add_buffer
*
* @param out pointer to store the new mailmap
* @param buf buffer to parse the mailmap from
* @return 0 on success, or an error code
*/ */
GIT_EXTERN(size_t) git_mailmap_entry_count(const git_mailmap *mailmap); GIT_EXTERN(int) git_mailmap_from_buffer(git_mailmap **out, const git_buf *buf);
/** /**
* Lookup a mailmap entry by index. * Create a new mailmap instance from a repository, loading mailmap files based
* on the repository's configuration.
* *
* Do not free the mailmap entry, it is owned by the mailmap. * Mailmaps are loaded in the following order:
* 1. '.mailmap' in the root of the repository's working directory, if present.
* 2. The blob object identified by the 'mailmap.blob' config entry, if set.
* [NOTE: 'mailmap.blob' defaults to 'HEAD:.mailmap' in bare repositories]
* 3. The path in the 'mailmap.file' config entry, if set.
* *
* @return the mailmap entry at index, or NULL if it cannot be found. * @param out pointer to store the new mailmap
* @param repo repository to load mailmap information from
* @return 0 on success, or an error code
*/ */
GIT_EXTERN(const git_mailmap_entry *) git_mailmap_entry_byindex( GIT_EXTERN(int) git_mailmap_from_repository(
const git_mailmap *mailmap, size_t idx); git_mailmap **out, git_repository *repo);
/** /**
* Lookup a mailmap entry by name/email pair. * Resolve a name and email to the corresponding real name and email.
* *
* Do not free the mailmap entry, it is owned by the mailmap. * The lifetime of the strings are tied to `mm`, `name`, and `email` parameters.
* *
* @param mailmap the mailmap to perform the lookup in. (may be NULL) * @param real_name pointer to store the real name
* @param name the name to perform the lookup with. * @param real_email pointer to store the real email
* @param email the email to perform the lookup with. * @param mm the mailmap to perform a lookup with (may be NULL)
* @return the corresponding mailmap entry, or NULL if it cannot be found. * @param name the name to look up
* @param email the email to look up
* @return 0 on success, or an error code
*/ */
GIT_EXTERN(const git_mailmap_entry *) git_mailmap_entry_lookup( GIT_EXTERN(int) git_mailmap_resolve(
const git_mailmap *mailmap, const char *name, const char *email); const char **real_name, const char **real_email,
const git_mailmap *mm, const char *name, const char *email);
/** @} */ /** @} */
GIT_END_DECL GIT_END_DECL
......
...@@ -134,7 +134,7 @@ git_blame* git_blame__alloc( ...@@ -134,7 +134,7 @@ git_blame* git_blame__alloc(
} }
if (opts.flags & GIT_BLAME_USE_MAILMAP) if (opts.flags & GIT_BLAME_USE_MAILMAP)
git_mailmap_from_repo(&gbr->mailmap, repo); git_mailmap_from_repository(&gbr->mailmap, repo);
return gbr; return gbr;
} }
......
/*
* Copyright (C) the libgit2 contributors. All rights reserved.
*
* 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_mailmap_h__
#define INCLUDE_mailmap_h__
#include "git2/mailmap.h"
#include "vector.h"
/*
* A mailmap is stored as a sorted vector of 'git_mailmap_entry's. These entries
* are sorted first by 'replace_email', and then by 'replace_name'. NULL
* replace_names are ordered first.
*
* Looking up a name and email in the mailmap is done with a binary search.
*/
struct git_mailmap {
git_vector entries;
};
/* Single entry parsed from a mailmap */
typedef struct git_mailmap_entry {
char *real_name; /**< the real name (may be NULL) */
char *real_email; /**< the real email (may be NULL) */
char *replace_name; /**< the name to replace (may be NULL) */
char *replace_email; /**< the email to replace */
} git_mailmap_entry;
const git_mailmap_entry *git_mailmap_entry_lookup(
const git_mailmap *mm, const char *name, const char *email);
#endif
...@@ -116,7 +116,8 @@ int git_signature_with_mailmap( ...@@ -116,7 +116,8 @@ int git_signature_with_mailmap(
if (source == NULL) if (source == NULL)
return 0; return 0;
error = git_mailmap_resolve(&name, &email, mailmap, source->name, source->email); error = git_mailmap_resolve(
&name, &email, mailmap, source->name, source->email);
if (error < 0) if (error < 0)
return error; return error;
......
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