Skip to content

Commit 296743a

Browse files
rscharfegitster
authored andcommitted
archive: load index before pathspec checks
git archive checks whether pathspec arguments match anything to avoid surprises due to typos and later loads the index to get attributes. This order was OK when these features were introduced by ba053ea (archive: do not read .gitattributes in working directory, 2009-04-18) and d5f53d6 (archive: complain about path specs that don't match anything, 2009-12-12). But when attribute matching was added to pathspec in b0db704 (pathspec: allow querying for attributes, 2017-03-13), the pathspec checker in git archive did not support it fully, because it lacks the attributes from the index. Load the index earlier, before the pathspec check, to support attr pathspecs. Reported-by: Ronan Pigott <[email protected]> Signed-off-by: René Scharfe <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 39bf06a commit 296743a

File tree

2 files changed

+32
-19
lines changed

2 files changed

+32
-19
lines changed

archive.c

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -304,8 +304,6 @@ int write_archive_entries(struct archiver_args *args,
304304
write_archive_entry_fn_t write_entry)
305305
{
306306
struct archiver_context context;
307-
struct unpack_trees_options opts;
308-
struct tree_desc t;
309307
int err;
310308
struct strbuf path_in_archive = STRBUF_INIT;
311309
struct strbuf content = STRBUF_INIT;
@@ -331,23 +329,6 @@ int write_archive_entries(struct archiver_args *args,
331329
context.args = args;
332330
context.write_entry = write_entry;
333331

334-
/*
335-
* Setup index and instruct attr to read index only
336-
*/
337-
if (!args->worktree_attributes) {
338-
memset(&opts, 0, sizeof(opts));
339-
opts.index_only = 1;
340-
opts.head_idx = -1;
341-
opts.src_index = args->repo->index;
342-
opts.dst_index = args->repo->index;
343-
opts.fn = oneway_merge;
344-
init_tree_desc(&t, &args->tree->object.oid,
345-
args->tree->buffer, args->tree->size);
346-
if (unpack_trees(1, &t, &opts))
347-
return -1;
348-
git_attr_set_direction(GIT_ATTR_INDEX);
349-
}
350-
351332
err = read_tree(args->repo, args->tree,
352333
&args->pathspec,
353334
queue_or_write_archive_entry,
@@ -540,6 +521,26 @@ static void parse_treeish_arg(const char **argv,
540521
if (!tree)
541522
die(_("not a tree object: %s"), oid_to_hex(&oid));
542523

524+
/*
525+
* Setup index and instruct attr to read index only
526+
*/
527+
if (!ar_args->worktree_attributes) {
528+
struct unpack_trees_options opts;
529+
struct tree_desc t;
530+
531+
memset(&opts, 0, sizeof(opts));
532+
opts.index_only = 1;
533+
opts.head_idx = -1;
534+
opts.src_index = ar_args->repo->index;
535+
opts.dst_index = ar_args->repo->index;
536+
opts.fn = oneway_merge;
537+
init_tree_desc(&t, &tree->object.oid, tree->buffer, tree->size);
538+
if (unpack_trees(1, &t, &opts))
539+
die(_("unable to checkout working tree"));
540+
541+
git_attr_set_direction(GIT_ATTR_INDEX);
542+
}
543+
543544
ar_args->refname = ref;
544545
ar_args->tree = tree;
545546
ar_args->commit_oid = commit_oid;

t/t5000-tar-tree.sh

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,8 @@ test_expect_success 'end-of-options is correctly eaten' '
136136

137137
test_expect_success 'populate workdir' '
138138
mkdir a &&
139+
echo "a files_named_a" >.gitattributes &&
140+
git add .gitattributes &&
139141
echo simple textfile >a/a &&
140142
ten=0123456789 &&
141143
hundred="$ten$ten$ten$ten$ten$ten$ten$ten$ten$ten" &&
@@ -449,6 +451,16 @@ test_expect_success 'allow pathspecs that resolve to the current directory' '
449451
test_cmp expect actual
450452
'
451453

454+
test_expect_success 'attr pathspec in bare repo' '
455+
test_expect_code 0 git --git-dir=bare.git archive -v HEAD \
456+
":(attr:files_named_a)" >/dev/null 2>actual &&
457+
cat >expect <<-\EOF &&
458+
a/
459+
a/a
460+
EOF
461+
test_cmp expect actual
462+
'
463+
452464
# Pull the size and date of each entry in a tarfile using the system tar.
453465
#
454466
# We'll pull out only the year from the date; that avoids any question of

0 commit comments

Comments
 (0)