aboutsummaryrefslogtreecommitdiffstats
path: root/archive.c
diff options
context:
space:
mode:
Diffstat (limited to 'archive.c')
-rw-r--r--archive.c50
1 files changed, 31 insertions, 19 deletions
diff --git a/archive.c b/archive.c
index 7bd60d0632..a7a92ff839 100644
--- a/archive.c
+++ b/archive.c
@@ -304,8 +304,6 @@ int write_archive_entries(struct archiver_args *args,
write_archive_entry_fn_t write_entry)
{
struct archiver_context context;
- struct unpack_trees_options opts;
- struct tree_desc t;
int err;
struct strbuf path_in_archive = STRBUF_INIT;
struct strbuf content = STRBUF_INIT;
@@ -331,23 +329,6 @@ int write_archive_entries(struct archiver_args *args,
context.args = args;
context.write_entry = write_entry;
- /*
- * Setup index and instruct attr to read index only
- */
- if (!args->worktree_attributes) {
- memset(&opts, 0, sizeof(opts));
- opts.index_only = 1;
- opts.head_idx = -1;
- opts.src_index = args->repo->index;
- opts.dst_index = args->repo->index;
- opts.fn = oneway_merge;
- init_tree_desc(&t, &args->tree->object.oid,
- args->tree->buffer, args->tree->size);
- if (unpack_trees(1, &t, &opts))
- return -1;
- git_attr_set_direction(GIT_ATTR_INDEX);
- }
-
err = read_tree(args->repo, args->tree,
&args->pathspec,
queue_or_write_archive_entry,
@@ -540,6 +521,27 @@ static void parse_treeish_arg(const char **argv,
if (!tree)
die(_("not a tree object: %s"), oid_to_hex(&oid));
+ /*
+ * Setup index and instruct attr to read index only
+ */
+ if (!ar_args->worktree_attributes) {
+ struct unpack_trees_options opts;
+ struct tree_desc t;
+
+ memset(&opts, 0, sizeof(opts));
+ opts.index_only = 1;
+ opts.head_idx = -1;
+ opts.src_index = ar_args->repo->index;
+ opts.dst_index = ar_args->repo->index;
+ opts.fn = oneway_merge;
+ init_tree_desc(&t, &tree->object.oid, tree->buffer, tree->size);
+ if (unpack_trees(1, &t, &opts))
+ die(_("failed to unpack tree object %s"),
+ oid_to_hex(&tree->object.oid));
+
+ git_attr_set_direction(GIT_ATTR_INDEX);
+ }
+
ar_args->refname = ref;
ar_args->tree = tree;
ar_args->commit_oid = commit_oid;
@@ -736,6 +738,7 @@ int write_archive(int argc, const char **argv, const char *prefix,
struct pretty_print_describe_status describe_status = {0};
struct pretty_print_context ctx = {0};
struct archiver_args args;
+ const char **argv_copy;
int rc;
git_config_get_bool("uploadarchive.allowunreachable", &remote_allow_unreachable);
@@ -749,6 +752,14 @@ int write_archive(int argc, const char **argv, const char *prefix,
args.repo = repo;
args.prefix = prefix;
string_list_init_dup(&args.extra_files);
+
+ /*
+ * `parse_archive_args()` modifies contents of `argv`, which is what we
+ * want. Our callers may not want it though, so we create a copy here.
+ */
+ DUP_ARRAY(argv_copy, argv, argc);
+ argv = argv_copy;
+
argc = parse_archive_args(argc, argv, &ar, &args, name_hint, remote);
if (!startup_info->have_repository) {
/*
@@ -767,6 +778,7 @@ int write_archive(int argc, const char **argv, const char *prefix,
string_list_clear_func(&args.extra_files, extra_file_info_clear);
free(args.refname);
clear_pathspec(&args.pathspec);
+ free(argv_copy);
return rc;
}