git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v2 2/2] teach git-archive to auto detect the output format

From
Dmitry Potapov <dpotapov@gmail.com>
Date
Sep 13, 2009, 20:17 UTC
Message-ID
<20090913201701.GH30385@dpotapov.dyndns.org>
In-Reply-To
<7vzl8yr81j.fsf@alter.siamese.dyndns.org>
When I type something like this:
  git archive -o my-v2.0.zip v2.0
it is almost certainly that I want to create a zip archive, and not
a tar file.

This patch teaches git-archive to auto detect the output format from the file name. Currently, only '.zip' is supported. If the auto detect failed, the tar format is used as before. The auto detect is not used when the output format is specified explicitly.

Signed-off-by: Dmitry Potapov <dpotapov@gmail.com>
---
I have corrected all remarks except this:
On Sun, Sep 13, 2009 at 11:52:56AM -0700, Junio C Hamano wrote:
Show 6 quoted lines
> > +		sprintf(fmt_opt, "--format=%s", format);
> > +		argv[argc++] = fmt_opt;
> > +		argv[argc] = NULL;
> 
> Did you make sure you are allowed to write into argv[] and the array is
> large enough?  You probably need to make a copy of the array.

Either --output or --format option was used before, and this option is extracted from argv[] by parse_options(). So it should be space for at least one argument in argv.

 Documentation/git-archive.txt |   13 +++++++++++--
 builtin-archive.c             |   25 ++++++++++++++++++++++++-
 2 files changed, 35 insertions(+), 3 deletions(-)
diff --git a/Documentation/git-archive.txt b/Documentation/git-archive.txt
index 1917f2e..3d1c1e7 100644
--- a/Documentation/git-archive.txt
+++ b/Documentation/git-archive.txt
@@ -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
 --------
diff --git a/builtin-archive.c b/builtin-archive.c
index 565314b..6efba6f 100644
--- a/builtin-archive.c
+++ b/builtin-archive.c
@@ -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,25 @@ 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);
+		argv[argc++] = fmt_opt;
+		argv[argc] = NULL;
+	}
 
 	if (remote)
 		return run_remote_archiver(argc, argv, remote, exec);
-- 
1.6.5.rc1.2.g6bb993
Previous: Junio C HamanoNext: Junio C Hamano
Message 37 of 46 in “obnoxious CLI complaints”
  1. Brendan MillerSep 9, 2009
  2. Jakub NarebskiSep 9, 2009
  3. Wincent ColaiutaSep 9, 2009
  4. Jakub NarebskiSep 10, 2009
  5. Junio C HamanoSep 10, 2009
  6. René ScharfeSep 10, 2009
  7. Björn SteinbrinkSep 11, 2009
  8. John TapsellSep 10, 2009
  9. Sverre RabbelierSep 10, 2009
  10. Jakub NarebskiSep 10, 2009
  11. John TapsellSep 10, 2009
  12. Junio C HamanoSep 10, 2009
  13. demerphqSep 10, 2009
  14. Junio C HamanoSep 11, 2009
  15. John TapsellSep 11, 2009
  16. Junio C HamanoSep 11, 2009
  17. Brendan MillerSep 10, 2009
  18. Todd ZullingerSep 10, 2009
  19. Jakub NarebskiSep 10, 2009
  20. Eric SchaeferSep 10, 2009
  21. Sverre RabbelierSep 10, 2009
  22. René ScharfeSep 10, 2009
  23. Linus TorvaldsSep 11, 2009
  24. René ScharfeSep 11, 2009
  25. Linus TorvaldsSep 11, 2009
  26. Dmitry PotapovSep 12, 2009
  27. John TapsellSep 12, 2009
  28. Dmitry PotapovSep 12, 2009
  29. John TapsellSep 12, 2009
  30. A Large Angry SCMSep 12, 2009
  31. Dmitry PotapovSep 12, 2009
  32. John TapsellSep 12, 2009
  33. Junio C HamanoSep 13, 2009
  34. 1/2 git-archive: add '-o' as a alias for '--output'Dmitry Potapov, Sep 13, 2009
  35. 2/2 teach git-archive to auto detect the output formatDmitry Potapov, Sep 13, 2009
  36. Junio C HamanoSep 13, 2009
  37. 2/2 teach git-archive to auto detect the output formatDmitry Potapov, Sep 13, 2009
  38. Junio C HamanoSep 13, 2009
  39. Junio C HamanoSep 13, 2009
  40. 1/2 git-archive: add '-o' as a alias for '--output'Dmitry Potapov, Sep 13, 2009
  41. Brendan MillerSep 17, 2009
  42. Junio C HamanoSep 17, 2009
  43. Sverre RabbelierSep 9, 2009
  44. Pierre HabouzitSep 9, 2009
  45. Björn SteinbrinkSep 10, 2009
  46. Matthieu MoySep 10, 2009

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.