Skip to content

Commit b612ee2

Browse files
pcloudsgitster
authored andcommitted
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>
1 parent a4009b0 commit b612ee2

File tree

4 files changed

+45
-21
lines changed

4 files changed

+45
-21
lines changed

archive.c

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ void *object_file_to_archive(const struct archiver_args *args,
7979
size_t size = 0;
8080

8181
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);
8383
if (commit)
8484
format_subst(commit, buf.buf, buf.len, &buf);
8585
buffer = strbuf_detach(&buf, &size);
@@ -104,12 +104,13 @@ struct archiver_context {
104104
struct directory *bottom;
105105
};
106106

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)
108109
{
109110
static struct attr_check *check;
110111
if (!check)
111112
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;
113114
}
114115

115116
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,
145146

146147
if (!S_ISDIR(mode)) {
147148
const struct attr_check *check;
148-
check = get_archive_attrs(path_without_prefix);
149+
check = get_archive_attrs(args->repo->index, path_without_prefix);
149150
if (check_attr_export_ignore(check))
150151
return 0;
151152
args->convert = check_attr_export_subst(check);
@@ -220,7 +221,7 @@ static int queue_or_write_archive_entry(const struct object_id *oid,
220221
/* Borrow base, but restore its original value when done. */
221222
strbuf_addstr(base, filename);
222223
strbuf_addch(base, '/');
223-
check = get_archive_attrs(base->buf);
224+
check = get_archive_attrs(c->args->repo->index, base->buf);
224225
strbuf_setlen(base, baselen);
225226

226227
if (check_attr_export_ignore(check))
@@ -268,8 +269,8 @@ int write_archive_entries(struct archiver_args *args,
268269
memset(&opts, 0, sizeof(opts));
269270
opts.index_only = 1;
270271
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;
273274
opts.fn = oneway_merge;
274275
init_tree_desc(&t, args->tree->buffer, args->tree->size);
275276
if (unpack_trees(1, &t, &opts))
@@ -304,33 +305,43 @@ static const struct archiver *lookup_archiver(const char *name)
304305
return NULL;
305306
}
306307

308+
struct path_exists_context {
309+
struct pathspec pathspec;
310+
struct archiver_args *args;
311+
};
312+
307313
static int reject_entry(const struct object_id *oid, struct strbuf *base,
308314
const char *filename, unsigned mode,
309315
int stage, void *context)
310316
{
311317
int ret = -1;
318+
struct path_exists_context *ctx = context;
319+
312320
if (S_ISDIR(mode)) {
313321
struct strbuf sb = STRBUF_INIT;
314322
strbuf_addbuf(&sb, base);
315323
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))
317327
ret = READ_TREE_RECURSIVE;
318328
strbuf_release(&sb);
319329
}
320330
return ret;
321331
}
322332

323-
static int path_exists(struct tree *tree, const char *path)
333+
static int path_exists(struct archiver_args *args, const char *path)
324334
{
325335
const char *paths[] = { path, NULL };
326-
struct pathspec pathspec;
336+
struct path_exists_context ctx;
327337
int ret;
328338

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);
334345
return ret != 0;
335346
}
336347

@@ -348,7 +359,7 @@ static void parse_pathspec_arg(const char **pathspec,
348359
ar_args->pathspec.recursive = 1;
349360
if (pathspec) {
350361
while (*pathspec) {
351-
if (**pathspec && !path_exists(ar_args->tree, *pathspec))
362+
if (**pathspec && !path_exists(ar_args, *pathspec))
352363
die(_("pathspec '%s' did not match any files"), *pathspec);
353364
pathspec++;
354365
}
@@ -510,6 +521,7 @@ static int parse_archive_args(int argc, const char **argv,
510521
}
511522

512523
int write_archive(int argc, const char **argv, const char *prefix,
524+
struct repository *repo,
513525
const char *name_hint, int remote)
514526
{
515527
const struct archiver *ar = NULL;
@@ -521,6 +533,7 @@ int write_archive(int argc, const char **argv, const char *prefix,
521533
init_tar_archiver();
522534
init_zip_archiver();
523535

536+
args.repo = repo;
524537
argc = parse_archive_args(argc, argv, &ar, &args, name_hint, remote);
525538
if (!startup_info->have_repository) {
526539
/*

archive.h

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@
33

44
#include "pathspec.h"
55

6+
struct repository;
7+
68
struct archiver_args {
9+
struct repository *repo;
710
const char *base;
811
size_t baselen;
912
struct tree *tree;
@@ -17,6 +20,16 @@ struct archiver_args {
1720
int compression_level;
1821
};
1922

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+
2033
#define ARCHIVER_WANT_COMPRESSION_LEVELS 1
2134
#define ARCHIVER_REMOTE 2
2235
struct archiver {
@@ -36,9 +49,6 @@ typedef int (*write_archive_entry_fn_t)(struct archiver_args *args,
3649
unsigned int mode);
3750

3851
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);
4252
extern void *object_file_to_archive(const struct archiver_args *args,
4353
const char *path, const struct object_id *oid,
4454
unsigned int mode, enum object_type *type,

builtin/archive.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,5 +105,5 @@ int cmd_archive(int argc, const char **argv, const char *prefix)
105105

106106
setvbuf(stderr, NULL, _IOLBF, BUFSIZ);
107107

108-
return write_archive(argc, argv, prefix, output, 0);
108+
return write_archive(argc, argv, prefix, the_repository, output, 0);
109109
}

builtin/upload-archive.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ int cmd_upload_archive_writer(int argc, const char **argv, const char *prefix)
4343
}
4444

4545
/* 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);
4748
}
4849

4950
__attribute__((format (printf, 1, 2)))

0 commit comments

Comments
 (0)