git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH 4/5] archive: do not read .gitattributes in working directory

From
Nguyen Thai Ngoc Duy <pclouds@gmail.com>
Date
Apr 16, 2009, 10:50 UTC
Message-ID
<fcaeb9bf0904160350m14dce828oe88bda6562d98f48@mail.gmail.com>
In-Reply-To
<1239848917-14399-5-git-send-email-gitster@pobox.com>
Sorry I got distracted by Vista+x11 stuff and had not work on this.
2009/4/16 Junio C Hamano <gitster@pobox.com>:
Show 23 quoted lines
> @@ -168,6 +171,22 @@ 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 = &the_index;
> +               opts.dst_index = &the_index;
> +               opts.fn = oneway_merge;
> +               init_tree_desc(&t, args->tree->buffer, args->tree->size);
> +               if (unpack_trees(1, &t, &opts))
> +                       return -1;
> +               git_attr_set_direction(GIT_ATTR_INDEX, &the_index);
> +       }
> +
>        err =  read_tree_recursive(args->tree, args->base, args->baselen, 0,
>                        args->pathspec, write_archive_entry, &context);
>        if (err == READ_TREE_RECURSIVE)

Squash the attached patch on top of this patch (I have yet to install mutt), we may avoid a few possible lstat()s during unpack_trees(), also less memory allocation.

I was thinking about loading .gitattributes inside write_archive_entry too, to avoid calling read_tree_recursive twice, but it requires .gitattributes to be traversed first. Won't work if there are files .abc, .def...

If read_tree_recusive() expose its tree to read_tree_fn_t, we can then look ahead and load .gitattributes, but that requires changing read_tree_fn_t interface. I'll see if it's feasible to make a customized read_tree_recusive() just for archive.c

Oh and a feature request (not really because I don't use it myself): support submodules in "git archive", anyone?

Show 8 quoted lines
> @@ -36,6 +36,14 @@ int cmd_tar_tree(int argc, const char **argv, const char *prefix)
>                argv++;
>                argc--;
>        }
> +       if (2 <= argc && !strcmp(argv[1], "--fix-attributes")) {
> +               argv++;
> +               argc--;
> +       }

Does this part needed? Gotta fix tar_tree_usage and git-tar-tree.txt too. I'd vote remove it.

-- 
Duy


diff --git a/archive.c b/archive.c
index 0ce628b..f79d005 100644
--- a/archive.c
+++ b/archive.c
@@ -147,12 +147,34 @@ static int write_archive_entry(const unsigned char *sha1, const char *base,
 	return err;
 }
 
+static int read_gitattr_to_index(const unsigned char *sha1, const char *base, int baselen, const char *pathname, unsigned mode, int stage, void *context)
+{
+	struct cache_entry *ce;
+	unsigned int size;
+	int len;
+	static int gitattr_len = 0;
+
+	if (S_ISDIR(mode))
+		return READ_TREE_RECURSIVE;
+
+	len = strlen(pathname);
+	if (!gitattr_len)
+		gitattr_len = strlen(GITATTRIBUTES_FILE);
+	if (len < gitattr_len || strcmp(pathname+len-gitattr_len, GITATTRIBUTES_FILE))
+		return 0;
+	size = cache_entry_size(len);
+	ce = xcalloc(1, size);
+	ce->ce_mode = create_ce_mode(mode);
+	ce->ce_flags = create_ce_flags(len, stage);
+	memcpy(ce->name, pathname, len+1);
+	hashcpy(ce->sha1, sha1);
+	return add_cache_entry(ce, ADD_CACHE_OK_TO_ADD | ADD_CACHE_SKIP_DFCHECK);
+}
+
 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;
 
 	if (args->baselen > 0 && args->base[args->baselen - 1] == '/') {
@@ -170,20 +192,8 @@ 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 = &the_index;
-		opts.dst_index = &the_index;
-		opts.fn = oneway_merge;
-		init_tree_desc(&t, args->tree->buffer, args->tree->size);
-		if (unpack_trees(1, &t, &opts))
-			return -1;
+		read_tree_recursive(args->tree, NULL, 0, 0, NULL, read_gitattr_to_index, NULL);
 		git_attr_set_direction(GIT_ATTR_INDEX, &the_index);
 	}
 
Previous: Jakub NarebskiNext: Nguyen Thai Ngoc Duy
Message 11 of 19 in “archive attribute series”
  1. 0/5 archive attribute seriesJunio C Hamano, Apr 16, 2009
  2. 1/5 archive tests: do not use .gitattributes in working directoryJunio C Hamano, Apr 16, 2009
  3. 2/5 attr: add GIT_ATTR_INDEX "direction"Junio C Hamano, Apr 16, 2009
  4. 3/5 unpack-trees: do not muck with attributes when we are not checking outJunio C Hamano, Apr 16, 2009
  5. 4/5 archive: do not read .gitattributes in working directoryJunio C Hamano, Apr 16, 2009
  6. 5/5 archive test: test new --fix-attributes featureJunio C Hamano, Apr 16, 2009
  7. René ScharfeApr 17, 2009
  8. Junio C HamanoApr 16, 2009
  9. Jeff KingApr 16, 2009
  10. Jakub NarebskiApr 16, 2009
  11. Nguyen Thai Ngoc DuyApr 16, 2009
  12. Nguyen Thai Ngoc DuyApr 16, 2009
  13. René ScharfeApr 17, 2009
  14. René ScharfeApr 17, 2009
  15. 1/5 archive tests: do not use .gitattributes in working directoryRené Scharfe, Apr 17, 2009
  16. 2/5 attr: add GIT_ATTR_INDEX "direction"René Scharfe, Apr 17, 2009
  17. 3/5 unpack-trees: do not muck with attributes when we are not checking outRené Scharfe, Apr 17, 2009
  18. 4/5 archive: do not read .gitattributes in working directoryRené Scharfe, Apr 17, 2009
  19. 5/5 archive test: attributesRené Scharfe, Apr 17, 2009

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.