Skip to content

Commit b05fbba

Browse files
committed
mailmap: Make everything a bit more style conforming
1 parent 939d8d5 commit b05fbba

File tree

2 files changed

+113
-55
lines changed

2 files changed

+113
-55
lines changed

include/git2/mailmap.h

Lines changed: 31 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
#define INCLUDE_git_mailmap_h__
99

1010
#include "common.h"
11-
#include "tree.h"
11+
#include "types.h"
1212

1313
/**
1414
* @file git2/mailmap.h
@@ -19,24 +19,27 @@
1919
*/
2020
GIT_BEGIN_DECL
2121

22-
typedef struct git_mailmap git_mailmap;
23-
2422
/**
2523
* A single entry parsed from a mailmap.
2624
*/
27-
typedef struct git_mailmap_entry {
25+
struct git_mailmap_entry {
26+
unsigned int version;
27+
2828
const char *real_name; /**< the real name (may be NULL) */
2929
const char *real_email; /**< the real email (may be NULL) */
3030
const char *replace_name; /**< the name to replace (may be NULL) */
3131
const char *replace_email; /**< the email to replace */
32-
} git_mailmap_entry;
32+
};
33+
34+
#define GIT_MAILMAP_ENTRY_VERSION 1
35+
#define GIT_MAILMAP_ENTRY_INIT {GIT_MAILMAP_ENTRY_VERSION}
3336

3437
/**
3538
* Create a mailmap object by parsing a mailmap file.
3639
*
3740
* The mailmap must be freed with 'git_mailmap_free'.
3841
*
39-
* @param out Pointer to store the mailmap
42+
* @param out pointer to store the mailmap
4043
* @param data raw data buffer to parse
4144
* @param size size of the raw data buffer
4245
* @return 0 on success
@@ -47,35 +50,26 @@ GIT_EXTERN(int) git_mailmap_parse(
4750
size_t size);
4851

4952
/**
50-
* Create a mailmap object by parsing the ".mailmap" file in the tree root.
53+
* Create a mailmap object from the given repository.
5154
*
52-
* The mailmap must be freed with 'git_mailmap_free'.
55+
* If the repository is not bare, the repository's working directory root will
56+
* be checked for the '.mailmap' file to be parsed.
5357
*
54-
* @param out pointer to store the mailmap
55-
* @param treeish root object that can be peeled to a tree
56-
* @return 0 on success; GIT_ENOTFOUND if .mailmap does not exist.
57-
*/
58-
GIT_EXTERN(int) git_mailmap_from_tree(
59-
git_mailmap **out,
60-
const git_object *treeish);
61-
62-
/**
63-
* Create a mailmap object by parsing the ".mailmap" file in the repository's
64-
* HEAD's tree root.
58+
* If the repository is bare, the repository's HEAD commit's tree root will be
59+
* searched for the '.mailmap' file to be parsed.
6560
*
6661
* The mailmap must be freed with 'git_mailmap_free'.
6762
*
6863
* @param out pointer to store the mailmap
6964
* @param repo repository to find the .mailmap in
70-
* @return 0 on success; GIT_ENOTFOUND if .mailmap does not exist.
65+
* @return 0 on success; GIT_ENOTFOUND if .mailmap could not be found.
7166
*/
7267
GIT_EXTERN(int) git_mailmap_from_repo(
7368
git_mailmap **out,
7469
git_repository *repo);
7570

7671
/**
77-
* Free a mailmap created by 'git_mailmap_parse', 'git_mailmap_from_tree' or
78-
* 'git_mailmap_from_repo'.
72+
* Free a mailmap created by 'git_mailmap_parse' or 'git_mailmap_from_repo'.
7973
*/
8074
GIT_EXTERN(void) git_mailmap_free(git_mailmap *mailmap);
8175

@@ -86,38 +80,45 @@ GIT_EXTERN(void) git_mailmap_free(git_mailmap *mailmap);
8680
* You should NOT free this value.
8781
* @param email_out either 'email' or the real email to use,
8882
* You should NOT free this value.
89-
* @param mailmap the mailmap to perform the lookup in.
83+
* @param mailmap the mailmap to perform the lookup in. (may be NULL)
9084
* @param name the name to resolve.
9185
* @param email the email to resolve.
9286
*/
9387
GIT_EXTERN(void) git_mailmap_resolve(
9488
const char **name_out,
9589
const char **email_out,
96-
git_mailmap *mailmap,
90+
const git_mailmap *mailmap,
9791
const char *name,
9892
const char *email);
9993

