builtin-am: support and auto-detect StGit series files
Sincec574e68
(git-am foreign patch support: StGIT support, 2009-05-27), git-am.sh is able to read a single StGit series file and, for each StGit patch listed in the file, convert the StGit patch into a RFC2822 mail patch suitable for parsing with git-mailinfo, and queue them in the state directory for applying. Since15ced75
(git-am foreign patch support: autodetect some patch formats, 2009-05-27), git-am.sh is able to auto-detect StGit series files by checking to see if the file starts with the string: # This series applies on GIT commit Re-implement the above in builtin/am.c. Signed-off-by: Paul Tan <pyokagan@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
5ae41c79b8
commit
336108c156
59
builtin/am.c
59
builtin/am.c
@ -80,7 +80,8 @@ static int str_isspace(const char *str)
|
|||||||
enum patch_format {
|
enum patch_format {
|
||||||
PATCH_FORMAT_UNKNOWN = 0,
|
PATCH_FORMAT_UNKNOWN = 0,
|
||||||
PATCH_FORMAT_MBOX,
|
PATCH_FORMAT_MBOX,
|
||||||
PATCH_FORMAT_STGIT
|
PATCH_FORMAT_STGIT,
|
||||||
|
PATCH_FORMAT_STGIT_SERIES
|
||||||
};
|
};
|
||||||
|
|
||||||
enum keep_type {
|
enum keep_type {
|
||||||
@ -650,6 +651,11 @@ static int detect_patch_format(const char **paths)
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (starts_with(l1.buf, "# This series applies on GIT commit")) {
|
||||||
|
ret = PATCH_FORMAT_STGIT_SERIES;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
strbuf_reset(&l2);
|
strbuf_reset(&l2);
|
||||||
strbuf_getline_crlf(&l2, fp);
|
strbuf_getline_crlf(&l2, fp);
|
||||||
strbuf_reset(&l3);
|
strbuf_reset(&l3);
|
||||||
@ -800,6 +806,53 @@ static int stgit_patch_to_mail(FILE *out, FILE *in, int keep_cr)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function only supports a single StGit series file in `paths`.
|
||||||
|
*
|
||||||
|
* Given an StGit series file, converts the StGit patches in the series into
|
||||||
|
* RFC2822 messages suitable for parsing with git-mailinfo, and queues them in
|
||||||
|
* the state directory.
|
||||||
|
*
|
||||||
|
* Returns 0 on success, -1 on failure.
|
||||||
|
*/
|
||||||
|
static int split_mail_stgit_series(struct am_state *state, const char **paths,
|
||||||
|
int keep_cr)
|
||||||
|
{
|
||||||
|
const char *series_dir;
|
||||||
|
char *series_dir_buf;
|
||||||
|
FILE *fp;
|
||||||
|
struct argv_array patches = ARGV_ARRAY_INIT;
|
||||||
|
struct strbuf sb = STRBUF_INIT;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!paths[0] || paths[1])
|
||||||
|
return error(_("Only one StGIT patch series can be applied at once"));
|
||||||
|
|
||||||
|
series_dir_buf = xstrdup(*paths);
|
||||||
|
series_dir = dirname(series_dir_buf);
|
||||||
|
|
||||||
|
fp = fopen(*paths, "r");
|
||||||
|
if (!fp)
|
||||||
|
return error(_("could not open '%s' for reading: %s"), *paths,
|
||||||
|
strerror(errno));
|
||||||
|
|
||||||
|
while (!strbuf_getline(&sb, fp, '\n')) {
|
||||||
|
if (*sb.buf == '#')
|
||||||
|
continue; /* skip comment lines */
|
||||||
|
|
||||||
|
argv_array_push(&patches, mkpath("%s/%s", series_dir, sb.buf));
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
strbuf_release(&sb);
|
||||||
|
free(series_dir_buf);
|
||||||
|
|
||||||
|
ret = split_mail_conv(stgit_patch_to_mail, state, patches.argv, keep_cr);
|
||||||
|
|
||||||
|
argv_array_clear(&patches);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Splits a list of files/directories into individual email patches. Each path
|
* Splits a list of files/directories into individual email patches. Each path
|
||||||
* in `paths` must be a file/directory that is formatted according to
|
* in `paths` must be a file/directory that is formatted according to
|
||||||
@ -830,6 +883,8 @@ static int split_mail(struct am_state *state, enum patch_format patch_format,
|
|||||||
return split_mail_mbox(state, paths, keep_cr);
|
return split_mail_mbox(state, paths, keep_cr);
|
||||||
case PATCH_FORMAT_STGIT:
|
case PATCH_FORMAT_STGIT:
|
||||||
return split_mail_conv(stgit_patch_to_mail, state, paths, keep_cr);
|
return split_mail_conv(stgit_patch_to_mail, state, paths, keep_cr);
|
||||||
|
case PATCH_FORMAT_STGIT_SERIES:
|
||||||
|
return split_mail_stgit_series(state, paths, keep_cr);
|
||||||
default:
|
default:
|
||||||
die("BUG: invalid patch_format");
|
die("BUG: invalid patch_format");
|
||||||
}
|
}
|
||||||
@ -1880,6 +1935,8 @@ static int parse_opt_patchformat(const struct option *opt, const char *arg, int
|
|||||||
*opt_value = PATCH_FORMAT_MBOX;
|
*opt_value = PATCH_FORMAT_MBOX;
|
||||||
else if (!strcmp(arg, "stgit"))
|
else if (!strcmp(arg, "stgit"))
|
||||||
*opt_value = PATCH_FORMAT_STGIT;
|
*opt_value = PATCH_FORMAT_STGIT;
|
||||||
|
else if (!strcmp(arg, "stgit-series"))
|
||||||
|
*opt_value = PATCH_FORMAT_STGIT_SERIES;
|
||||||
else
|
else
|
||||||
return error(_("Invalid value for --patch-format: %s"), arg);
|
return error(_("Invalid value for --patch-format: %s"), arg);
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user