path_without_prefix = path.buf + args->baselen;
setup_archive_check(check);
- if (!git_checkattr(path_without_prefix, ARRAY_SIZE(check), check)) {
+ if (!git_check_attr(path_without_prefix, ARRAY_SIZE(check), check)) {
if (ATTR_TRUE(check[0].value))
return 0;
convert = ATTR_TRUE(check[1].value);
static int parse_archive_args(int argc, const char **argv,
const struct archiver **ar, struct archiver_args *args,
- const char *name_hint)
+ const char *name_hint, int is_remote)
{
const char *format = NULL;
const char *base = NULL;
"prepend prefix to each pathname in the archive"),
OPT_STRING('o', "output", &output, "file",
"write the archive to this file"),
- OPT_BOOLEAN(0, "worktree-attributes", &worktree_attributes,
+ OPT_BOOL(0, "worktree-attributes", &worktree_attributes,
"read .gitattributes in working directory"),
OPT__VERBOSE(&verbose, "report archived files on stderr"),
OPT__COMPR('0', &compression_level, "store only", 0),
OPT__COMPR_HIDDEN('8', &compression_level, 8),
OPT__COMPR('9', &compression_level, "compress better", 9),
OPT_GROUP(""),
- OPT_BOOLEAN('l', "list", &list,
+ OPT_BOOL('l', "list", &list,
"list supported archive formats"),
OPT_GROUP(""),
OPT_STRING(0, "remote", &remote, "repo",
if (list) {
for (i = 0; i < nr_archivers; i++)
- printf("%s\n", archivers[i]->name);
+ if (!is_remote || archivers[i]->flags & ARCHIVER_REMOTE)
+ printf("%s\n", archivers[i]->name);
exit(0);
}
if (argc < 1)
usage_with_options(archive_usage, opts);
*ar = lookup_archiver(format);
- if (!*ar)
+ if (!*ar || (is_remote && !((*ar)->flags & ARCHIVER_REMOTE)))
die("Unknown archive format '%s'", format);
args->compression_level = Z_DEFAULT_COMPRESSION;
}
int write_archive(int argc, const char **argv, const char *prefix,
- int setup_prefix, const char *name_hint)
+ int setup_prefix, const char *name_hint, int remote)
{
int nongit = 0;
const struct archiver *ar = NULL;
init_tar_archiver();
init_zip_archiver();
- argc = parse_archive_args(argc, argv, &ar, &args, name_hint);
+ argc = parse_archive_args(argc, argv, &ar, &args, name_hint, remote);
if (nongit) {
/*
* We know this will die() with an error, so we could just
return ar->write_archive(ar, &args);
}
+static int match_extension(const char *filename, const char *ext)
+{
+ int prefixlen = strlen(filename) - strlen(ext);
+
+ /*
+ * We need 1 character for the '.', and 1 character to ensure that the
+ * prefix is non-empty (k.e., we don't match .tar.gz with no actual
+ * filename).
+ */
+ if (prefixlen < 2 || filename[prefixlen-1] != '.')
+ return 0;
+ return !strcmp(filename + prefixlen, ext);
+}
+
const char *archive_format_from_filename(const char *filename)
{
- const char *ext = strrchr(filename, '.');
- if (!ext)
- return NULL;
- ext++;
- if (!strcasecmp(ext, "zip"))
- return "zip";
+ int i;
+
+ for (i = 0; i < nr_archivers; i++)
+ if (match_extension(filename, archivers[i]->name))
+ return archivers[i]->name;
return NULL;
}