提交 0f4b377c 编写于 作者: D Dmitry Potapov 提交者: Junio C Hamano

git-archive: infer output format from filename when unspecified

A command line

    $ git archive -o my-v2.0.zip v2.0

almost certainly wants the output in zip format, even though it does not
specify any --format option.

When --format is not given, but output filename is, try to infer what
format is requested from the filename extension.  Currently this code only
knows about '.zip'.  When the format is unspecified and the filename does
not tell us, the output will be in 'tar' format as before.

Of course, an explicit --format will not trigger this guesswork.
Signed-off-by: NDmitry Potapov <dpotapov@gmail.com>
Signed-off-by: NJunio C Hamano <gitster@pobox.com>
上级 518ef8f0
......@@ -34,8 +34,11 @@ OPTIONS
-------
--format=<fmt>::
Format of the resulting archive: 'tar' or 'zip'. The default
is 'tar'.
Format of the resulting archive: 'tar' or 'zip'. If this option
is not given, and the output file is specified, the format is
inferred from the filename if possible (e.g. writing to "foo.zip"
makes the output to be in the zip format). Otherwise the output
format is `tar`.
-l::
--list::
......@@ -130,6 +133,12 @@ git archive --format=zip --prefix=git-docs/ HEAD:Documentation/ > git-1.4.0-docs
Put everything in the current head's Documentation/ directory
into 'git-1.4.0-docs.zip', with the prefix 'git-docs/'.
git archive -o latest.zip HEAD::
Create a Zip archive that contains the contents of the latest
commit on the current branch. Note that the output format is
inferred by the extension of the output file.
SEE ALSO
--------
......
......@@ -60,6 +60,17 @@ static int run_remote_archiver(int argc, const char **argv,
return !!rv;
}
static const char *format_from_name(const char *filename)
{
const char *ext = strrchr(filename, '.');
if (!ext)
return NULL;
ext++;
if (!strcasecmp(ext, "zip"))
return "zip";
return NULL;
}
#define PARSE_OPT_KEEP_ALL ( PARSE_OPT_KEEP_DASHDASH | \
PARSE_OPT_KEEP_ARGV0 | \
PARSE_OPT_KEEP_UNKNOWN | \
......@@ -70,6 +81,7 @@ int cmd_archive(int argc, const char **argv, const char *prefix)
const char *exec = "git-upload-archive";
const char *output = NULL;
const char *remote = NULL;
const char *format = NULL;
struct option local_opts[] = {
OPT_STRING('o', "output", &output, "file",
"write the archive to this file"),
......@@ -77,14 +89,31 @@ int cmd_archive(int argc, const char **argv, const char *prefix)
"retrieve the archive from remote repository <repo>"),
OPT_STRING(0, "exec", &exec, "cmd",
"path to the remote git-upload-archive command"),
OPT_STRING(0, "format", &format, "fmt", "archive format"),
OPT_END()
};
char fmt_opt[32];
argc = parse_options(argc, argv, prefix, local_opts, NULL,
PARSE_OPT_KEEP_ALL);
if (output)
if (output) {
create_output_file(output);
if (!format)
format = format_from_name(output);
}
if (format) {
sprintf(fmt_opt, "--format=%s", format);
/*
* This is safe because either --format and/or --output must
* have been given on the original command line if we get to
* this point, and parse_options() must have eaten at least
* one argument, i.e. we have enough room to append to argv[].
*/
argv[argc++] = fmt_opt;
argv[argc] = NULL;
}
if (remote)
return run_remote_archiver(argc, argv, remote, exec);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册