10094
/**
101-
* Get the number of mailmap entries.
95+
* Get the number of mailmap entries in this mailmap.
10296
*/
103-
GIT_EXTERN(size_t) git_mailmap_entry_count(git_mailmap *mailmap);
97+
GIT_EXTERN(size_t) git_mailmap_entry_count(const git_mailmap *mailmap);
10498

10599
/**
106100
* Lookup a mailmap entry by index.
107101
*
108102
* Do not free the mailmap entry, it is owned by the mailmap.
103+
*
104+
* @return the mailmap entry at index, or NULL if it cannot be found.
109105
*/
110-
GIT_EXTERN(git_mailmap_entry *) git_mailmap_entry_byindex(
111-
git_mailmap *mailmap,
106+
GIT_EXTERN(const git_mailmap_entry *) git_mailmap_entry_byindex(
107+
const git_mailmap *mailmap,
112108
size_t idx);
113109

114110
/**
115111
* Lookup a mailmap entry by name/email pair.
116112
*
117113
* Do not free the mailmap entry, it is owned by the mailmap.
114+
*
115+
* @param mailmap the mailmap to perform the lookup in. (may be NULL)
116+
* @param name the name to perform the lookup with.
117+
* @param email the email to perform the lookup with.
118+
* @return the corresponding mailmap entry, or NULL if it cannot be found.
118119
*/
119-
GIT_EXTERN(git_mailmap_entry *) git_mailmap_entry_lookup(
120-
git_mailmap *mailmap,
120+
GIT_EXTERN(const git_mailmap_entry *) git_mailmap_entry_lookup(
121+
const git_mailmap *mailmap,
121122
const char *name,
122123
const char *email);
123124

src/mailmap.c

Lines changed: 82 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,8 @@ static int git_mailmap_parse_single(
135135
*real_name = name_a;
136136

137137
if (two_emails) {
138-
*real_email = email_a;
138+
if (email_a.len > 0)
139+
*real_email = email_a;
139140
*replace_email = email_b;
140141

141142
if (name_b.len > 0)
@@ -158,6 +159,9 @@ int git_mailmap_parse(
158159
git_mailmap_entry* entry = NULL;
159160
int error = 0;
160161

162+
if (memchr(data, '\0', size) != NULL)
163+
return -1; /* data may not contain '\0's */
164+
161165
*mailmap = git__calloc(1, sizeof(git_mailmap));
162166
if (!*mailmap)
163167
return -1;
@@ -194,6 +198,7 @@ int git_mailmap_parse(
194198
error = -1;
195199
goto cleanup;
196200
}
201+
entry->version = GIT_MAILMAP_ENTRY_VERSION;
197202

198203
buf = (char*)(entry + 1);
199204
entry->real_name = range_copyz(&buf, NULL, real_name);
@@ -209,9 +214,8 @@ int git_mailmap_parse(
209214
}
210215

211216
cleanup:
212-
if (entry)
213-
git__free(entry);
214-
if (error < 0 && *mailmap) {
217+
git__free(entry);
218+
if (error < 0)
215219
git_mailmap_free(*mailmap);
216220
*mailmap = NULL;
217221
}
@@ -220,22 +224,29 @@ int git_mailmap_parse(
220224

221225
void git_mailmap_free(git_mailmap *mailmap)
222226
{
227+
if (!mailmap)
228+
return;
229+
223230
git_vector_free_deep(&mailmap->entries);
224231
git__free(mailmap);
225232
}
226233

227234
void git_mailmap_resolve(
228235
const char **name_out,
229236
const char **email_out,
230-
git_mailmap *mailmap,
237+
const git_mailmap *mailmap,
231238
const char *name,
232239
const char *email)
233240
{
234-
git_mailmap_entry *entry = NULL;
241+
const git_mailmap_entry *entry = NULL;
242+
assert(name && email);
235243

236244
*name_out = name;
237245
*email_out = email;
238246

247+
if (!mailmap)
248+
return;
249+
239250
entry = git_mailmap_entry_lookup(mailmap, name, email);
240251
if (entry) {
241252
if (entry->real_name)
@@ -245,14 +256,17 @@ void git_mailmap_resolve(
245256
}
246257
}
247258

248-
git_mailmap_entry *git_mailmap_entry_lookup(
249-
git_mailmap *mailmap,
259+
const git_mailmap_entry *git_mailmap_entry_lookup(
260+
const git_mailmap *mailmap,
250261
const char *name,
251262
const char *email)
252263
{
253264
size_t i;
254265
git_mailmap_entry *entry;
255-
assert(mailmap && name && email);
266+
assert(name && email);
267+
268+
if (!mailmap)
269+
return NULL;
256270

257271
git_vector_foreach(&mailmap->entries, i, entry) {
258272
if (!git__strcmp(email, entry->replace_email) &&
@@ -264,26 +278,42 @@ git_mailmap_entry *git_mailmap_entry_lookup(
264278
return NULL;
265279
}
266280

267-
git_mailmap_entry *git_mailmap_entry_byindex(git_mailmap *mailmap, size_t idx)
281+
const git_mailmap_entry *git_mailmap_entry_byindex(
282+
const git_mailmap *mailmap, size_t idx)
268283
{
269-
return git_vector_get(&mailmap->entries, idx);
284+
if (mailmap)
285+
return git_vector_get(&mailmap->entries, idx);
286+
return NULL;
270287
}
271288

272-
size_t git_mailmap_entry_count(git_mailmap *mailmap)
289+
size_t git_mailmap_entry_count(const git_mailmap *mailmap)
273290
{
274-
return git_vector_length(&mailmap->entries);
291+
if (mailmap)
292+
return git_vector_length(&mailmap->entries);
293+
return 0;
275294
}
276295

277-
int git_mailmap_from_tree(
296+
static int git_mailmap_from_bare_repo(
278297
git_mailmap **mailmap,
279-
const git_object *treeish)
298+
git_repository *repo)
280299
{
300+
git_reference *head = NULL;
301+
git_object *tree = NULL;
281302
git_blob *blob = NULL;
282303
const char *content = NULL;
283304
git_off_t size = 0;
284305
int error;
285306

286-
*mailmap = NULL;
307+
assert(git_repository_is_bare(repo));
308+
309+
/* In bare repositories, fall back to reading from HEAD's tree */
310+
error = git_repository_head(&head, repo);
311+
if (error < 0)
312+
goto cleanup;
313+
314+
error = git_reference_peel(&tree, head, GIT_OBJ_TREE);
315+
if (error < 0)
316+
goto cleanup;
287317

288318
error = git_object_lookup_bypath(
289319
(git_object **) &blob,
@@ -297,28 +327,55 @@ int git_mailmap_from_tree(
297327
size = git_blob_rawsize(blob);
298328

299329
error = git_mailmap_parse(mailmap, content, size);
330+
if (error < 0)
331+
goto cleanup;
300332

301333
cleanup:
302-
if (blob != NULL)
303-
git_blob_free(blob);
334+
git_reference_free(head);
335+
git_object_free(tree);
336+
git_blob_free(blob);
337+
304338
return error;
305339
}
306340

307-
int git_mailmap_from_repo(git_mailmap **mailmap, git_repository *repo)
341+
static int git_mailmap_from_workdir_repo(
342+
git_mailmap **mailmap,
343+
git_repository *repo)
308344
{
309-
git_object *head = NULL;
345+
git_buf path = GIT_BUF_INIT;
346+
git_buf data = GIT_BUF_INIT;
310347
int error;
311348

312-
*mailmap = NULL;
349+
assert(!git_repository_is_bare(repo));
313350

314-
error = git_revparse_single(&head, repo, "HEAD");
351+
/* In non-bare repositories, .mailmap should be read from the workdir */
352+
error = git_buf_joinpath(&path, git_repository_workdir(repo), ".mailmap");
315353
if (error < 0)
316354
goto cleanup;
317355

318-
error = git_mailmap_from_tree(mailmap, head);
356+
error = git_futils_readbuffer(&data, git_buf_cstr(&path));
357+
if (error < 0)
358+
goto cleanup;
359+
360+
error = git_mailmap_parse(mailmap, data.ptr, data.size);
361+
if (error < 0)
362+
goto cleanup;
319363

320364
cleanup:
321-
if (head)
322-
git_object_free(head);
365+
git_buf_free(&path);
366+
git_buf_free(&data);
367+
323368
return error;
324369
}
370+
371+
int git_mailmap_from_repo(git_mailmap **mailmap, git_repository *repo)
372+
{
373+
assert(mailmap && repo);
374+
375+
*mailmap = NULL;
376+
377+
if (git_repository_is_bare(repo))
378+
return git_mailmap_from_bare_repo(mailmap, repo);
379+
else
380+
return git_mailmap_from_workdir_repo(mailmap, repo);
381+
}

0 commit comments

Comments
 (0)