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
@ -12,7 +12,8 @@ SYNOPSIS
|
|||||||
'git-am' [--signoff] [--dotest=<dir>] [--keep] [--utf8 | --no-utf8]
|
'git-am' [--signoff] [--dotest=<dir>] [--keep] [--utf8 | --no-utf8]
|
||||||
[--3way] [--interactive] [--binary]
|
[--3way] [--interactive] [--binary]
|
||||||
[--whitespace=<option>] [-C<n>] [-p<n>]
|
[--whitespace=<option>] [-C<n>] [-p<n>]
|
||||||
<mbox>...
|
<mbox>|<Maildir>...
|
||||||
|
|
||||||
'git-am' [--skip | --resolved]
|
'git-am' [--skip | --resolved]
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
@ -23,9 +24,10 @@ current branch.
|
|||||||
|
|
||||||
OPTIONS
|
OPTIONS
|
||||||
-------
|
-------
|
||||||
<mbox>...::
|
<mbox>|<Maildir>...::
|
||||||
The list of mailbox files to read patches from. If you do not
|
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::
|
-s, --signoff::
|
||||||
Add `Signed-off-by:` line to the commit message, using
|
Add `Signed-off-by:` line to the commit message, using
|
||||||
|
@ -7,12 +7,15 @@ git-mailsplit - Simple UNIX mbox splitter program
|
|||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
--------
|
--------
|
||||||
'git-mailsplit' [-b] [-f<nn>] [-d<prec>] -o<directory> [--] [<mbox>...]
|
'git-mailsplit' [-b] [-f<nn>] [-d<prec>] -o<directory> [--] [<mbox>|<Maildir>...]
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
-----------
|
-----------
|
||||||
Splits a mbox file into a list of files: "0001" "0002" .. in the specified
|
Splits a mbox file or a Maildir into a list of files: "0001" "0002" .. in the
|
||||||
directory so you can process them further from there.
|
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
|
OPTIONS
|
||||||
-------
|
-------
|
||||||
@ -20,6 +23,10 @@ OPTIONS
|
|||||||
Mbox file to split. If not given, the mbox is read from
|
Mbox file to split. If not given, the mbox is read from
|
||||||
the standard input.
|
the standard input.
|
||||||
|
|
||||||
|
<Maildir>::
|
||||||
|
Root of the Maildir to split. This directory should contain the cur, tmp
|
||||||
|
and new subdirectories.
|
||||||
|
|
||||||
<directory>::
|
<directory>::
|
||||||
Directory in which to place the individual messages.
|
Directory in which to place the individual messages.
|
||||||
|
|
||||||
|
@ -6,9 +6,10 @@
|
|||||||
*/
|
*/
|
||||||
#include "cache.h"
|
#include "cache.h"
|
||||||
#include "builtin.h"
|
#include "builtin.h"
|
||||||
|
#include "path-list.h"
|
||||||
|
|
||||||
static const char git_mailsplit_usage[] =
|
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)
|
static int is_from_line(const char *line, int len)
|
||||||
{
|
{
|
||||||
@ -96,44 +97,107 @@ static int split_one(FILE *mbox, const char *name, int allow_bare)
|
|||||||
exit(1);
|
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 ret = -1;
|
||||||
|
int i;
|
||||||
|
struct path_list list = {NULL, 0, 0, 1};
|
||||||
|
|
||||||
while (*mbox) {
|
snprintf(curdir, sizeof(curdir), "%s/cur", maildir);
|
||||||
const char *file = *mbox++;
|
if (populate_maildir_list(&list, curdir) < 0)
|
||||||
FILE *f = !strcmp(file, "-") ? stdin : fopen(file, "r");
|
goto out;
|
||||||
int file_done = 0;
|
|
||||||
|
|
||||||
if ( !f ) {
|
for (i = 0; i < list.nr; i++) {
|
||||||
error("cannot open mbox %s", file);
|
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;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fgets(buf, sizeof(buf), f) == NULL) {
|
if (fgets(buf, sizeof(buf), f) == NULL) {
|
||||||
if (f == stdin)
|
error("cannot read mail %s (%s)", file, strerror(errno));
|
||||||
break; /* empty stdin is OK */
|
|
||||||
error("cannot read mbox %s", file);
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!file_done) {
|
sprintf(name, "%s/%0*d", dir, nr_prec, ++skip);
|
||||||
sprintf(name, "%s/%0*d", dir, nr_prec, ++skip);
|
split_one(f, name, 1);
|
||||||
file_done = split_one(f, name, allow_bare);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (f != stdin)
|
fclose(f);
|
||||||
fclose(f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
path_list_clear(&list, 1);
|
||||||
|
|
||||||
ret = skip;
|
ret = skip;
|
||||||
out:
|
out:
|
||||||
free(name);
|
|
||||||
return ret;
|
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;
|
||||||
|
|
||||||
|
FILE *f = !strcmp(file, "-") ? stdin : fopen(file, "r");
|
||||||
|
int file_done = 0;
|
||||||
|
|
||||||
|
if (!f) {
|
||||||
|
error("cannot open mbox %s", file);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fgets(buf, sizeof(buf), f) == NULL) {
|
||||||
|
/* 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);
|
||||||
|
file_done = split_one(f, name, allow_bare);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (f != stdin)
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
ret = skip;
|
||||||
|
out:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int cmd_mailsplit(int argc, const char **argv, const char *prefix)
|
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;
|
int allow_bare = 0;
|
||||||
const char *dir = NULL;
|
const char *dir = NULL;
|
||||||
const char **argp;
|
const char **argp;
|
||||||
@ -186,9 +250,39 @@ int cmd_mailsplit(int argc, const char **argv, const char *prefix)
|
|||||||
argp = stdin_only;
|
argp = stdin_only;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = split_mbox(argp, dir, allow_bare, nr_prec, nr);
|
while (*argp) {
|
||||||
if (ret != -1)
|
const char *arg = *argp++;
|
||||||
printf("%d\n", ret);
|
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 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 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 void stripspace(FILE *in, FILE *out);
|
||||||
extern int write_tree(unsigned char *sha1, int missing_ok, const char *prefix);
|
extern int write_tree(unsigned char *sha1, int missing_ok, const char *prefix);
|
||||||
extern void prune_packed_objects(int);
|
extern void prune_packed_objects(int);
|
||||||
|
Loading…
Reference in New Issue
Block a user