Skip to content

Commit

Permalink
archive: refactor file extension format-guessing
Browse files Browse the repository at this point in the history
Git-archive will guess a format from the output filename if
no format is explicitly given.  The current function just
hardcodes "zip" to the zip format, and leaves everything
else NULL (which will default to tar). Since we are about
to add user-specified formats, we need to be more flexible.
The new rule is "if a filename ends with a dot and the name
of a format, it matches that format". For the existing "tar"
and "zip" formats, this is identical to the current
behavior. For new user-specified formats, this will do what
the user expects if they name their formats appropriately.

Because we will eventually start matching arbitrary
user-specified extensions that may include dots, the strrchr
search for the final dot is not sufficient. We need to do an
actual suffix match with each extension.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
peff authored and gitster committed Jun 22, 2011
1 parent 56baa61 commit 08716b3
Showing 1 changed file with 19 additions and 6 deletions.
25 changes: 19 additions & 6 deletions archive.c
Expand Up @@ -419,13 +419,26 @@ int write_archive(int argc, const char **argv, const char *prefix,
return ar->write_archive(ar, &args); 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 *archive_format_from_filename(const char *filename)
{ {
const char *ext = strrchr(filename, '.'); int i;
if (!ext)
return NULL; for (i = 0; i < nr_archivers; i++)
ext++; if (match_extension(filename, archivers[i]->name))
if (!strcasecmp(ext, "zip")) return archivers[i]->name;
return "zip";
return NULL; return NULL;
} }

0 comments on commit 08716b3

Please sign in to comment.