All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/5] archive attribute series
@ 2009-04-16  2:28 Junio C Hamano
  2009-04-16  2:28 ` [PATCH 1/5] archive tests: do not use .gitattributes in working directory Junio C Hamano
                   ` (5 more replies)
  0 siblings, 6 replies; 19+ messages in thread
From: Junio C Hamano @ 2009-04-16  2:28 UTC (permalink / raw)
  To: git

Here is my attempt to consolidate the fix-ups on Duy's git-archive
enhancements.

I haven't decided if this should go to 1.6.3; it is a sensible change but
it *is* a change in behaviour that could be seen as incompatible.

Junio C Hamano (1):
  unpack-trees: do not muck with attributes when we are not checking
    out

Nguyễn Thái Ngọc Duy (2):
  attr: add GIT_ATTR_INDEX "direction"
  archive: do not read .gitattributes in working directory

René Scharfe (2):
  archive tests: do not use .gitattributes in working directory
  archive test: test new --fix-attributes feature

 Documentation/git-archive.txt |    5 ++-
 archive.c                     |   22 ++++++++++++++
 archive.h                     |    1 +
 attr.c                        |   12 ++++++--
 attr.h                        |    3 +-
 builtin-tar-tree.c            |    8 +++++
 t/t5000-tar-tree.sh           |    9 +++--
 t/t5001-archive-attr.sh       |   62 +++++++++++++++++++++++++++++++++++++++++
 unpack-trees.c                |    6 ++-
 9 files changed, 117 insertions(+), 11 deletions(-)
 create mode 100755 t/t5001-archive-attr.sh

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

* [PATCH 1/5] archive tests: do not use .gitattributes in working directory
  2009-04-16  2:28 [PATCH 0/5] archive attribute series Junio C Hamano
@ 2009-04-16  2:28 ` Junio C Hamano
  2009-04-16  2:28   ` [PATCH 2/5] attr: add GIT_ATTR_INDEX "direction" Junio C Hamano
  2009-04-17 19:51   ` [PATCH 1/5] archive tests: do not use .gitattributes in working directory René Scharfe
  2009-04-17 22:17 ` [PATCH v2 " René Scharfe
                   ` (4 subsequent siblings)
  5 siblings, 2 replies; 19+ messages in thread
From: Junio C Hamano @ 2009-04-16  2:28 UTC (permalink / raw)
  To: git; +Cc: René Scharfe

From: René Scharfe <rene.scharfe@lsrfire.ath.cx>

We are interested in using archive mostly from a bare repository, so it
should not add .gitattributes to the work tree.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 t/t5000-tar-tree.sh |    9 +++++----
 1 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/t/t5000-tar-tree.sh b/t/t5000-tar-tree.sh
index 7641e0d..abb41b0 100755
--- a/t/t5000-tar-tree.sh
+++ b/t/t5000-tar-tree.sh
@@ -50,7 +50,7 @@ test_expect_success \
 test_expect_success \
     'add ignored file' \
     'echo ignore me >a/ignored &&
-     echo ignored export-ignore >.gitattributes'
+     echo ignored export-ignore >.git/info/attributes'
 
 test_expect_success \
     'add files to repository' \
@@ -64,7 +64,7 @@ test_expect_success \
 test_expect_success \
     'create bare clone' \
     'git clone --bare . bare.git &&
-     cp .gitattributes bare.git/info/attributes'
+     cp .git/info/attributes bare.git/info/attributes'
 
 test_expect_success \
     'remove ignored file' \
@@ -139,10 +139,11 @@ test_expect_success \
 
 test_expect_success \
     'create archives with substfiles' \
-    'echo "substfile?" export-subst >a/.gitattributes &&
+    'cp .git/info/attributes .git/info/attributes.before &&
+     echo "substfile?" export-subst >>.git/info/attributes &&
      git archive HEAD >f.tar &&
      git archive --prefix=prefix/ HEAD >g.tar &&
-     rm a/.gitattributes'
+     mv .git/info/attributes.before .git/info/attributes'
 
 test_expect_success \
     'extract substfiles' \
-- 
1.6.3.rc0.6.g08087

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

* [PATCH 2/5] attr: add GIT_ATTR_INDEX "direction"
  2009-04-16  2:28 ` [PATCH 1/5] archive tests: do not use .gitattributes in working directory Junio C Hamano
@ 2009-04-16  2:28   ` Junio C Hamano
  2009-04-16  2:28     ` [PATCH 3/5] unpack-trees: do not muck with attributes when we are not checking out Junio C Hamano
  2009-04-17 20:33     ` [PATCH 2/5] attr: add GIT_ATTR_INDEX "direction" René Scharfe
  2009-04-17 19:51   ` [PATCH 1/5] archive tests: do not use .gitattributes in working directory René Scharfe
  1 sibling, 2 replies; 19+ messages in thread
From: Junio C Hamano @ 2009-04-16  2:28 UTC (permalink / raw)
  To: git; +Cc: Nguyễn Thái Ngọc Duy

From: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>

This instructs attr mechanism, not to look into working .gitattributes
at all. Needed by tools that does not handle working directory, such
as "git archive".

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 attr.c |   12 +++++++++---
 attr.h |    3 ++-
 2 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/attr.c b/attr.c
index 43259e5..626eadb 100644
--- a/attr.c
+++ b/attr.c
@@ -405,7 +405,7 @@ static struct attr_stack *read_attr(const char *path, int macro_ok)
 		if (!res)
 			res = read_attr_from_file(path, macro_ok);
 	}
