mirror of
https://github.com/git/git
synced 2024-10-30 14:03:28 +00:00
Teach mailsplit about Maildir's
Signed-off-by: Fernando J. Pereda <ferdy@gentoo.org> Signed-off-by: Junio C Hamano <junkio@cox.net>
This commit is contained in:
parent
98ee8187e4
commit
d63bd9a217
4 changed files with 134 additions and 31 deletions
|
@ -12,7 +12,8 @@ SYNOPSIS
|
|||
'git-am' [--signoff] [--dotest=<dir>] [--keep] [--utf8 | --no-utf8]
|
||||
[--3way] [--interactive] [--binary]
|
||||
[--whitespace=<option>] [-C<n>] [-p<n>]
|
||||
<mbox>...
|
||||
<mbox>|<Maildir>...
|
||||
|
||||
'git-am' [--skip | --resolved]
|
||||
|
||||
DESCRIPTION
|
||||
|
@ -23,9 +24,10 @@ current branch.
|
|||
|
||||
OPTIONS
|
||||
-------
|
||||
<mbox>...::
|
||||
<mbox>|<Maildir>...::
|
||||
The list of mailbox files to read patches from. If you do not
|
||||
supply this argument, reads from the standard input.
|
||||
supply this argument, reads from the standard input. If you supply
|
||||
directories, they'll be treated as Maildirs.
|
||||
|
||||
-s, --signoff::
|
||||
Add `Signed-off-by:` line to the commit message, using
|
||||
|
|
|
@ -7,12 +7,15 @@ git-mailsplit - Simple UNIX mbox splitter program
|
|||
|
||||
SYNOPSIS
|
||||
--------
|
||||
'git-mailsplit' [-b] [-f<nn>] [-d<prec>] -o<directory> [--] [<mbox>...]
|
||||
'git-mailsplit' [-b] [-f<nn>] [-d<prec>] -o<directory> [--] [<mbox>|<Maildir>...]
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
Splits a mbox file into a list of files: "0001" "0002" .. in the specified
|
||||
directory so you can process them further from there.
|
||||
Splits a mbox file or a Maildir into a list of files: "0001" "0002" .. in the
|
||||
specified directory so you can process them further from there.
|
||||
|
||||
IMPORTANT: Maildir splitting relies upon filenames being sorted to output
|
||||
patches in the correct order.
|
||||
|
||||
OPTIONS
|
||||
-------
|
||||
|
@ -20,6 +23,10 @@ OPTIONS
|
|||
Mbox file to split. If not given, the mbox is read from
|
||||
the standard input.
|
||||
|
||||
<Maildir>::
|
||||
Root of the Maildir to split. This directory should contain the cur, tmp
|
||||
and new subdirectories.
|
||||
|
||||
<directory>::
|
||||
Directory in which to place the individual messages.
|
||||
|
||||
|
|
|
@ -6,9 +6,10 @@
|
|||
*/
|
||||
#include "cache.h"
|
||||
#include "builtin.h"
|
||||
#include "path-list.h"
|
||||
|
||||
static const char git_mailsplit_usage[] =
|
||||
"git-mailsplit [-d<prec>] [-f<n>] [-b] -o<directory> <mbox>...";
|
||||
"git-mailsplit [-d<prec>] [-f<n>] [-b] -o<directory> <mbox>|<Maildir>...";
|
||||
|
||||
static int is_from_line(const char *line, int len)
|
||||
{
|
||||
|
@ -96,13 +97,74 @@ static int split_one(FILE *mbox, const char *name, int allow_bare)
|
|||
exit(1);
|
||||
}
|
||||
|
||||
int split_mbox(const char **mbox, const char *dir, int allow_bare, int nr_prec, int skip)
|
||||
static int populate_maildir_list(struct path_list *list, const char *path)
|
||||
{
|
||||
char *name = xmalloc(strlen(dir) + 2 + 3 * sizeof(skip));
|
||||
DIR *dir;
|
||||
struct dirent *dent;
|
||||
|
||||
if ((dir = opendir(path)) == NULL) {
|
||||
error("cannot opendir %s (%s)", path, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
while ((dent = readdir(dir)) != NULL) {
|
||||
if (dent->d_name[0] == '.')
|
||||
continue;
|
||||
path_list_insert(dent->d_name, list);
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int split_maildir(const char *maildir, const char *dir,
|
||||
int nr_prec, int skip)
|
||||
{
|
||||
char file[PATH_MAX];
|
||||
char curdir[PATH_MAX];
|
||||
char name[PATH_MAX];
|
||||
int ret = -1;
|
||||
int i;
|
||||
struct path_list list = {NULL, 0, 0, 1};
|
||||
|
||||
snprintf(curdir, sizeof(curdir), "%s/cur", maildir);
|
||||
if (populate_maildir_list(&list, curdir) < 0)
|
||||
goto out;
|
||||
|
||||
for (i = 0; i < list.nr; i++) {
|
||||
FILE *f;
|
||||
snprintf(file, sizeof(file), "%s/%s", curdir, list.items[i].path);
|
||||
f = fopen(file, "r");
|
||||
if (!f) {
|
||||
error("cannot open mail %s (%s)", file, strerror(errno));
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (fgets(buf, sizeof(buf), f) == NULL) {
|
||||
error("cannot read mail %s (%s)", file, strerror(errno));
|
||||
goto out;
|
||||
}
|
||||
|
||||
sprintf(name, "%s/%0*d", dir, nr_prec, ++skip);
|
||||
split_one(f, name, 1);
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
path_list_clear(&list, 1);
|
||||
|
||||
ret = skip;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int split_mbox(const char *file, const char *dir, int allow_bare,
|
||||
int nr_prec, int skip)
|
||||
{
|
||||
char name[PATH_MAX];
|
||||
int ret = -1;
|
||||
|
||||
while (*mbox) {
|
||||
const char *file = *mbox++;
|
||||
FILE *f = !strcmp(file, "-") ? stdin : fopen(file, "r");
|
||||
int file_done = 0;
|
||||
|
||||
|
@ -112,11 +174,13 @@ int split_mbox(const char **mbox, const char *dir, int allow_bare, int nr_prec,
|
|||
}
|
||||
|
||||
if (fgets(buf, sizeof(buf), f) == NULL) {
|
||||
if (f == stdin)
|
||||
break; /* empty stdin is OK */
|
||||
/* empty stdin is OK */
|
||||
if (f != stdin) {
|
||||
error("cannot read mbox %s", file);
|
||||
goto out;
|
||||
}
|
||||
file_done = 1;
|
||||
}
|
||||
|
||||
while (!file_done) {
|
||||
sprintf(name, "%s/%0*d", dir, nr_prec, ++skip);
|
||||
|
@ -125,15 +189,15 @@ int split_mbox(const char **mbox, const char *dir, int allow_bare, int nr_prec,
|
|||
|
||||
if (f != stdin)
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
ret = skip;
|
||||
out:
|
||||
free(name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int cmd_mailsplit(int argc, const char **argv, const char *prefix)
|
||||
{
|
||||
int nr = 0, nr_prec = 4, ret;
|
||||
int nr = 0, nr_prec = 4, num = 0;
|
||||
int allow_bare = 0;
|
||||
const char *dir = NULL;
|
||||
const char **argp;
|
||||
|
@ -186,9 +250,39 @@ int cmd_mailsplit(int argc, const char **argv, const char *prefix)
|
|||
argp = stdin_only;
|
||||
}
|
||||
|
||||
ret = split_mbox(argp, dir, allow_bare, nr_prec, nr);
|
||||
if (ret != -1)
|
||||
printf("%d\n", ret);
|
||||
while (*argp) {
|
||||
const char *arg = *argp++;
|
||||
struct stat argstat;
|
||||
int ret = 0;
|
||||
|
||||
return ret == -1;
|
||||
if (arg[0] == '-' && arg[1] == 0) {
|
||||
ret = split_mbox(arg, dir, allow_bare, nr_prec, nr);
|
||||
if (ret < 0) {
|
||||
error("cannot split patches from stdin");
|
||||
return 1;
|
||||
}
|
||||
num += ret;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (stat(arg, &argstat) == -1) {
|
||||
error("cannot stat %s (%s)", arg, strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (S_ISDIR(argstat.st_mode))
|
||||
ret = split_maildir(arg, dir, nr_prec, nr);
|
||||
else
|
||||
ret = split_mbox(arg, dir, allow_bare, nr_prec, nr);
|
||||
|
||||
if (ret < 0) {
|
||||
error("cannot split patches from %s", arg);
|
||||
return 1;
|
||||
}
|
||||
num += ret;
|
||||
}
|
||||
|
||||
printf("%d\n", num);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ extern const char git_usage_string[];
|
|||
|
||||
extern void help_unknown_cmd(const char *cmd);
|
||||
extern int mailinfo(FILE *in, FILE *out, int ks, const char *encoding, const char *msg, const char *patch);
|
||||
extern int split_mbox(const char **mbox, const char *dir, int allow_bare, int nr_prec, int skip);
|
||||
extern int split_mbox(const char *file, const char *dir, int allow_bare, int nr_prec, int skip);
|
||||
extern void stripspace(FILE *in, FILE *out);
|
||||
extern int write_tree(unsigned char *sha1, int missing_ok, const char *prefix);
|
||||
extern void prune_packed_objects(int);
|
||||
|
|
Loading…
Reference in a new issue