mirror of
https://github.com/git/git
synced 2024-08-24 18:26:02 +00:00
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>
This commit is contained in:
parent
a4009b0b45
commit
b612ee202a
45
archive.c
45
archive.c
|
@ -79,7 +79,7 @@ void *object_file_to_archive(const struct archiver_args *args,
|
|||
size_t size = 0;
|
||||
|
||||
strbuf_attach(&buf, buffer, *sizep, *sizep + 1);
|
||||
convert_to_working_tree(&the_index, path, buf.buf, buf.len, &buf);
|
||||
convert_to_working_tree(args->repo->index, path, buf.buf, buf.len, &buf);
|
||||
if (commit)
|
||||
format_subst(commit, buf.buf, buf.len, &buf);
|
||||
buffer = strbuf_detach(&buf, &size);
|
||||
|
@ -104,12 +104,13 @@ struct archiver_context {
|
|||
struct directory *bottom;
|
||||
};
|
||||
|
||||
static const struct attr_check *get_archive_attrs(const char *path)
|
||||
static const struct attr_check *get_archive_attrs(struct index_state *istate,
|
||||
const char *path)
|
||||
{
|
||||
static struct attr_check *check;
|
||||
if (!check)
|
||||
check = attr_check_initl("export-ignore", "export-subst", NULL);
|
||||
return git_check_attr(&the_index, path, check) ? NULL : check;
|
||||
return git_check_attr(istate, path, check) ? NULL : check;
|
||||
}
|
||||
|
||||
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,
|
|||
|
||||
if (!S_ISDIR(mode)) {
|
||||
const struct attr_check *check;
|
||||
check = get_archive_attrs(path_without_prefix);
|
||||
check = get_archive_attrs(args->repo->index, path_without_prefix);
|
||||
if (check_attr_export_ignore(check))
|
||||
return 0;
|
||||
args->convert = check_attr_export_subst(check);
|
||||
|
@ -220,7 +221,7 @@ static int queue_or_write_archive_entry(const struct object_id *oid,
|
|||
/* Borrow base, but restore its original value when done. */
|
||||
strbuf_addstr(base, filename);
|
||||
strbuf_addch(base, '/');
|
||||
check = get_archive_attrs(base->buf);
|
||||
check = get_archive_attrs(c->args->repo->index, base->buf);
|
||||
strbuf_setlen(base, baselen);
|
||||
|
||||
if (check_attr_export_ignore(check))
|
||||
|
@ -268,8 +269,8 @@ int write_archive_entries(struct archiver_args *args,
|
|||
memset(&opts, 0, sizeof(opts));
|
||||
opts.index_only = 1;
|
||||
opts.head_idx = -1;
|
||||
opts.src_index = &the_index;
|
||||
opts.dst_index = &the_index;
|
||||
opts.src_index = args->repo->index;
|
||||
opts.dst_index = args->repo->index;
|
||||
opts.fn = oneway_merge;
|
||||
init_tree_desc(&t, args->tree->buffer, args->tree->size);
|
||||
if (unpack_trees(1, &t, &opts))
|
||||
|
@ -304,33 +305,43 @@ static const struct archiver *lookup_archiver(const char *name)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
struct path_exists_context {
|
||||
struct pathspec pathspec;
|
||||
struct archiver_args *args;
|
||||
};
|
||||
|
||||
static int reject_entry(const struct object_id *oid, struct strbuf *base,
|
||||
const char *filename, unsigned mode,
|
||||
int stage, void *context)
|
||||
{
|
||||
int ret = -1;
|
||||
struct path_exists_context *ctx = context;
|
||||
|
||||
if (S_ISDIR(mode)) {
|
||||
struct strbuf sb = STRBUF_INIT;
|
||||
strbuf_addbuf(&sb, base);
|
||||
strbuf_addstr(&sb, filename);
|
||||
if (!match_pathspec(&the_index, context, sb.buf, sb.len, 0, NULL, 1))
|
||||
if (!match_pathspec(ctx->args->repo->index,
|
||||
&ctx->pathspec,
|
||||
sb.buf, sb.len, 0, NULL, 1))
|
||||
ret = READ_TREE_RECURSIVE;
|
||||
strbuf_release(&sb);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int path_exists(struct tree *tree, const char *path)
|
||||
static int path_exists(struct archiver_args *args, const char *path)
|
||||
{
|
||||
const char *paths[] = { path, NULL };
|
||||
struct pathspec pathspec;
|
||||
struct path_exists_context ctx;
|
||||
int ret;
|
||||
|
||||
parse_pathspec(&pathspec, 0, 0, "", paths);
|
||||
pathspec.recursive = 1;
|
||||
ret = read_tree_recursive(tree, "", 0, 0, &pathspec,
|
||||
reject_entry, &pathspec);
|
||||
clear_pathspec(&pathspec);
|
||||
ctx.args = args;
|
||||
parse_pathspec(&ctx.pathspec, 0, 0, "", paths);
|
||||
ctx.pathspec.recursive = 1;
|
||||
ret = read_tree_recursive(args->tree, "", 0, 0, &ctx.pathspec,
|
||||
reject_entry, &ctx);
|
||||
clear_pathspec(&ctx.pathspec);
|
||||
return ret != 0;
|
||||
}
|
||||
|
||||
|
@ -348,7 +359,7 @@ static void parse_pathspec_arg(const char **pathspec,
|
|||
ar_args->pathspec.recursive = 1;
|
||||
if (pathspec) {
|
||||
while (*pathspec) {
|
||||
if (**pathspec && !path_exists(ar_args->tree, *pathspec))
|
||||
if (**pathspec && !path_exists(ar_args, *pathspec))
|
||||
die(_("pathspec '%s' did not match any files"), *pathspec);
|
||||
pathspec++;
|
||||
}
|
||||
|
@ -510,6 +521,7 @@ static int parse_archive_args(int argc, const char **argv,
|
|||
}
|
||||
|
||||
int write_archive(int argc, const char **argv, const char *prefix,
|
||||
struct repository *repo,
|
||||
const char *name_hint, int remote)
|
||||
{
|
||||
const struct archiver *ar = NULL;
|
||||
|
@ -521,6 +533,7 @@ int write_archive(int argc, const char **argv, const char *prefix,
|
|||
init_tar_archiver();
|
||||
init_zip_archiver();
|
||||
|
||||
args.repo = repo;
|
||||
argc = parse_archive_args(argc, argv, &ar, &args, name_hint, remote);
|
||||
if (!startup_info->have_repository) {
|
||||
/*
|
||||
|
|
16
archive.h
16
archive.h
|
@ -3,7 +3,10 @@
|
|||
|
||||
#include "pathspec.h"
|
||||
|
||||
struct repository;
|
||||
|
||||
struct archiver_args {
|
||||
struct repository *repo;
|
||||
const char *base;
|
||||
size_t baselen;
|
||||
struct tree *tree;
|
||||
|
@ -17,6 +20,16 @@ struct archiver_args {
|
|||
int compression_level;
|
||||
};
|
||||
|
||||
/* main api */
|
||||
|
||||
extern int write_archive(int argc, const char **argv, const char *prefix,
|
||||
struct repository *repo,
|
||||
const char *name_hint, int remote);
|
||||
|
||||
const char *archive_format_from_filename(const char *filename);
|
||||
|
||||
/* archive backend stuff */
|
||||
|
||||
#define ARCHIVER_WANT_COMPRESSION_LEVELS 1
|
||||
#define ARCHIVER_REMOTE 2
|
||||
struct archiver {
|
||||
|
@ -36,9 +49,6 @@ typedef int (*write_archive_entry_fn_t)(struct archiver_args *args,
|
|||
unsigned int mode);
|
||||
|
||||
extern int write_archive_entries(struct archiver_args *args, write_archive_entry_fn_t write_entry);
|
||||
extern int write_archive(int argc, const char **argv, const char *prefix, const char *name_hint, int remote);
|
||||
|
||||
const char *archive_format_from_filename(const char *filename);
|
||||
extern void *object_file_to_archive(const struct archiver_args *args,
|
||||
const char *path, const struct object_id *oid,
|
||||
unsigned int mode, enum object_type *type,
|
||||
|
|
|
@ -105,5 +105,5 @@ int cmd_archive(int argc, const char **argv, const char *prefix)
|
|||
|
||||
setvbuf(stderr, NULL, _IOLBF, BUFSIZ);
|
||||
|
||||
return write_archive(argc, argv, prefix, output, 0);
|
||||
return write_archive(argc, argv, prefix, the_repository, output, 0);
|
||||
}
|
||||
|
|
|
@ -43,7 +43,8 @@ int cmd_upload_archive_writer(int argc, const char **argv, const char *prefix)
|
|||
}
|
||||
|
||||
/* parse all options sent by the client */
|
||||
return write_archive(sent_argv.argc, sent_argv.argv, prefix, NULL, 1);
|
||||
return write_archive(sent_argv.argc, sent_argv.argv, prefix,
|
||||
the_repository, NULL, 1);
|
||||
}
|
||||
|
||||
__attribute__((format (printf, 1, 2)))
|
||||
|
|
Loading…
Reference in a new issue