-	else {
+	else if (direction == GIT_ATTR_CHECKIN) {
 		res = read_attr_from_file(path, macro_ok);
 		if (!res)
 			/*
@@ -415,6 +415,8 @@ static struct attr_stack *read_attr(const char *path, int macro_ok)
 			 */
 			res = read_attr_from_index(path, macro_ok);
 	}
+	else
+		res = read_attr_from_index(path, macro_ok);
 	if (!res)
 		res = xcalloc(1, sizeof(*res));
 	return res;
@@ -466,7 +468,7 @@ static void bootstrap_attr_stack(void)
 		elem->prev = attr_stack;
 		attr_stack = elem;
 
-		if (!is_bare_repository()) {
+		if (!is_bare_repository() || direction == GIT_ATTR_INDEX) {
 			elem = read_attr(GITATTRIBUTES_FILE, 1);
 			elem->origin = strdup("");
 			elem->prev = attr_stack;
@@ -533,7 +535,7 @@ static void prepare_attr_stack(const char *path, int dirlen)
 	/*
 	 * Read from parent directories and push them down
 	 */
-	if (!is_bare_repository()) {
+	if (!is_bare_repository() || direction == GIT_ATTR_INDEX) {
 		while (1) {
 			char *cp;
 
@@ -674,6 +676,10 @@ int git_checkattr(const char *path, int num, struct git_attr_check *check)
 void git_attr_set_direction(enum git_attr_direction new, struct index_state *istate)
 {
 	enum git_attr_direction old = direction;
+
+	if (is_bare_repository() && new != GIT_ATTR_INDEX)
+		die("BUG: non-INDEX att direction in a bare repo");
+
 	direction = new;
 	if (new != old)
 		drop_attr_stack();
diff --git a/attr.h b/attr.h
index 3a2f4ec..69b5767 100644
--- a/attr.h
+++ b/attr.h
@@ -33,7 +33,8 @@ int git_checkattr(const char *path, int, struct git_attr_check *);
 
 enum git_attr_direction {
 	GIT_ATTR_CHECKIN,
-	GIT_ATTR_CHECKOUT
+	GIT_ATTR_CHECKOUT,
+	GIT_ATTR_INDEX,
 };
 void git_attr_set_direction(enum git_attr_direction, struct index_state *);
 
-- 
1.6.3.rc0.6.g08087

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

* [PATCH 3/5] unpack-trees: do not muck with attributes when we are not checking out
  2009-04-16  2:28   ` [PATCH 2/5] attr: add GIT_ATTR_INDEX "direction" Junio C Hamano
@ 2009-04-16  2:28     ` Junio C Hamano
  2009-04-16  2:28       ` [PATCH 4/5] archive: do not read .gitattributes in working directory Junio C Hamano
  2009-04-17 20:33     ` [PATCH 2/5] attr: add GIT_ATTR_INDEX "direction" René Scharfe
  1 sibling, 1 reply; 19+ messages in thread
From: Junio C Hamano @ 2009-04-16  2:28 UTC (permalink / raw)
  To: git

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 unpack-trees.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/unpack-trees.c b/unpack-trees.c
index 6847c2d..e4eb8fa 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -87,7 +87,8 @@ static int check_updates(struct unpack_trees_options *o)
 		cnt = 0;
 	}
 
-	git_attr_set_direction(GIT_ATTR_CHECKOUT, &o->result);
+	if (o->update)
+		git_attr_set_direction(GIT_ATTR_CHECKOUT, &o->result);
 	for (i = 0; i < index->cache_nr; i++) {
 		struct cache_entry *ce = index->cache[i];
 
@@ -112,7 +113,8 @@ static int check_updates(struct unpack_trees_options *o)
 		}
 	}
 	stop_progress(&progress);
-	git_attr_set_direction(GIT_ATTR_CHECKIN, NULL);
+	if (o->update)
+		git_attr_set_direction(GIT_ATTR_CHECKIN, NULL);
 	return errs != 0;
 }
 
-- 
1.6.3.rc0.6.g08087

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

* [PATCH 4/5] archive: do not read .gitattributes in working directory
  2009-04-16  2:28     ` [PATCH 3/5] unpack-trees: do not muck with attributes when we are not checking out Junio C Hamano
@ 2009-04-16  2:28       ` Junio C Hamano
  2009-04-16  2:28         ` [PATCH 5/5] archive test: test new --fix-attributes feature Junio C Hamano
                           ` (3 more replies)
  0 siblings, 4 replies; 19+ messages in thread
From: Junio C Hamano @ 2009-04-16  2:28 UTC (permalink / raw)
  To: git; +Cc: Nguyễn Thái Ngọc Duy

From: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>

The old behaviour still remains with --fix-attributes, and it is always on
for the legacy "git tar-tree".

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 Documentation/git-archive.txt |    5 ++++-
 archive.c                     |   22 ++++++++++++++++++++++
 archive.h                     |    1 +
 builtin-tar-tree.c            |    8 ++++++++
 4 files changed, 35 insertions(+), 1 deletions(-)

diff --git a/Documentation/git-archive.txt b/Documentation/git-archive.txt
index c1adf59..fd882bf 100644
--- a/Documentation/git-archive.txt
+++ b/Documentation/git-archive.txt
@@ -10,7 +10,7 @@ SYNOPSIS
 --------
 [verse]
 'git archive' --format=<fmt> [--list] [--prefix=<prefix>/] [<extra>]
-	      [--output=<file>]
+	      [--output=<file>] [--fix-attributes]
 	      [--remote=<repo> [--exec=<git-upload-archive>]] <tree-ish>
 	      [path...]
 
@@ -51,6 +51,9 @@ OPTIONS
 --output=<file>::
 	Write the archive to <file> instead of stdout.
 
+--fix-attributes::
+	Look for attributes in .gitattributes in working directory too.
+
 <extra>::
 	This can be any options that the archiver backend understands.
 	See next section.
diff --git a/archive.c b/archive.c
index 96b62d4..0ce628b 100644
--- a/archive.c
+++ b/archive.c
@@ -4,6 +4,7 @@
 #include "attr.h"
 #include "archive.h"
 #include "parse-options.h"
+#include "unpack-trees.h"
 
 static char const * const archive_usage[] = {
 	"git archive [options] <tree-ish> [path...]",
@@ -150,6 +151,8 @@ 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] == '/') {
@@ -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)
@@ -258,6 +277,7 @@ static int parse_archive_args(int argc, const char **argv,
 	int verbose = 0;
 	int i;
 	int list = 0;
+	int worktree_attributes = 0;
 	struct option opts[] = {
 		OPT_GROUP(""),
 		OPT_STRING(0, "format", &format, "fmt", "archive format"),
@@ -265,6 +285,7 @@ static int parse_archive_args(int argc, const char **argv,
 			"prepend prefix to each pathname in the archive"),
 		OPT_STRING(0, "output", &output, "file",
 			"write the archive to this file"),
+		OPT_BOOLEAN(0, "fix-attributes", &worktree_attributes, "read .gitattributes in working directory"),
 		OPT__VERBOSE(&verbose),
 		OPT__COMPR('0', &compression_level, "store only", 0),
 		OPT__COMPR('1', &compression_level, "compress faster", 1),
@@ -324,6 +345,7 @@ static int parse_archive_args(int argc, const char **argv,
 	args->verbose = verbose;
 	args->base = base;
 	args->baselen = strlen(base);
+	args->worktree_attributes = worktree_attributes;
 
 	return argc;
 }
diff --git a/archive.h b/archive.h
index 0b15b35..038ac35 100644
--- a/archive.h
+++ b/archive.h
@@ -10,6 +10,7 @@ struct archiver_args {
 	time_t time;
 	const char **pathspec;
 	unsigned int verbose : 1;
+	unsigned int worktree_attributes : 1;
 	int compression_level;
 };
 
diff --git a/builtin-tar-tree.c b/builtin-tar-tree.c
index 0713bca..760ea9d 100644
--- a/builtin-tar-tree.c
+++ b/builtin-tar-tree.c
@@ -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--;
+	}
+
+	/* tar-tree defaults to fix-attributes as before */
+	nargv[nargc++] = "--fix-attributes";
+
 	switch (argc) {
 	default:
 		usage(tar_tree_usage);
-- 
1.6.3.rc0.6.g08087

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

* [PATCH 5/5] archive test: test new --fix-attributes feature
  2009-04-16  2:28       ` [PATCH 4/5] archive: do not read .gitattributes in working directory Junio C Hamano
@ 2009-04-16  2:28         ` Junio C Hamano
  2009-04-17 19:53           ` René Scharfe
  2009-04-16  5:17         ` [PATCH 4/5] archive: do not read .gitattributes in working directory Junio C Hamano
                           ` (2 subsequent siblings)
  3 siblings, 1 reply; 19+ messages in thread
From: Junio C Hamano @ 2009-04-16  2:28 UTC (permalink / raw)
  To: git; +Cc: René Scharfe

From: René Scharfe <rene.scharfe@lsrfire.ath.cx>

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 t/t5001-archive-attr.sh |   62 +++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 62 insertions(+), 0 deletions(-)
 create mode 100755 t/t5001-archive-attr.sh

diff --git a/t/t5001-archive-attr.sh b/t/t5001-archive-attr.sh
new file mode 100755
index 0000000..b754f21
--- /dev/null
+++ b/t/t5001-archive-attr.sh
@@ -0,0 +1,62 @@
+#!/bin/sh
+
+test_description='git archive attribute tests'
+
+. ./test-lib.sh
+
+SUBSTFORMAT=%H%n
+
+test_expect_success 'setup' '
+	echo ignored >ignored &&
+	echo ignored export-ignore >>.git/info/attributes &&
+	git add ignored &&
+
+	echo ignored by tree >ignored-by-tree &&
+	echo ignored-by-tree export-ignore >.gitattributes &&
+	git add ignored-by-tree .gitattributes &&
+
+	echo ignored by worktree >ignored-by-worktree &&
+	echo ignored-by-worktree export-ignore >.gitattributes &&
+	git add ignored-by-worktree &&
+
+	printf "A\$Format:%s\$O" "$SUBSTFORMAT" >nosubstfile &&
+	printf "A\$Format:%s\$O" "$SUBSTFORMAT" >substfile1 &&
+	printf "A not substituted O" >substfile2 &&
+	echo "substfile?" export-subst >>.git/info/attributes &&
+	git add nosubstfile substfile1 substfile2 &&
+
+	git commit -m.
+'
+
+test_expect_success 'git archive' '
+	git archive HEAD >archive.tar &&
+	(mkdir archive && cd archive && "$TAR" xf -) <archive.tar
+'
+
+test_expect_success 'git archive with worktree attributes' '
+	git archive --fix-attributes HEAD >worktree.tar &&
+	(mkdir worktree && cd worktree && "$TAR" xf -) <worktree.tar
+'
+
+test_expect_success 'export-ignore' '
+	test ! -e archive/ignored &&
+	test ! -e archive/ignored-by-tree &&
+	test   -e archive/ignored-by-worktree &&
+	test ! -e worktree/ignored &&
+	test   -e worktree/ignored-by-tree &&
+	test ! -e worktree/ignored-by-worktree
+'
+
+test_expect_success 'export-subst' '
+	git log "--pretty=format:A${SUBSTFORMAT}O" HEAD >substfile1.expected &&
+	test_cmp nosubstfile archive/nosubstfile &&
+	test_cmp substfile1.expected archive/substfile1 &&
+	test_cmp substfile2 archive/substfile2
+'
+
+test_expect_success 'git tar-tree vs. git archive with worktree attributes' '
+	git tar-tree HEAD >tar-tree.tar &&
+	test_cmp worktree.tar tar-tree.tar
+'
+
+test_done
-- 
1.6.3.rc0.6.g08087

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

* Re: [PATCH 4/5] archive: do not read .gitattributes in working directory
  2009-04-16  2:28       ` [PATCH 4/5] archive: do not read .gitattributes in working directory Junio C Hamano
  2009-04-16  2:28         ` [PATCH 5/5] archive test: test new --fix-attributes feature Junio C Hamano
@ 2009-04-16  5:17         ` Junio C Hamano
  2009-04-16  7:06           ` Jeff King
  2009-04-16  7:29         ` Jakub Narebski
  2009-04-16 10:50         ` Nguyen Thai Ngoc Duy
  3 siblings, 1 reply; 19+ messages in thread
From: Junio C Hamano @ 2009-04-16  5:17 UTC (permalink / raw)
  To: git; +Cc: Nguyễn Thái Ngọc Duy

Junio C Hamano <gitster@pobox.com> writes:

> diff --git a/builtin-tar-tree.c b/builtin-tar-tree.c
> index 0713bca..760ea9d 100644
> --- a/builtin-tar-tree.c
> +++ b/builtin-tar-tree.c
> @@ -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--;
> +	}
> +
> +	/* tar-tree defaults to fix-attributes as before */
> +	nargv[nargc++] = "--fix-attributes";
> +
>  	switch (argc) {
>  	default:
>  		usage(tar_tree_usage);

I screwed up this part; nargv[] array needs to be enlarged by one element
because of this change.  It resulted in a funny breakage in tests that
triggered only when run from the toplevel of the tree but did not surface
when the individual test was done from t/ directory, which my final
testing on the k.org machine caught, and that is why I still haven't
managed to push the result out for tonight.

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

* Re: [PATCH 4/5] archive: do not read .gitattributes in working directory
  2009-04-16  5:17         ` [PATCH 4/5] archive: do not read .gitattributes in working directory Junio C Hamano
@ 2009-04-16  7:06           ` Jeff King
  0 siblings, 0 replies; 19+ messages in thread
From: Jeff King @ 2009-04-16  7:06 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Nguyễn Thái Ngọc Duy

On Wed, Apr 15, 2009 at 10:17:36PM -0700, Junio C Hamano wrote:

> > +	/* tar-tree defaults to fix-attributes as before */
> > +	nargv[nargc++] = "--fix-attributes";
> > +
> >  	switch (argc) {
> >  	default:
> >  		usage(tar_tree_usage);
> 
> I screwed up this part; nargv[] array needs to be enlarged by one element
> because of this change.  It resulted in a funny breakage in tests that
> triggered only when run from the toplevel of the tree but did not surface
> when the individual test was done from t/ directory, which my final
> testing on the k.org machine caught, and that is why I still haven't
> managed to push the result out for tonight.

FWIW, running t5000 with --valgrind does catch it. I'll try to run the
full test suite with valgrind on the last -rc before 1.6.3 to catch any
hidden issues which have cropped up during this cycle (I can do it
earlier, too, but it is a real pain to run the whole thing, so I want to
just wait until the last minute).

-Peff

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

* Re: [PATCH 4/5] archive: do not read .gitattributes in working directory
  2009-04-16  2:28       ` [PATCH 4/5] archive: do not read .gitattributes in working directory Junio C Hamano
  2009-04-16  2:28         ` [PATCH 5/5] archive test: test new --fix-attributes feature Junio C Hamano
  2009-04-16  5:17         ` [PATCH 4/5] archive: do not read .gitattributes in working directory Junio C Hamano
@ 2009-04-16  7:29         ` Jakub Narebski
  2009-04-16 10:50         ` Nguyen Thai Ngoc Duy
  3 siblings, 0 replies; 19+ messages in thread
From: Jakub Narebski @ 2009-04-16  7:29 UTC (permalink / raw)
  To: git

Junio C Hamano wrote:

> The old behaviour still remains with --fix-attributes, and it is always on
> for the legacy "git tar-tree".

I thought that we agreed on '--worktree-attributes' being better name,
didn't we?

-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git

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

* Re: [PATCH 4/5] archive: do not read .gitattributes in working  directory
  2009-04-16  2:28       ` [PATCH 4/5] archive: do not read .gitattributes in working directory Junio C Hamano
                           ` (2 preceding siblings ...)
  2009-04-16  7:29         ` Jakub Narebski
@ 2009-04-16 10:50         ` Nguyen Thai Ngoc Duy
  2009-04-16 12:38           ` Nguyen Thai Ngoc Duy
  3 siblings, 1 reply; 19+ messages in thread
From: Nguyen Thai Ngoc Duy @ 2009-04-16 10:50 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

[-- Attachment #1: Type: text/plain, Size: 2454 bytes --]

Sorry I got distracted by Vista+x11 stuff and had not work on this.

2009/4/16 Junio C Hamano <gitster@pobox.com>:
> @@ -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?

> @@ -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

[-- Attachment #2: attr-1.patch --]
[-- Type: text/x-patch, Size: 1927 bytes --]

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);
 	}
 

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

* Re: [PATCH 4/5] archive: do not read .gitattributes in working  directory
  2009-04-16 10:50         ` Nguyen Thai Ngoc Duy
@ 2009-04-16 12:38           ` Nguyen Thai Ngoc Duy
  0 siblings, 0 replies; 19+ messages in thread
From: Nguyen Thai Ngoc Duy @ 2009-04-16 12:38 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

[-- Attachment #1: Type: text/plain, Size: 693 bytes --]

On Thu, Apr 16, 2009 at 8:50 PM, Nguyen Thai Ngoc Duy <pclouds@gmail.com> wrote:
> 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

Here it is (again on top of your patch). Need to read directories
twice, but not as bad as read_tree_recursive() twice.
-- 
Duy

[-- Attachment #2: attr-3.patch --]
[-- Type: text/x-patch, Size: 5198 bytes --]

diff --git a/archive.c b/archive.c
index 0ce628b..8df53a8 100644
--- a/archive.c
+++ b/archive.c
@@ -97,6 +97,43 @@ struct archiver_context {
 	write_archive_entry_fn_t write_entry;
 };
 
+static int read_gitattr_to_index(struct tree *tree, const char *base, int baselen, struct archiver_args *args)
+{
+	struct tree_desc desc;
+	struct name_entry entry;
+	struct cache_entry *ce;
+	unsigned int size;
+	int pathlen;
+
+	if (parse_tree(tree))
+		return -1;
+
+	init_tree_desc(&desc, tree->buffer, tree->size);
+
+	while (tree_entry(&desc, &entry)) {
+		if (S_ISDIR(entry.mode) || S_ISGITLINK(entry.mode))
+			continue;
+		if (strcmp(entry.path, GITATTRIBUTES_FILE))
+			continue;
+		pathlen = tree_entry_len(entry.path, entry.sha1);
+		baselen -= args->baselen; /* remove user prefix */
+		if (baselen)
+			baselen++; /* slash */
+		size = cache_entry_size(baselen + pathlen);
+		ce = xcalloc(1, size);
+		ce->ce_mode = create_ce_mode(entry.mode);
+		ce->ce_flags = create_ce_flags(baselen + pathlen, 0);
+		if (baselen) {
+			memcpy(ce->name, base + args->baselen, baselen-1);
+			ce->name[baselen-1] = '/';
+		}
+		memcpy(ce->name + baselen, entry.path, pathlen + 1);
+		hashcpy(ce->sha1, entry.sha1);
+		return add_cache_entry(ce, ADD_CACHE_OK_TO_ADD | ADD_CACHE_SKIP_DFCHECK);
+	}
+	return 0;
+}
+
 static int write_archive_entry(const unsigned char *sha1, const char *base,
 		int baselen, const char *filename, unsigned mode, int stage,
 		void *context)
@@ -119,11 +156,25 @@ static int write_archive_entry(const unsigned char *sha1, const char *base,
 	strbuf_addstr(&path, filename);
 	path_without_prefix = path.buf + args->baselen;
 
-	setup_archive_check(check);
-	if (!git_checkattr(path_without_prefix, ARRAY_SIZE(check), check)) {
-		if (ATTR_TRUE(check[0].value))
-			return 0;
-		convert = ATTR_TRUE(check[1].value);
+	if (S_ISDIR(mode)) {
+		/*
+		 * we want to read .gitattributes before any entry is processed
+		 * so every time we get a directory entry, we look ahead to see
+		 * if there is .gitattributes and load it
+		 *
+		 * later when the directory is processed, .gitattributes is
+		 * already ready in index for git_checkattr()
+		 */
+		if (!args->worktree_attributes)
+			read_gitattr_to_index(lookup_tree(sha1), base, baselen, args);
+	}
+	else {
+		setup_archive_check(check);
+		if (!git_checkattr(path_without_prefix, ARRAY_SIZE(check), check)) {
+			if (ATTR_TRUE(check[0].value))
+				return 0;
+			convert = ATTR_TRUE(check[1].value);
+		}
 	}
 
 	if (S_ISDIR(mode) || S_ISGITLINK(mode)) {
@@ -151,8 +202,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;
 
 	if (args->baselen > 0 && args->base[args->baselen - 1] == '/') {
@@ -171,19 +220,9 @@ 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 .gitattributes at root if any */
+		read_gitattr_to_index(args->tree, args->base, args->baselen, args);
 		git_attr_set_direction(GIT_ATTR_INDEX, &the_index);
 	}
 
@@ -209,13 +248,23 @@ static const struct archiver *lookup_archiver(const char *name)
 }
 
 static void parse_pathspec_arg(const char **pathspec,
-		struct archiver_args *ar_args)
+		struct archiver_args *ar_args,
+		const char *prefix)
 {
-	ar_args->pathspec = get_pathspec(ar_args->base, pathspec);
+	struct strbuf s = STRBUF_INIT;
+	if (ar_args->base)
+		strbuf_addstr(&s, ar_args->base);
+	if (prefix)
+		strbuf_addstr(&s, prefix);
+	ar_args->pathspec = get_pathspec(s.len ? s.buf : NULL, pathspec);
+	/*
+	 * s.buf must never be freed because
+	 * get_pathspec does not duplicate it
+	 */
 }
 
 static void parse_treeish_arg(const char **argv,
-		struct archiver_args *ar_args, const char *prefix)
+		struct archiver_args *ar_args)
 {
 	const char *name = argv[0];
 	const unsigned char *commit_sha1;
@@ -240,18 +289,6 @@ static void parse_treeish_arg(const char **argv,
 	if (tree == NULL)
 		die("not a tree object");
 
-	if (prefix) {
-		unsigned char tree_sha1[20];
-		unsigned int mode;
-		int err;
-
-		err = get_tree_entry(tree->object.sha1, prefix,
-				     tree_sha1, &mode);
-		if (err || !S_ISDIR(mode))
-			die("current working directory is untracked");
-
-		tree = parse_tree_indirect(tree_sha1);
-	}
 	ar_args->tree = tree;
 	ar_args->commit_sha1 = commit_sha1;
 	ar_args->commit = commit;
@@ -360,8 +397,8 @@ int write_archive(int argc, const char **argv, const char *prefix,
 	if (setup_prefix && prefix == NULL)
 		prefix = setup_git_directory();
 
-	parse_treeish_arg(argv, &args, prefix);
-	parse_pathspec_arg(argv + 1, &args);
+	parse_treeish_arg(argv, &args);
+	parse_pathspec_arg(argv + 1, &args, prefix);
 
 	git_config(git_default_config, NULL);
 

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

* Re: [PATCH 1/5] archive tests: do not use .gitattributes in working directory
  2009-04-16  2:28 ` [PATCH 1/5] archive tests: do not use .gitattributes in working directory Junio C Hamano
  2009-04-16  2:28   ` [PATCH 2/5] attr: add GIT_ATTR_INDEX "direction" Junio C Hamano
@ 2009-04-17 19:51   ` René Scharfe
  1 sibling, 0 replies; 19+ messages in thread
From: René Scharfe @ 2009-04-17 19:51 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

Thanks for wrapping this series up.  You can add a

Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>

to the this patch, if you like.

René

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

* Re: [PATCH 5/5] archive test: test new --fix-attributes feature
  2009-04-16  2:28         ` [PATCH 5/5] archive test: test new --fix-attributes feature Junio C Hamano
@ 2009-04-17 19:53           ` René Scharfe
  0 siblings, 0 replies; 19+ messages in thread
From: René Scharfe @ 2009-04-17 19:53 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

Could you please squash in the following, which adds test cases for bare repos
and gives every export-ignore file existence test its own test case?  And also

Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>

?

 t/t5001-archive-attr.sh |   46 ++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 38 insertions(+), 8 deletions(-)

diff --git a/t/t5001-archive-attr.sh b/t/t5001-archive-attr.sh
index b754f21..dd93c3f 100755
--- a/t/t5001-archive-attr.sh
+++ b/t/t5001-archive-attr.sh
@@ -6,6 +6,14 @@ test_description='git archive attribute tests'
 
 SUBSTFORMAT=%H%n
 
+test_expect_exists() {
+	test_expect_success " $1 exists" "test -e $1"
+}
+
+test_expect_missing() {
+	test_expect_success " $1 does not exist" "test ! -e $1"
+}
+
 test_expect_success 'setup' '
 	echo ignored >ignored &&
 	echo ignored export-ignore >>.git/info/attributes &&
@@ -25,7 +33,10 @@ test_expect_success 'setup' '
 	echo "substfile?" export-subst >>.git/info/attributes &&
 	git add nosubstfile substfile1 substfile2 &&
 
-	git commit -m.
+	git commit -m. &&
+
+	git clone --bare . bare &&
+	cp .git/info/attributes bare/info/attributes
 '
 
 test_expect_success 'git archive' '
@@ -33,20 +44,34 @@ test_expect_success 'git archive' '
 	(mkdir archive && cd archive && "$TAR" xf -) <archive.tar
 '
 
+test_expect_missing	archive/ignored
+test_expect_missing	archive/ignored-by-tree
+test_expect_exists	archive/ignored-by-worktree
+
 test_expect_success 'git archive with worktree attributes' '
 	git archive --fix-attributes HEAD >worktree.tar &&
 	(mkdir worktree && cd worktree && "$TAR" xf -) <worktree.tar
 '
 
-test_expect_success 'export-ignore' '
-	test ! -e archive/ignored &&
-	test ! -e archive/ignored-by-tree &&
-	test   -e archive/ignored-by-worktree &&
-	test ! -e worktree/ignored &&
-	test   -e worktree/ignored-by-tree &&
-	test ! -e worktree/ignored-by-worktree
+test_expect_missing	worktree/ignored
+test_expect_exists	worktree/ignored-by-tree
+test_expect_missing	worktree/ignored-by-worktree
+
+test_expect_success 'git archive vs. bare' '
+	(cd bare && git archive HEAD) >bare-archive.tar &&
+	test_cmp archive.tar bare-archive.tar
+'
+
+test_expect_success 'git archive with worktree attributes, bare' '
+	(cd bare && git archive --fix-attributes HEAD) >bare-worktree.tar &&
+	(mkdir bare-worktree && cd bare-worktree && "$TAR" xf -
+	) <bare-worktree.tar
 '
 
+test_expect_missing	bare-worktree/ignored
+test_expect_exists	bare-worktree/ignored-by-tree
+test_expect_exists	bare-worktree/ignored-by-worktree
+
 test_expect_success 'export-subst' '
 	git log "--pretty=format:A${SUBSTFORMAT}O" HEAD >substfile1.expected &&
 	test_cmp nosubstfile archive/nosubstfile &&
@@ -59,4 +84,9 @@ test_expect_success 'git tar-tree vs. git archive with worktree attributes' '
 	test_cmp worktree.tar tar-tree.tar
 '
 
+test_expect_success 'git tar-tree vs. git archive with worktree attrs, bare' '
+	(cd bare && git tar-tree HEAD) >bare-tar-tree.tar &&
+	test_cmp bare-worktree.tar bare-tar-tree.tar
+'
+
 test_done

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

* Re: [PATCH 2/5] attr: add GIT_ATTR_INDEX "direction"
  2009-04-16  2:28   ` [PATCH 2/5] attr: add GIT_ATTR_INDEX "direction" Junio C Hamano
  2009-04-16  2:28     ` [PATCH 3/5] unpack-trees: do not muck with attributes when we are not checking out Junio C Hamano
@ 2009-04-17 20:33     ` René Scharfe
  1 sibling, 0 replies; 19+ messages in thread
From: René Scharfe @ 2009-04-17 20:33 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Nguyễn Thái Ngọc Duy

Junio C Hamano schrieb:
> @@ -674,6 +676,10 @@ int git_checkattr(const char *path, int num, struct git_attr_check *check)
>  void git_attr_set_direction(enum git_attr_direction new, struct index_state *istate)
>  {
>  	enum git_attr_direction old = direction;
> +
> +	if (is_bare_repository() && new != GIT_ATTR_INDEX)
> +		die("BUG: non-INDEX att direction in a bare repo");

It's just a message that is probably never shown, but "[...] attr
direction [...]" (with r) would still look better.

René

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

* [PATCH v2 1/5] archive tests: do not use .gitattributes in working directory
  2009-04-16  2:28 [PATCH 0/5] archive attribute series Junio C Hamano
  2009-04-16  2:28 ` [PATCH 1/5] archive tests: do not use .gitattributes in working directory Junio C Hamano
@ 2009-04-17 22:17 ` René Scharfe
  2009-04-17 22:17 ` [PATCH v2 2/5] attr: add GIT_ATTR_INDEX "direction" René Scharfe
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 19+ messages in thread
From: René Scharfe @ 2009-04-17 22:17 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Nguyễn Thái Ngọc Duy

We are interested in using archive mostly from a bare repository, so it
should not add .gitattributes to the work tree.

Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 t/t5000-tar-tree.sh |    9 +++++----
 1 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/t/t5000-tar-tree.sh b/t/t5000-tar-tree.sh
index 7641e0d..abb41b0 100755
--- a/t/t5000-tar-tree.sh
+++ b/t/t5000-tar-tree.sh
@@ -50,7 +50,7 @@ test_expect_success \
 test_expect_success \
     'add ignored file' \
     'echo ignore me >a/ignored &&
-     echo ignored export-ignore >.gitattributes'
+     echo ignored export-ignore >.git/info/attributes'
 
 test_expect_success \
     'add files to repository' \
@@ -64,7 +64,7 @@ test_expect_success \
 test_expect_success \
     'create bare clone' \
     'git clone --bare . bare.git &&
-     cp .gitattributes bare.git/info/attributes'
+     cp .git/info/attributes bare.git/info/attributes'
 
 test_expect_success \
     'remove ignored file' \
@@ -139,10 +139,11 @@ test_expect_success \
 
 test_expect_success \
     'create archives with substfiles' \
-    'echo "substfile?" export-subst >a/.gitattributes &&
+    'cp .git/info/attributes .git/info/attributes.before &&
+     echo "substfile?" export-subst >>.git/info/attributes &&
      git archive HEAD >f.tar &&
      git archive --prefix=prefix/ HEAD >g.tar &&
-     rm a/.gitattributes'
+     mv .git/info/attributes.before .git/info/attributes'
 
 test_expect_success \
     'extract substfiles' \
-- 
1.6.3.rc0

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

* [PATCH v2 2/5] attr: add GIT_ATTR_INDEX "direction"
  2009-04-16  2:28 [PATCH 0/5] archive attribute series Junio C Hamano
  2009-04-16  2:28 ` [PATCH 1/5] archive tests: do not use .gitattributes in working directory Junio C Hamano
  2009-04-17 22:17 ` [PATCH v2 " René Scharfe
@ 2009-04-17 22:17 ` René Scharfe
  2009-04-17 22:18 ` [PATCH v2 3/5] unpack-trees: do not muck with attributes when we are not checking out René Scharfe
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 19+ messages in thread
From: René Scharfe @ 2009-04-17 22:17 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Nguyễn Thái Ngọc Duy

From: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>

This instructs attr mechanism, not to look into working .gitattributes
at all. Needed by tools that does not handle working directory, such
as "git archive".

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 attr.c |   12 +++++++++---
 attr.h |    3 ++-
 2 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/attr.c b/attr.c
index 43259e5..f1ca4f5 100644
--- a/attr.c
+++ b/attr.c
@@ -405,7 +405,7 @@ static struct attr_stack *read_attr(const char *path, int macro_ok)
 		if (!res)
 			res = read_attr_from_file(path, macro_ok);
 	}
-	else {
+	else if (direction == GIT_ATTR_CHECKIN) {
 		res = read_attr_from_file(path, macro_ok);
 		if (!res)
 			/*
@@ -415,6 +415,8 @@ static struct attr_stack *read_attr(const char *path, int macro_ok)
 			 */
 			res = read_attr_from_index(path, macro_ok);
 	}
+	else
+		res = read_attr_from_index(path, macro_ok);
 	if (!res)
 		res = xcalloc(1, sizeof(*res));
 	return res;
@@ -466,7 +468,7 @@ static void bootstrap_attr_stack(void)
 		elem->prev = attr_stack;
 		attr_stack = elem;
 
-		if (!is_bare_repository()) {
+		if (!is_bare_repository() || direction == GIT_ATTR_INDEX) {
 			elem = read_attr(GITATTRIBUTES_FILE, 1);
 			elem->origin = strdup("");
 			elem->prev = attr_stack;
@@ -533,7 +535,7 @@ static void prepare_attr_stack(const char *path, int dirlen)
 	/*
 	 * Read from parent directories and push them down
 	 */
-	if (!is_bare_repository()) {
+	if (!is_bare_repository() || direction == GIT_ATTR_INDEX) {
 		while (1) {
 			char *cp;
 
@@ -674,6 +676,10 @@ int git_checkattr(const char *path, int num, struct git_attr_check *check)
 void git_attr_set_direction(enum git_attr_direction new, struct index_state *istate)
 {
 	enum git_attr_direction old = direction;
+
+	if (is_bare_repository() && new != GIT_ATTR_INDEX)
+		die("BUG: non-INDEX attr direction in a bare repo");
+
 	direction = new;
 	if (new != old)
 		drop_attr_stack();
diff --git a/attr.h b/attr.h
index 3a2f4ec..69b5767 100644
--- a/attr.h
+++ b/attr.h
@@ -33,7 +33,8 @@ int git_checkattr(const char *path, int, struct git_attr_check *);
 
 enum git_attr_direction {
 	GIT_ATTR_CHECKIN,
-	GIT_ATTR_CHECKOUT
+	GIT_ATTR_CHECKOUT,
+	GIT_ATTR_INDEX,
 };
 void git_attr_set_direction(enum git_attr_direction, struct index_state *);
 
-- 
1.6.3.rc0

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

* [PATCH v2 3/5] unpack-trees: do not muck with attributes when we are not checking out
  2009-04-16  2:28 [PATCH 0/5] archive attribute series Junio C Hamano
                   ` (2 preceding siblings ...)
  2009-04-17 22:17 ` [PATCH v2 2/5] attr: add GIT_ATTR_INDEX "direction" René Scharfe
@ 2009-04-17 22:18 ` René Scharfe
  2009-04-17 22:18 ` [PATCH v2 4/5] archive: do not read .gitattributes in working directory René Scharfe
  2009-04-17 22:18 ` [PATCH v2 5/5] archive test: attributes René Scharfe
  5 siblings, 0 replies; 19+ messages in thread
From: René Scharfe @ 2009-04-17 22:18 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Nguyễn Thái Ngọc Duy

From: Junio C Hamano <gitster@pobox.com>

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 unpack-trees.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/unpack-trees.c b/unpack-trees.c
index 6847c2d..e4eb8fa 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -87,7 +87,8 @@ static int check_updates(struct unpack_trees_options *o)
 		cnt = 0;
 	}
 
-	git_attr_set_direction(GIT_ATTR_CHECKOUT, &o->result);
+	if (o->update)
+		git_attr_set_direction(GIT_ATTR_CHECKOUT, &o->result);
 	for (i = 0; i < index->cache_nr; i++) {
 		struct cache_entry *ce = index->cache[i];
 
@@ -112,7 +113,8 @@ static int check_updates(struct unpack_trees_options *o)
 		}
 	}
 	stop_progress(&progress);
-	git_attr_set_direction(GIT_ATTR_CHECKIN, NULL);
+	if (o->update)
+		git_attr_set_direction(GIT_ATTR_CHECKIN, NULL);
 	return errs != 0;
 }
 
-- 
1.6.3.rc0

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

* [PATCH v2 4/5] archive: do not read .gitattributes in working directory
  2009-04-16  2:28 [PATCH 0/5] archive attribute series Junio C Hamano
                   ` (3 preceding siblings ...)
  2009-04-17 22:18 ` [PATCH v2 3/5] unpack-trees: do not muck with attributes when we are not checking out René Scharfe
@ 2009-04-17 22:18 ` René Scharfe
  2009-04-17 22:18 ` [PATCH v2 5/5] archive test: attributes René Scharfe
  5 siblings, 0 replies; 19+ messages in thread
From: René Scharfe @ 2009-04-17 22:18 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Nguyễn Thái Ngọc Duy

From: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>

The old behaviour still remains with --worktree-attributes, and it is
always on for the legacy "git tar-tree".

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
Changes:

   s/--fix-attributes/--worktree-attributes/g

   Don't make tar-tree silently ignore --worktree-attributes; its
   behaviour should not be changed any more.

 Documentation/git-archive.txt |    5 ++++-
 archive.c                     |   23 +++++++++++++++++++++++
 archive.h                     |    1 +
 builtin-tar-tree.c            |    9 ++++++++-
 4 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/Documentation/git-archive.txt b/Documentation/git-archive.txt
index c1adf59..bc132c8 100644
--- a/Documentation/git-archive.txt
+++ b/Documentation/git-archive.txt
@@ -10,7 +10,7 @@ SYNOPSIS
 --------
 [verse]
 'git archive' --format=<fmt> [--list] [--prefix=<prefix>/] [<extra>]
-	      [--output=<file>]
+	      [--output=<file>] [--worktree-attributes]
 	      [--remote=<repo> [--exec=<git-upload-archive>]] <tree-ish>
 	      [path...]
 
@@ -51,6 +51,9 @@ OPTIONS
 --output=<file>::
 	Write the archive to <file> instead of stdout.
 
+--worktree-attributes::
+	Look for attributes in .gitattributes in working directory too.
+
 <extra>::
 	This can be any options that the archiver backend understands.
 	See next section.
diff --git a/archive.c b/archive.c
index 96b62d4..b2b90d3 100644
--- a/archive.c
+++ b/archive.c
@@ -4,6 +4,7 @@
 #include "attr.h"
 #include "archive.h"
 #include "parse-options.h"
+#include "unpack-trees.h"
 
 static char const * const archive_usage[] = {
 	"git archive [options] <tree-ish> [path...]",
@@ -150,6 +151,8 @@ 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] == '/') {
@@ -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)
@@ -258,6 +277,7 @@ static int parse_archive_args(int argc, const char **argv,
 	int verbose = 0;
 	int i;
 	int list = 0;
+	int worktree_attributes = 0;
 	struct option opts[] = {
 		OPT_GROUP(""),
 		OPT_STRING(0, "format", &format, "fmt", "archive format"),
@@ -265,6 +285,8 @@ static int parse_archive_args(int argc, const char **argv,
 			"prepend prefix to each pathname in the archive"),
 		OPT_STRING(0, "output", &output, "file",
 			"write the archive to this file"),
+		OPT_BOOLEAN(0, "worktree-attributes", &worktree_attributes,
+			"read .gitattributes in working directory"),
 		OPT__VERBOSE(&verbose),
 		OPT__COMPR('0', &compression_level, "store only", 0),
 		OPT__COMPR('1', &compression_level, "compress faster", 1),
@@ -324,6 +346,7 @@ static int parse_archive_args(int argc, const char **argv,
 	args->verbose = verbose;
 	args->base = base;
 	args->baselen = strlen(base);
+	args->worktree_attributes = worktree_attributes;
 
 	return argc;
 }
diff --git a/archive.h b/archive.h
index 0b15b35..038ac35 100644
--- a/archive.h
+++ b/archive.h
@@ -10,6 +10,7 @@ struct archiver_args {
 	time_t time;
 	const char **pathspec;
 	unsigned int verbose : 1;
+	unsigned int worktree_attributes : 1;
 	int compression_level;
 };
 
diff --git a/builtin-tar-tree.c b/builtin-tar-tree.c
index 0713bca..1a5a2ed 100644
--- a/builtin-tar-tree.c
+++ b/builtin-tar-tree.c
@@ -24,7 +24,7 @@ int cmd_tar_tree(int argc, const char **argv, const char *prefix)
 	 * 	git archive --format-tar --prefix=basedir tree-ish
 	 */
 	int i;
-	const char **nargv = xcalloc(sizeof(*nargv), argc + 2);
+	const char **nargv = xcalloc(sizeof(*nargv), argc + 3);
 	char *basedir_arg;
 	int nargc = 0;
 
@@ -36,6 +36,13 @@ int cmd_tar_tree(int argc, const char **argv, const char *prefix)
 		argv++;
 		argc--;
 	}
+
+	/*
+	 * Because it's just a compatibility wrapper, tar-tree supports only
+	 * the old behaviour of reading attributes from the work tree.
+	 */
+	nargv[nargc++] = "--worktree-attributes";
+
 	switch (argc) {
 	default:
 		usage(tar_tree_usage);
-- 
1.6.3.rc0

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

* [PATCH v2 5/5] archive test: attributes
  2009-04-16  2:28 [PATCH 0/5] archive attribute series Junio C Hamano
                   ` (4 preceding siblings ...)
  2009-04-17 22:18 ` [PATCH v2 4/5] archive: do not read .gitattributes in working directory René Scharfe
@ 2009-04-17 22:18 ` René Scharfe
  5 siblings, 0 replies; 19+ messages in thread
From: René Scharfe @ 2009-04-17 22:18 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Nguyễn Thái Ngọc Duy

Add a test script for all archive attributes and their handling in
normal and bare repositories.  export-ignore and export-subst are
tested, as well as the effect of the option --worktree-attributes.

Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
Any attribute related tests in t5000 can eventually be removed if
there is an equivalent test in t5001 -- and there should be.

 t/t5001-archive-attr.sh |   91 +++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 91 insertions(+), 0 deletions(-)
 create mode 100755 t/t5001-archive-attr.sh

diff --git a/t/t5001-archive-attr.sh b/t/t5001-archive-attr.sh
new file mode 100755
index 0000000..426b319
--- /dev/null
+++ b/t/t5001-archive-attr.sh
@@ -0,0 +1,91 @@
+#!/bin/sh
+
+test_description='git archive attribute tests'
+
+. ./test-lib.sh
+
+SUBSTFORMAT=%H%n
+
+test_expect_exists() {
+	test_expect_success " $1 exists" "test -e $1"
+}
+
+test_expect_missing() {
+	test_expect_success " $1 does not exist" "test ! -e $1"
+}
+
+test_expect_success 'setup' '
+	echo ignored >ignored &&
+	echo ignored export-ignore >>.git/info/attributes &&
+	git add ignored &&
+
+	echo ignored by tree >ignored-by-tree &&
+	echo ignored-by-tree export-ignore >.gitattributes &&
+	git add ignored-by-tree .gitattributes &&
+
+	echo ignored by worktree >ignored-by-worktree &&
+	echo ignored-by-worktree export-ignore >.gitattributes &&
+	git add ignored-by-worktree &&
+
+	printf "A\$Format:%s\$O" "$SUBSTFORMAT" >nosubstfile &&
+	printf "A\$Format:%s\$O" "$SUBSTFORMAT" >substfile1 &&
+	printf "A not substituted O" >substfile2 &&
+	echo "substfile?" export-subst >>.git/info/attributes &&
+	git add nosubstfile substfile1 substfile2 &&
+
+	git commit -m. &&
+
+	git clone --bare . bare &&
+	cp .git/info/attributes bare/info/attributes
+'
+
+test_expect_success 'git archive' '
+	git archive HEAD >archive.tar &&
+	(mkdir archive && cd archive && "$TAR" xf -) <archive.tar
+'
+
+test_expect_missing	archive/ignored
+test_expect_missing	archive/ignored-by-tree
+test_expect_exists	archive/ignored-by-worktree
+
+test_expect_success 'git archive with worktree attributes' '
+	git archive --worktree-attributes HEAD >worktree.tar &&
+	(mkdir worktree && cd worktree && "$TAR" xf -) <worktree.tar
+'
+
+test_expect_missing	worktree/ignored
+test_expect_exists	worktree/ignored-by-tree
+test_expect_missing	worktree/ignored-by-worktree
+
+test_expect_success 'git archive vs. bare' '
+	(cd bare && git archive HEAD) >bare-archive.tar &&
+	test_cmp archive.tar bare-archive.tar
+'
+
+test_expect_success 'git archive with worktree attributes, bare' '
+	(cd bare && git archive --worktree-attributes HEAD) >bare-worktree.tar &&
+	(mkdir bare-worktree && cd bare-worktree && "$TAR" xf -) <bare-worktree.tar
+'
+
+test_expect_missing	bare-worktree/ignored
+test_expect_exists	bare-worktree/ignored-by-tree
+test_expect_exists	bare-worktree/ignored-by-worktree
+
+test_expect_success 'export-subst' '
+	git log "--pretty=format:A${SUBSTFORMAT}O" HEAD >substfile1.expected &&
+	test_cmp nosubstfile archive/nosubstfile &&
+	test_cmp substfile1.expected archive/substfile1 &&
+	test_cmp substfile2 archive/substfile2
+'
+
+test_expect_success 'git tar-tree vs. git archive with worktree attributes' '
+	git tar-tree HEAD >tar-tree.tar &&
+	test_cmp worktree.tar tar-tree.tar
+'
+
+test_expect_success 'git tar-tree vs. git archive with worktree attrs, bare' '
+	(cd bare && git tar-tree HEAD) >bare-tar-tree.tar &&
+	test_cmp bare-worktree.tar bare-tar-tree.tar
+'
+
+test_done
-- 
1.6.3.rc0

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

end of thread, other threads:[~2009-04-17 22:20 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-04-16  2:28 [PATCH 0/5] archive attribute series Junio C Hamano
2009-04-16  2:28 ` [PATCH 1/5] archive tests: do not use .gitattributes in working directory Junio C Hamano
2009-04-16  2:28   ` [PATCH 2/5] attr: add GIT_ATTR_INDEX "direction" Junio C Hamano
2009-04-16  2:28     ` [PATCH 3/5] unpack-trees: do not muck with attributes when we are not checking out Junio C Hamano
2009-04-16  2:28       ` [PATCH 4/5] archive: do not read .gitattributes in working directory Junio C Hamano
2009-04-16  2:28         ` [PATCH 5/5] archive test: test new --fix-attributes feature Junio C Hamano
2009-04-17 19:53           ` René Scharfe
2009-04-16  5:17         ` [PATCH 4/5] archive: do not read .gitattributes in working directory Junio C Hamano
2009-04-16  7:06           ` Jeff King
2009-04-16  7:29         ` Jakub Narebski
2009-04-16 10:50         ` Nguyen Thai Ngoc Duy
2009-04-16 12:38           ` Nguyen Thai Ngoc Duy
2009-04-17 20:33     ` [PATCH 2/5] attr: add GIT_ATTR_INDEX "direction" René Scharfe
2009-04-17 19:51   ` [PATCH 1/5] archive tests: do not use .gitattributes in working directory René Scharfe
2009-04-17 22:17 ` [PATCH v2 " René Scharfe
2009-04-17 22:17 ` [PATCH v2 2/5] attr: add GIT_ATTR_INDEX "direction" René Scharfe
2009-04-17 22:18 ` [PATCH v2 3/5] unpack-trees: do not muck with attributes when we are not checking out René Scharfe
2009-04-17 22:18 ` [PATCH v2 4/5] archive: do not read .gitattributes in working directory René Scharfe
2009-04-17 22:18 ` [PATCH v2 5/5] archive test: attributes René Scharfe

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.