6 #include "parse-options.h"
 
   7 #include "unpack-trees.h"
 
   9 static char const * const archive_usage[] = {
 
  10         "git archive [options] <tree-ish> [<path>...]",
 
  12         "git archive --remote <repo> [--exec <cmd>] [options] <tree-ish> [<path>...]",
 
  13         "git archive --remote <repo> [--exec <cmd>] --list",
 
  17 static const struct archiver **archivers;
 
  18 static int nr_archivers;
 
  19 static int alloc_archivers;
 
  21 void register_archiver(struct archiver *ar)
 
  23         ALLOC_GROW(archivers, nr_archivers + 1, alloc_archivers);
 
  24         archivers[nr_archivers++] = ar;
 
  27 static void format_subst(const struct commit *commit,
 
  28                          const char *src, size_t len,
 
  32         struct strbuf fmt = STRBUF_INIT;
 
  33         struct pretty_print_context ctx = {0};
 
  34         ctx.date_mode = DATE_NORMAL;
 
  35         ctx.abbrev = DEFAULT_ABBREV;
 
  38                 to_free = strbuf_detach(buf, NULL);
 
  42                 b = memmem(src, len, "$Format:", 8);
 
  45                 c = memchr(b + 8, '$', (src + len) - b - 8);
 
  50                 strbuf_add(&fmt, b + 8, c - b - 8);
 
  52                 strbuf_add(buf, src, b - src);
 
  53                 format_commit_message(commit, fmt.buf, buf, &ctx);
 
  57         strbuf_add(buf, src, len);
 
  62 static void *sha1_file_to_archive(const char *path, const unsigned char *sha1,
 
  63                 unsigned int mode, enum object_type *type,
 
  64                 unsigned long *sizep, const struct commit *commit)
 
  68         buffer = read_sha1_file(sha1, type, sizep);
 
  69         if (buffer && S_ISREG(mode)) {
 
  70                 struct strbuf buf = STRBUF_INIT;
 
  73                 strbuf_attach(&buf, buffer, *sizep, *sizep + 1);
 
  74                 convert_to_working_tree(path, buf.buf, buf.len, &buf);
 
  76                         format_subst(commit, buf.buf, buf.len, &buf);
 
  77                 buffer = strbuf_detach(&buf, &size);
 
  84 static void setup_archive_check(struct git_attr_check *check)
 
  86         static struct git_attr *attr_export_ignore;
 
  87         static struct git_attr *attr_export_subst;
 
  89         if (!attr_export_ignore) {
 
  90                 attr_export_ignore = git_attr("export-ignore");
 
  91                 attr_export_subst = git_attr("export-subst");
 
  93         check[0].attr = attr_export_ignore;
 
  94         check[1].attr = attr_export_subst;
 
  97 struct archiver_context {
 
  98         struct archiver_args *args;
 
  99         write_archive_entry_fn_t write_entry;
 
 102 static int write_archive_entry(const unsigned char *sha1, const char *base,
 
 103                 int baselen, const char *filename, unsigned mode, int stage,
 
 106         static struct strbuf path = STRBUF_INIT;
 
 107         struct archiver_context *c = context;
 
 108         struct archiver_args *args = c->args;
 
 109         write_archive_entry_fn_t write_entry = c->write_entry;
 
 110         struct git_attr_check check[2];
 
 111         const char *path_without_prefix;
 
 114         enum object_type type;
 
 119         strbuf_grow(&path, PATH_MAX);
 
 120         strbuf_add(&path, args->base, args->baselen);
 
 121         strbuf_add(&path, base, baselen);
 
 122         strbuf_addstr(&path, filename);
 
 123         path_without_prefix = path.buf + args->baselen;
 
 125         setup_archive_check(check);
 
 126         if (!git_check_attr(path_without_prefix, ARRAY_SIZE(check), check)) {
 
 127                 if (ATTR_TRUE(check[0].value))
 
 129                 convert = ATTR_TRUE(check[1].value);
 
 132         if (S_ISDIR(mode) || S_ISGITLINK(mode)) {
 
 133                 strbuf_addch(&path, '/');
 
 135                         fprintf(stderr, "%.*s\n", (int)path.len, path.buf);
 
 136                 err = write_entry(args, sha1, path.buf, path.len, mode, NULL, 0);
 
 139                 return (S_ISDIR(mode) ? READ_TREE_RECURSIVE : 0);
 
 142         buffer = sha1_file_to_archive(path_without_prefix, sha1, mode,
 
 143                         &type, &size, convert ? args->commit : NULL);
 
 145                 return error("cannot read %s", sha1_to_hex(sha1));
 
 147                 fprintf(stderr, "%.*s\n", (int)path.len, path.buf);
 
 148         err = write_entry(args, sha1, path.buf, path.len, mode, buffer, size);
 
 153 int write_archive_entries(struct archiver_args *args,
 
 154                 write_archive_entry_fn_t write_entry)
 
 156         struct archiver_context context;
 
 157         struct unpack_trees_options opts;
 
 159         struct pathspec pathspec;
 
 162         if (args->baselen > 0 && args->base[args->baselen - 1] == '/') {
 
 163                 size_t len = args->baselen;
 
 165                 while (len > 1 && args->base[len - 2] == '/')
 
 168                         fprintf(stderr, "%.*s\n", (int)len, args->base);
 
 169                 err = write_entry(args, args->tree->object.sha1, args->base,
 
 170                                 len, 040777, NULL, 0);
 
 176         context.write_entry = write_entry;
 
 179          * Setup index and instruct attr to read index only
 
 181         if (!args->worktree_attributes) {
 
 182                 memset(&opts, 0, sizeof(opts));
 
 185                 opts.src_index = &the_index;
 
 186                 opts.dst_index = &the_index;
 
 187                 opts.fn = oneway_merge;
 
 188                 init_tree_desc(&t, args->tree->buffer, args->tree->size);
 
 189                 if (unpack_trees(1, &t, &opts))
 
 191                 git_attr_set_direction(GIT_ATTR_INDEX, &the_index);
 
 194         init_pathspec(&pathspec, args->pathspec);
 
 195         err = read_tree_recursive(args->tree, "", 0, 0, &pathspec,
 
 196                                   write_archive_entry, &context);
 
 197         free_pathspec(&pathspec);
 
 198         if (err == READ_TREE_RECURSIVE)
 
 203 static const struct archiver *lookup_archiver(const char *name)
 
 210         for (i = 0; i < nr_archivers; i++) {
 
 211                 if (!strcmp(name, archivers[i]->name))
 
 217 static int reject_entry(const unsigned char *sha1, const char *base,
 
 218                         int baselen, const char *filename, unsigned mode,
 
 219                         int stage, void *context)
 
 224 static int path_exists(struct tree *tree, const char *path)
 
 226         const char *paths[] = { path, NULL };
 
 227         struct pathspec pathspec;
 
 230         init_pathspec(&pathspec, paths);
 
 231         ret = read_tree_recursive(tree, "", 0, 0, &pathspec, reject_entry, NULL);
 
 232         free_pathspec(&pathspec);
 
 236 static void parse_pathspec_arg(const char **pathspec,
 
 237                 struct archiver_args *ar_args)
 
 239         ar_args->pathspec = pathspec = get_pathspec("", pathspec);
 
 242                         if (!path_exists(ar_args->tree, *pathspec))
 
 243                                 die("path not found: %s", *pathspec);
 
 249 static void parse_treeish_arg(const char **argv,
 
 250                 struct archiver_args *ar_args, const char *prefix)
 
 252         const char *name = argv[0];
 
 253         const unsigned char *commit_sha1;
 
 256         const struct commit *commit;
 
 257         unsigned char sha1[20];
 
 259         if (get_sha1(name, sha1))
 
 260                 die("Not a valid object name");
 
 262         commit = lookup_commit_reference_gently(sha1, 1);
 
 264                 commit_sha1 = commit->object.sha1;
 
 265                 archive_time = commit->date;
 
 268                 archive_time = time(NULL);
 
 271         tree = parse_tree_indirect(sha1);
 
 273                 die("not a tree object");
 
 276                 unsigned char tree_sha1[20];
 
 280                 err = get_tree_entry(tree->object.sha1, prefix,
 
 282                 if (err || !S_ISDIR(mode))
 
 283                         die("current working directory is untracked");
 
 285                 tree = parse_tree_indirect(tree_sha1);
 
 287         ar_args->tree = tree;
 
 288         ar_args->commit_sha1 = commit_sha1;
 
 289         ar_args->commit = commit;
 
 290         ar_args->time = archive_time;
 
 293 #define OPT__COMPR(s, v, h, p) \
 
 294         { OPTION_SET_INT, (s), NULL, (v), NULL, (h), \
 
 295           PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, (p) }
 
 296 #define OPT__COMPR_HIDDEN(s, v, p) \
 
 297         { OPTION_SET_INT, (s), NULL, (v), NULL, "", \
 
 298           PARSE_OPT_NOARG | PARSE_OPT_NONEG | PARSE_OPT_HIDDEN, NULL, (p) }
 
 300 static int parse_archive_args(int argc, const char **argv,
 
 301                 const struct archiver **ar, struct archiver_args *args,
 
 302                 const char *name_hint, int is_remote)
 
 304         const char *format = NULL;
 
 305         const char *base = NULL;
 
 306         const char *remote = NULL;
 
 307         const char *exec = NULL;
 
 308         const char *output = NULL;
 
 309         int compression_level = -1;
 
 313         int worktree_attributes = 0;
 
 314         struct option opts[] = {
 
 316                 OPT_STRING(0, "format", &format, "fmt", "archive format"),
 
 317                 OPT_STRING(0, "prefix", &base, "prefix",
 
 318                         "prepend prefix to each pathname in the archive"),
 
 319                 OPT_STRING('o', "output", &output, "file",
 
 320                         "write the archive to this file"),
 
 321                 OPT_BOOLEAN(0, "worktree-attributes", &worktree_attributes,
 
 322                         "read .gitattributes in working directory"),
 
 323                 OPT__VERBOSE(&verbose, "report archived files on stderr"),
 
 324                 OPT__COMPR('0', &compression_level, "store only", 0),
 
 325                 OPT__COMPR('1', &compression_level, "compress faster", 1),
 
 326                 OPT__COMPR_HIDDEN('2', &compression_level, 2),
 
 327                 OPT__COMPR_HIDDEN('3', &compression_level, 3),
 
 328                 OPT__COMPR_HIDDEN('4', &compression_level, 4),
 
 329                 OPT__COMPR_HIDDEN('5', &compression_level, 5),
 
 330                 OPT__COMPR_HIDDEN('6', &compression_level, 6),
 
 331                 OPT__COMPR_HIDDEN('7', &compression_level, 7),
 
 332                 OPT__COMPR_HIDDEN('8', &compression_level, 8),
 
 333                 OPT__COMPR('9', &compression_level, "compress better", 9),
 
 335                 OPT_BOOLEAN('l', "list", &list,
 
 336                         "list supported archive formats"),
 
 338                 OPT_STRING(0, "remote", &remote, "repo",
 
 339                         "retrieve the archive from remote repository <repo>"),
 
 340                 OPT_STRING(0, "exec", &exec, "cmd",
 
 341                         "path to the remote git-upload-archive command"),
 
 345         argc = parse_options(argc, argv, NULL, opts, archive_usage, 0);
 
 348                 die("Unexpected option --remote");
 
 350                 die("Option --exec can only be used together with --remote");
 
 352                 die("Unexpected option --output");
 
 358                 for (i = 0; i < nr_archivers; i++)
 
 359                         if (!is_remote || archivers[i]->flags & ARCHIVER_REMOTE)
 
 360                                 printf("%s\n", archivers[i]->name);
 
 364         if (!format && name_hint)
 
 365                 format = archive_format_from_filename(name_hint);
 
 369         /* We need at least one parameter -- tree-ish */
 
 371                 usage_with_options(archive_usage, opts);
 
 372         *ar = lookup_archiver(format);
 
 373         if (!*ar || (is_remote && !((*ar)->flags & ARCHIVER_REMOTE)))
 
 374                 die("Unknown archive format '%s'", format);
 
 376         args->compression_level = Z_DEFAULT_COMPRESSION;
 
 377         if (compression_level != -1) {
 
 378                 if ((*ar)->flags & ARCHIVER_WANT_COMPRESSION_LEVELS)
 
 379                         args->compression_level = compression_level;
 
 381                         die("Argument not supported for format '%s': -%d",
 
 382                                         format, compression_level);
 
 385         args->verbose = verbose;
 
 387         args->baselen = strlen(base);
 
 388         args->worktree_attributes = worktree_attributes;
 
 393 int write_archive(int argc, const char **argv, const char *prefix,
 
 394                   int setup_prefix, const char *name_hint, int remote)
 
 397         const struct archiver *ar = NULL;
 
 398         struct archiver_args args;
 
 400         if (setup_prefix && prefix == NULL)
 
 401                 prefix = setup_git_directory_gently(&nongit);
 
 403         git_config(git_default_config, NULL);
 
 407         argc = parse_archive_args(argc, argv, &ar, &args, name_hint, remote);
 
 410                  * We know this will die() with an error, so we could just
 
 411                  * die ourselves; but its error message will be more specific
 
 412                  * than what we could write here.
 
 414                 setup_git_directory();
 
 417         parse_treeish_arg(argv, &args, prefix);
 
 418         parse_pathspec_arg(argv + 1, &args);
 
 420         return ar->write_archive(ar, &args);
 
 423 static int match_extension(const char *filename, const char *ext)
 
 425         int prefixlen = strlen(filename) - strlen(ext);
 
 428          * We need 1 character for the '.', and 1 character to ensure that the
 
 429          * prefix is non-empty (k.e., we don't match .tar.gz with no actual
 
 432         if (prefixlen < 2 || filename[prefixlen-1] != '.')
 
 434         return !strcmp(filename + prefixlen, ext);
 
 437 const char *archive_format_from_filename(const char *filename)
 
 441         for (i = 0; i < nr_archivers; i++)
 
 442                 if (match_extension(filename, archivers[i]->name))
 
 443                         return archivers[i]->name;