archive.c: avoid access to the_index
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Nguyễn Thái Ngọc Duy committed
Aug 13, 2018 at 18:14 UTC
b612ee202a48f129f81f8f6a5af6cf71d1a9caef
4 files changed
+45
-21
archive.c
+29
-16
@@ -79,7 +79,7 @@ void *object_file_to_archive(const struct archiver_args *args,
79
size_t size = 0;
80
81
strbuf_attach(&buf, buffer, *sizep, *sizep + 1);
82
- convert_to_working_tree(&the_index, path, buf.buf, buf.len, &buf);
82
+ convert_to_working_tree(args->repo->index, path, buf.buf, buf.len, &buf);
83
if (commit)
84
format_subst(commit, buf.buf, buf.len, &buf);
85
buffer = strbuf_detach(&buf, &size);
@@ -104,12 +104,13 @@ struct archiver_context {
104
struct directory *bottom;
105
};
106
107
-static const struct attr_check *get_archive_attrs(const char *path)
107
+static const struct attr_check *get_archive_attrs(struct index_state *istate,
108
+ const char *path)
109
{
110
static struct attr_check *check;
111
if (!check)
112
check = attr_check_initl("export-ignore", "export-subst", NULL);
112
- return git_check_attr(&the_index, path, check) ? NULL : check;
113
+ return git_check_attr(istate, path, check) ? NULL : check;
114
}
115
116
static int check_attr_export_ignore(const struct attr_check *check)
@@ -145,7 +146,7 @@ static int write_archive_entry(const struct object_id *oid, const char *base,
146
147
if (!S_ISDIR(mode)) {
148
const struct attr_check *check;
148
- check = get_archive_attrs(path_without_prefix);
149
+ check = get_archive_attrs(args->repo->index, path_without_prefix);
150
if (check_attr_export_ignore(check))
151
return 0;
152
args->convert = check_attr_export_subst(check);
@@ -220,7 +221,7 @@ static int queue_or_write_archive_entry(const struct object_id *oid,
221
/* Borrow base, but restore its original value when done. */
222
strbuf_addstr(base, filename);
223
strbuf_addch(base, '/');
223
- check = get_archive_attrs(base->buf);
224
+ check = get_archive_attrs(c->args->repo->index, base->buf);
225
strbuf_setlen(base, baselen);
226
227
if (check_attr_export_ignore(check))
@@ -268,8 +269,8 @@ int write_archive_entries(struct archiver_args *args,
269
memset(&opts, 0, sizeof(opts));
270
opts.index_only = 1;
271
opts.head_idx = -1;
271
- opts.src_index = &the_index;
272
- opts.dst_index = &the_index;
272
+ opts.src_index = args->repo->index;
273
+ opts.dst_index = args->repo->index;
274
opts.fn = oneway_merge;
275
init_tree_desc(&t, args->tree->buffer, args->tree->size);
276
if (unpack_trees(1, &t, &opts))
@@ -304,33 +305,43 @@ static const struct archiver *lookup_archiver(const char *name)
305
return NULL;
306
}
307
308
+struct path_exists_context {
309
+ struct pathspec pathspec;
310
+ struct archiver_args *args;
311
+};
312
+
313
static int reject_entry(const struct object_id *oid, struct strbuf *base,
314
const char *filename, unsigned mode,
315
int stage, void *context)
316
{
317
int ret = -1;
318
+ struct path_exists_context *ctx = context;
319
+
320
if (S_ISDIR(mode)) {
321
struct strbuf sb = STRBUF_INIT;
322
strbuf_addbuf(&sb, base);
323
strbuf_addstr(&sb, filename);
316
- if (!match_pathspec(&the_index, context, sb.buf, sb.len, 0, NULL, 1))
324
+ if (!match_pathspec(ctx->args->repo->index,
325
+ &ctx->pathspec,
326
+ sb.buf, sb.len, 0, NULL, 1))
327
ret = READ_TREE_RECURSIVE;
328
strbuf_release(&sb);
329
}
330
return ret;
331
}
332
323
-static int path_exists(struct tree *tree, const char *path)
333
+static int path_exists(struct archiver_args *args, const char *path)
334
{
335
const char *paths[] = { path, NULL };
326
- struct pathspec pathspec;
336
+ struct path_exists_context ctx;
337
int ret;
338
329
- parse_pathspec(&pathspec, 0, 0, "", paths);
330
- pathspec.recursive = 1;
331
- ret = read_tree_recursive(tree, "", 0, 0, &pathspec,
332
- reject_entry, &pathspec);
333
- clear_pathspec(&pathspec);
339
+ ctx.args = args;
340
+ parse_pathspec(&ctx.pathspec, 0, 0, "", paths);
341
+ ctx.pathspec.recursive = 1;
342
+ ret = read_tree_recursive(args->tree, "", 0, 0, &ctx.pathspec,
343
+ reject_entry, &ctx);
344
+ clear_pathspec(&ctx.pathspec);
345
return ret != 0;
346
}
347
@@ -348,7 +359,7 @@ static void parse_pathspec_arg(const char **pathspec,
359
ar_args->pathspec.recursive = 1;
360
if (pathspec) {
361
while (*pathspec) {
351
- if (**pathspec && !path_exists(ar_args->tree, *pathspec))
362
+ if (**pathspec && !path_exists(ar_args, *pathspec))
363
die(_("pathspec '%s' did not match any files"), *pathspec);
364
pathspec++;
365
}
@@ -510,6 +521,7 @@ static int parse_archive_args(int argc, const char **argv,
521
}
522
523
int write_archive(int argc, const char **argv, const char *prefix,
524
+ struct repository *repo,
525
const char *name_hint, int remote)
526
{
527
const struct archiver *ar = NULL;
@@ -521,6 +533,7 @@ int write_archive(int argc, const char **argv, const char *prefix,
533
init_tar_archiver();
534
init_zip_archiver();
535
536
+ args.repo = repo;
537
argc = parse_archive_args(argc, argv, &ar, &args, name_hint, remote);
538
if (!startup_info->have_repository) {
539
/*
archive.h
+13
-3
@@ -3,7 +3,10 @@
3
4
#include "pathspec.h"
5
6
+struct repository;
7
+
8
struct archiver_args {
9
+ struct repository *repo;
10
const char *base;
11
size_t baselen;
12
struct tree *tree;
@@ -17,6 +20,16 @@ struct archiver_args {
20
int compression_level;
21
};
22
23
+/* main api */
24
+
25
+extern int write_archive(int argc, const char **argv, const char *prefix,
26
+ struct repository *repo,
27
+ const char *name_hint, int remote);
28
+
29
+const char *archive_format_from_filename(const char *filename);
30
+
31
+/* archive backend stuff */
32
+
33
#define ARCHIVER_WANT_COMPRESSION_LEVELS 1
34
#define ARCHIVER_REMOTE 2
35
struct archiver {
@@ -36,9 +49,6 @@ typedef int (*write_archive_entry_fn_t)(struct archiver_args *args,
49
unsigned int mode);
50
51
extern int write_archive_entries(struct archiver_args *args, write_archive_entry_fn_t write_entry);
39
-extern int write_archive(int argc, const char **argv, const char *prefix, const char *name_hint, int remote);
40
-
41
-const char *archive_format_from_filename(const char *filename);
52
extern void *object_file_to_archive(const struct archiver_args *args,
53
const char *path, const struct object_id *oid,
54
unsigned int mode, enum object_type *type,
builtin/archive.c
+1
-1
@@ -105,5 +105,5 @@ int cmd_archive(int argc, const char **argv, const char *prefix)
105
106
setvbuf(stderr, NULL, _IOLBF, BUFSIZ);
107
108
- return write_archive(argc, argv, prefix, output, 0);
108
+ return write_archive(argc, argv, prefix, the_repository, output, 0);
109
}
builtin/upload-archive.c
+2
-1
@@ -43,7 +43,8 @@ int cmd_upload_archive_writer(int argc, const char **argv, const char *prefix)
43
}
44
45
/* parse all options sent by the client */
46
- return write_archive(sent_argv.argc, sent_argv.argv, prefix, NULL, 1);
46
+ return write_archive(sent_argv.argc, sent_argv.argv, prefix,
47
+ the_repository, NULL, 1);
48
}
49
50
__attribute__((format (printf, 1, 2)))