public inbox for git@vger.kernel.org
 help / color / mirror / Atom feed
* Archive from bare repo?
@ 2024-09-20 17:48 Ronan Pigott
  2024-09-20 17:53 ` Ronan Pigott
  2024-09-21 20:23 ` [PATCH] archive: load index before pathspec checks René Scharfe
  0 siblings, 2 replies; 4+ messages in thread
From: Ronan Pigott @ 2024-09-20 17:48 UTC (permalink / raw)
  To: git

Hi git,

I'm trying and failing to create a specific archive from a bare repo. The
following all works correctly:

  $ git clone https://my.git.repo/test --bare test
  $ git --git-dir=test archive @ | tar -tf - # archive of full repo
  $ git --git-dir=test cat-file -p @:.gitattributes # shows subset of files with myattr set
  $ git --work-tree=/var/empty --git-dir=test reset --mixed
  $ git --work-tree=/var/empty --git-dir=test ls-files ':(attr:myattr)' # list of files with myattr set

Now I get:

  $ git --git-dir=test archive @ ':(attr:login)'
  fatal: pathspec ':(attr:login)' did not match any files

The manpage indicates that git-archive should use the .gitattributes from the
archived tree, and as indicated above it has the expected content. Why doesn't
this produce an archive with the files listed by ls-files from above? Is there
a way to achive the archive I want?

Thanks,
Ronan

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Archive from bare repo?
  2024-09-20 17:48 Archive from bare repo? Ronan Pigott
@ 2024-09-20 17:53 ` Ronan Pigott
  2024-09-21 20:23 ` [PATCH] archive: load index before pathspec checks René Scharfe
  1 sibling, 0 replies; 4+ messages in thread
From: Ronan Pigott @ 2024-09-20 17:53 UTC (permalink / raw)
  To: git

September 20, 2024 at 10:48 AM, "Ronan Pigott" <ronan@rjp.ie> wrote:

>  $ git --work-tree=/var/empty --git-dir=test ls-files ':(attr:myattr)' # list of files with myattr set
 
>  $ git --git-dir=test archive @ ':(attr:login)'
> 
>  fatal: pathspec ':(attr:login)' did not match any files

Sorry for the typo, both cases are using the same pathspec
':(attr:login)' but the issue as described remains.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH] archive: load index before pathspec checks
  2024-09-20 17:48 Archive from bare repo? Ronan Pigott
  2024-09-20 17:53 ` Ronan Pigott
@ 2024-09-21 20:23 ` René Scharfe
       [not found]   ` <f8e0ad836366480e32ec5b40b753cb533dd41cb6@rjp.ie>
  1 sibling, 1 reply; 4+ messages in thread
From: René Scharfe @ 2024-09-21 20:23 UTC (permalink / raw)
  To: Ronan Pigott, git

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 ba053ea96c
(archive: do not read .gitattributes in working directory, 2009-04-18)
and d5f53d6d6f (archive: complain about path specs that don't match
anything, 2009-12-12).

But when attribute matching was added to pathspec in b0db704652
(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 <ronan@rjp.ie>
Signed-off-by: René Scharfe <l.s.r@web.de>
---
 archive.c           | 39 ++++++++++++++++++++-------------------
 t/t5000-tar-tree.sh | 12 ++++++++++++
 2 files changed, 32 insertions(+), 19 deletions(-)

diff --git a/archive.c b/archive.c
index 9ba96aae4f..58f86bf75c 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,26 @@ 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(_("unable to checkout working tree"));
+
+		git_attr_set_direction(GIT_ATTR_INDEX);
+	}
+
 	ar_args->refname = ref;
 	ar_args->tree = tree;
 	ar_args->commit_oid = commit_oid;
diff --git a/t/t5000-tar-tree.sh b/t/t5000-tar-tree.sh
index 7abba8a4b2..b9fda973f7 100755
--- a/t/t5000-tar-tree.sh
+++ b/t/t5000-tar-tree.sh
@@ -137,6 +137,8 @@ test_expect_success 'end-of-options is correctly eaten' '

 test_expect_success 'populate workdir' '
 	mkdir a &&
+	echo "a files_named_a" >.gitattributes &&
+	git add .gitattributes &&
 	echo simple textfile >a/a &&
 	ten=0123456789 &&
 	hundred="$ten$ten$ten$ten$ten$ten$ten$ten$ten$ten" &&
@@ -450,6 +452,16 @@ test_expect_success 'allow pathspecs that resolve to the current directory' '
 	test_cmp expect actual
 '

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

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] archive: load index before pathspec checks
       [not found]   ` <f8e0ad836366480e32ec5b40b753cb533dd41cb6@rjp.ie>
@ 2024-09-21 22:02     ` René Scharfe
  0 siblings, 0 replies; 4+ messages in thread
From: René Scharfe @ 2024-09-21 22:02 UTC (permalink / raw)
  To: Ronan Pigott; +Cc: git

Hello Ronan,

Am 21.09.24 um 23:23 schrieb Ronan Pigott:
> Thanks for the patch. I tried it applied to 2.46.1 and it works as expected.

thank you for testing, and for the original report!

René


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2024-09-21 22:02 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-09-20 17:48 Archive from bare repo? Ronan Pigott
2024-09-20 17:53 ` Ronan Pigott
2024-09-21 20:23 ` [PATCH] archive: load index before pathspec checks René Scharfe
     [not found]   ` <f8e0ad836366480e32ec5b40b753cb533dd41cb6@rjp.ie>
2024-09-21 22:02     ` René Scharfe

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox