git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "René Scharfe" <rene.scharfe@lsrfire.ath.cx>
To: Jakub Narebski <jnareb@gmail.com>
Cc: Junio C Hamano <gitster@pobox.com>,
	Victor Bogado da Silva Lins <victor@bogado.net>,
	Sean Estabrooks <seanlkml@sympatico.ca>,
	git@vger.kernel.org
Subject: Re: how to git-archive ignore some files?
Date: Sun, 08 Jun 2008 18:42:33 +0200	[thread overview]
Message-ID: <484C0BF9.1090909@lsrfire.ath.cx> (raw)
In-Reply-To: <m3prrr50gc.fsf@localhost.localdomain>

Jakub Narebski schrieb:
> Junio C Hamano <gitster@pobox.com> writes:
> 
>> René Scharfe <rene.scharfe@lsrfire.ath.cx> writes:
>>
>>> Another idea: would it make sense to have an attribute for that instead
>>> (or in addition to the command line parameter)?  I.e. files marked
>>> export-ignore would not end up in the archive.  I suspect the set of
>>> files to ignore doesn't change from archive to archive one creates.
>> That sounds extremely sensible.
>>
>> Should/does git-archive read .gitattributes from the tree being exported?
> 
> If I understand and remember correctly, current implementation of
> gitattributes, and current tools (git-check-attr), use and can use
> only working directory version of .gitattributes, in part because of
> chicken-and-egg problem (attributes effect checkout) IIRC.
> 
> It would be nice if git-archive read and use .gitattribues from
> a tree being exported; this would for example make `export-subs`
> work even for bare repositories.  This would be needed for
> `export-ignore`.

git-archive uses the routines from attr.c, and this is where the ability
to read attributes from git trees should be added.  It's independent from
ignoring files when creating archives.  Maybe it would be a good idea to
add this feature; in the meantime users need to resort to adding their
attributes to $GIT_DIR/info/attributes.

Anyway, here's a patch to add export-ignore support to git-archive.
Files and directories with this attribute are not added to archives.

Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
---
 Documentation/gitattributes.txt |    6 ++++++
 archive-tar.c                   |    2 ++
 archive-zip.c                   |    2 ++
 archive.c                       |   13 +++++++++++++
 archive.h                       |    1 +
 t/t5000-tar-tree.sh             |    9 +++++++++
 6 files changed, 33 insertions(+), 0 deletions(-)

diff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt
index 471754e..6e67990 100644
--- a/Documentation/gitattributes.txt
+++ b/Documentation/gitattributes.txt
@@ -502,6 +502,12 @@ frotz	unspecified
 Creating an archive
 ~~~~~~~~~~~~~~~~~~~
 
+`export-ignore`
+^^^^^^^^^^^^^^^
+
+Files and directories with the attribute `export-ignore` won't be added to
+archive files.
+
 `export-subst`
 ^^^^^^^^^^^^^^
 
diff --git a/archive-tar.c b/archive-tar.c
index d7598f9..99db58f 100644
--- a/archive-tar.c
+++ b/archive-tar.c
@@ -247,6 +247,8 @@ static int write_tar_entry(const unsigned char *sha1,
 	strbuf_grow(&path, PATH_MAX);
 	strbuf_add(&path, base, baselen);
 	strbuf_addstr(&path, filename);
+	if (is_archive_path_ignored(path.buf + base_len))
+		return 0;
 	if (S_ISDIR(mode) || S_ISGITLINK(mode)) {
 		strbuf_addch(&path, '/');
 		buffer = NULL;
diff --git a/archive-zip.c b/archive-zip.c
index 18c0f87..5742762 100644
--- a/archive-zip.c
+++ b/archive-zip.c
@@ -176,6 +176,8 @@ static int write_zip_entry(const unsigned char *sha1,
 	crc = crc32(0, NULL, 0);
 
 	path = construct_path(base, baselen, filename, S_ISDIR(mode), &pathlen);
+	if (is_archive_path_ignored(path + base_len))
+		return 0;
 	if (verbose)
 		fprintf(stderr, "%s\n", path);
 	if (pathlen > 0xffff) {
diff --git a/archive.c b/archive.c
index 7a32c19..6502b76 100644
--- a/archive.c
+++ b/archive.c
@@ -82,3 +82,16 @@ void *sha1_file_to_archive(const char *path, const unsigned char *sha1,
 	return buffer;
 }
 
+int is_archive_path_ignored(const char *path)
+{
+	static struct git_attr *attr_export_ignore;
+	struct git_attr_check check[1];
+
+	if (!attr_export_ignore)
+		attr_export_ignore = git_attr("export-ignore", 13);
+
+	check[0].attr = attr_export_ignore;
+	if (git_checkattr(path, ARRAY_SIZE(check), check))
+		return 0;
+	return ATTR_TRUE(check[0].value);
+}
diff --git a/archive.h b/archive.h
index 5791e65..ddf004a 100644
--- a/archive.h
+++ b/archive.h
@@ -44,5 +44,6 @@ extern int write_zip_archive(struct archiver_args *);
 extern void *parse_extra_zip_args(int argc, const char **argv);
 
 extern void *sha1_file_to_archive(const char *path, const unsigned char *sha1, unsigned int mode, enum object_type *type, unsigned long *size, const struct commit *commit);
+extern int is_archive_path_ignored(const char *path);
 
 #endif	/* ARCHIVE_H */
diff --git a/t/t5000-tar-tree.sh b/t/t5000-tar-tree.sh
index 9b0baac..3f1e25d 100755
--- a/t/t5000-tar-tree.sh
+++ b/t/t5000-tar-tree.sh
@@ -45,6 +45,11 @@ test_expect_success \
      (cd a && find .) | sort >a.lst'
 
 test_expect_success \
+    'add ignored file' \
+    'echo ignore me >a/ignored &&
+     echo ignored export-ignore >.gitattributes'
+
+test_expect_success \
     'add files to repository' \
     'find a -type f | xargs git update-index --add &&
      find a -type l | xargs git update-index --add &&
@@ -54,6 +59,10 @@ test_expect_success \
      git commit-tree $treeid </dev/null)'
 
 test_expect_success \
+    'remove ignored file' \
+    'rm a/ignored'
+
+test_expect_success \
     'git archive' \
     'git archive HEAD >b.tar'
 

  reply	other threads:[~2008-06-08 16:43 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-05-06 18:15 how to git-archive ignore some files? Victor Bogado da Silva Lins
2008-05-06 18:56 ` Sean Estabrooks
2008-05-06 21:23   ` René Scharfe
2008-05-06 22:08     ` Junio C Hamano
2008-05-11 10:44       ` René Scharfe
2008-05-11 16:20         ` Junio C Hamano
2008-05-12  9:36           ` Jakub Narebski
2008-06-08 16:42             ` René Scharfe [this message]
2008-05-08 17:04 ` David Bryson
2008-05-08 20:22   ` Johannes Schindelin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=484C0BF9.1090909@lsrfire.ath.cx \
    --to=rene.scharfe@lsrfire.ath.cx \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=jnareb@gmail.com \
    --cc=seanlkml@sympatico.ca \
    --cc=victor@bogado.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).