+static int write_archive_type(const char *format, const char *hex, const char *prefix)
+{
+ struct strvec argv = STRVEC_INIT;
+ const char **nargv;
+ int result;
+ strvec_push(&argv, "snapshot");
+ strvec_push(&argv, format);
+ if (prefix) {
+ struct strbuf buf = STRBUF_INIT;
+ strbuf_addstr(&buf, prefix);
+ strbuf_addch(&buf, '/');
+ strvec_push(&argv, "--prefix");
+ strvec_push(&argv, buf.buf);
+ strbuf_release(&buf);
+ }
+ strvec_push(&argv, hex);
+ /*
+ * Now we need to copy the pointers to arguments into a new
+ * structure because write_archive will rearrange its arguments
+ * which may result in duplicated/missing entries causing leaks
+ * or double-frees in strvec_clear.
+ */
+ nargv = xmalloc(sizeof(char *) * (argv.nr + 1));
+ /* strvec guarantees a trailing NULL entry. */
+ memcpy(nargv, argv.v, sizeof(char *) * (argv.nr + 1));
+
+ result = write_archive(argv.nr, nargv, NULL, the_repository, NULL, 0);
+ strvec_clear(&argv);
+ free(nargv);
+ return result;
+}
+
+static int write_tar_archive(const char *hex, const char *prefix)
+{
+ return write_archive_type("--format=tar", hex, prefix);
+}
+
+static int write_zip_archive(const char *hex, const char *prefix)
+{
+ return write_archive_type("--format=zip", hex, prefix);
+}
+
+static int write_compressed_tar_archive(const char *hex,
+ const char *prefix,
+ char *filter_argv[])