{"thread":{"id":"13401","subject":"how to git-archive ignore some files?","startedAt":"2008-05-06T18:15:31Z","lastAt":"2008-06-08T16:42:33Z","messageCount":10,"participants":["Victor Bogado da Silva Lins","Sean Estabrooks","René Scharfe","Junio C Hamano","David Bryson","Johannes Schindelin","Jakub Narebski"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"76217","messageId":"1210097731.5238.3.camel@omicron.ep.petrobras.com.br","threadId":"13401","inReplyTo":null,"subject":"how to git-archive ignore some files?","fromName":"Victor Bogado da Silva Lins","fromEmail":"victor@bogado.net","sentAt":"2008-05-06T18:15:31Z","receivedAt":"2008-05-06T18:15:31Z","isPatch":false,"sender":{"key":"victor@bogado.net","avatar":"https://gravatar.com/avatar/4ad1d046d4c1a5673a65aac199e2113f4e2d2ffe88d095cb3e17c1f20126cfac?d=mp&s=160"},"body":"I want to use git-archive to create source packages, but my git\nrepository has a .gitignore that I don't want to be pushed into the\narchive. So is it possible to keep the .gitignore file in the repository\nand create an archive(*) without it? \n\n*) using git-archive, off course. \n"},{"id":"76218","messageId":"BAYC1-PASMTP023026B88005E512F95384AED60@CEZ.ICE","threadId":"13401","inReplyTo":"1210097731.5238.3.camel@omicron.ep.petrobras.com.br","subject":"Re: how to git-archive ignore some files?","fromName":"Sean Estabrooks","fromEmail":"seanlkml@sympatico.ca","sentAt":"2008-05-06T18:56:47Z","receivedAt":"2008-05-06T18:56:47Z","isPatch":false,"sender":{"key":"seanlkml@sympatico.ca","avatar":"https://gravatar.com/avatar/f92923f54fc08c401fc59b71829d4b89e9b8087fbba45ff87c82e6a83aee02ae?d=mp&s=160"},"body":"On Tue, 06 May 2008 15:15:31 -0300\nVictor Bogado da Silva Lins <victor@bogado.net> wrote:\n\n> I want to use git-archive to create source packages, but my git\n> repository has a .gitignore that I don't want to be pushed into the\n> archive. So is it possible to keep the .gitignore file in the repository\n> and create an archive(*) without it? \n> \n> *) using git-archive, off course. \n> \n\nHi Victor,\n\nYou can do something like:\n\ngit archive HEAD  | \\\n\ttar --delete .gitignore .mailmap .gitattributes | \\\n\tbzip2 -c > archive.tar.bz2\n\nHTH,\nSean\n"},{"id":"76223","messageId":"4820CC35.3090202@lsrfire.ath.cx","threadId":"13401","inReplyTo":"BAYC1-PASMTP023026B88005E512F95384AED60@CEZ.ICE","subject":"Re: how to git-archive ignore some files?","fromName":"René Scharfe","fromEmail":"rene.scharfe@lsrfire.ath.cx","sentAt":"2008-05-06T21:23:01Z","receivedAt":"2008-05-06T21:23:01Z","isPatch":false,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Sean Estabrooks schrieb:\n> On Tue, 06 May 2008 15:15:31 -0300\n> Victor Bogado da Silva Lins <victor@bogado.net> wrote:\n> \n>> I want to use git-archive to create source packages, but my git\n>> repository has a .gitignore that I don't want to be pushed into the\n>> archive. So is it possible to keep the .gitignore file in the repository\n>> and create an archive(*) without it? \n>>\n>> *) using git-archive, off course. \n>>\n> \n> Hi Victor,\n> \n> You can do something like:\n> \n> git archive HEAD  | \\\n> \ttar --delete .gitignore .mailmap .gitattributes | \\\n> \tbzip2 -c > archive.tar.bz2\n\nOr, if there is only a small number of files in your repository, you\ncould do something like this:\n\n   git archive HEAD -- \\\n      $(git ls-tree -r --name-only HEAD | grep -v '^\\.gitignore$')\n\nTo really solve this without external tools, git-archive needed to grow\nan --exclude option like git-ls-files, though.\n\nRené\n"},{"id":"76226","messageId":"7vk5i7gk6e.fsf@gitster.siamese.dyndns.org","threadId":"13401","inReplyTo":"4820CC35.3090202@lsrfire.ath.cx","subject":"Re: how to git-archive ignore some files?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-05-06T22:08:25Z","receivedAt":"2008-05-06T22:08:25Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"René Scharfe <rene.scharfe@lsrfire.ath.cx> writes:\n\n> To really solve this without external tools, git-archive needed to grow\n> an --exclude option like git-ls-files, though.\n\nBecause exclude is never about ignoring what is already tracked, an option\n\"like\" git-ls-files would not help this case, I am afraid.\n"},{"id":"76383","messageId":"20080508170442.GK9562@eratosthenes.sbcglobal.net","threadId":"13401","inReplyTo":"1210097731.5238.3.camel@omicron.ep.petrobras.com.br","subject":"Re: how to git-archive ignore some files?","fromName":"David Bryson","fromEmail":"david@statichacks.org","sentAt":"2008-05-08T17:04:42Z","receivedAt":"2008-05-08T17:04:42Z","isPatch":false,"sender":{"key":"david@statichacks.org","avatar":"https://gravatar.com/avatar/b8796a0b286799d99dcbaea3fd3e8675648cc094ff10b07bae8fe3bc0ac40b9c?d=mp&s=160"},"body":"Hi Victor,\n\nOn Tue, May 06, 2008 at 03:15:31PM -0300 or thereabouts, Victor Bogado da Silva Lins wrote:\n> I want to use git-archive to create source packages, but my git\n> repository has a .gitignore that I don't want to be pushed into the\n> archive. So is it possible to keep the .gitignore file in the repository\n> and create an archive(*) without it? \n> \n> *) using git-archive, off course. \n\nOthers already discussed the --delete method with tar, and I do something\nsimilar except slightly more flexible.  I have for example, a git repo\nthat checks out directories from CVS, and of course I don't want these\nCVS directories in my 'release'.  So put a executable '.release' file in\neach repo that tells my release script how to fix up the tarball to be\nproduction ready.\n\nHere is my release script, modeled after some lines Linus put in the git\ndocumentation.  It is meant to be run, reviewed for mistakes, and then\nhave the commands run via cut-paste.\n\n#!/bin/bash \nstable=\"$1\"\nlast=\"$2\"\nnew=\"$3\"\nchip=\"$4\"\nrel=`pwd | cut -d'/' -f6 | sed -e 's/\\.git//'`\n\nif [ -z $chip ]; then\n\treldir=$rel\nelse\n\treldir=$rel-$chip\nfi\n\nreldir=\"$reldir-$new\"\ntarfile=\"$reldir.tar\"\n\nif [ -d $reldir ]; then\n\techo \"release directory $reldir already exists, please remove\" 1>&2\n\texit 1\nfi\n\nif [ -f \"../$reldir.tar\" ]; then\n\techo \"Release file ../$reldir.tar already exists, please remove\" 1>&2\n\texit 1\nfi\n\nif [ -f \"../$reldir.tar.gz\" ]; then\n\techo \"Release file ../$reldir.tar.gz already exists, please remove\" 1>&2\n\texit 1\nfi\n\necho \"#git tag v$new\"\necho \"Tagging new release v$new\" 1>&2\necho \"git archive --prefix=$reldir/ v$new > ../$tarfile\"\necho \"mkdir $reldir\"\n#echo \"git diff v$stable v$new | gzip -9 > ../patch-$new.gz\"\necho \"git log --no-merges v$new ^v$last > $reldir/ChangeLog-$new\"\necho \"git shortlog --no-merges v$new ^v$last > $reldir/ShortLog\"\necho \"git diff --stat --summary -M v$last v$new > $reldir/diffstat-$new\"\necho \"tar -rf ../$tarfile $reldir/*\"\n./.release $reldir ../$tarfile\nif [ $? != 0 ]; then\n\techo \".release script failed! removing generated files\" 1>&2\n\techo \"rm -rf $reldir ../$tarfile\"\n\texit 1\nfi\necho \"gzip -9 < ../$tarfile > ../$tarfile.gz\"\necho \"rm -rf $reldir ../$tarfile\"\necho \"New release at ../$tarfile.gz\" 1>&2\n\nAnd an example .release file\n\n#!/bin/bash\ndirlist=\"make foo_include scripts\"\nexcludes=\"--exclude CVS --exclude '*.o' --exclude '*.swp' --exclude '*.d' --exclude '*.a'\"\nreldir=$1\ntarfile=$2\n#echo \"make doc && make -C doc/latex pdf\"\necho \"cp -a $dirlist $reldir\"\necho \"cp Makefile.release $reldir/Makefile\"\necho \"tar $excludes -rf $tarfile $reldir/*\"\n\n# write over the makefile\necho \"cp Makefile.release $reldir/Makefile\"\necho \"tar -u -f $tarfile $reldir/Makefile\"\necho \"tar --delete --file=$tarfile $reldir/Makefile.release\"\n\n# delete the doxygen file\necho \"cp Doxyfile $reldir\"\necho \"tar --delete --file=$tarfile $reldir/Doxyfile\"\n\n# remove traces of the release file\necho \"tar --delete --file=$tarfile $reldir/.release\"\n\n"},{"id":"76401","messageId":"alpine.DEB.1.00.0805082118390.30431@racer","threadId":"13401","inReplyTo":"20080508170442.GK9562@eratosthenes.sbcglobal.net","subject":"Re: how to git-archive ignore some files?","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2008-05-08T20:22:07Z","receivedAt":"2008-05-08T20:22:07Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Thu, 8 May 2008, David Bryson wrote:\n\n> On Tue, May 06, 2008 at 03:15:31PM -0300 or thereabouts, Victor Bogado da Silva Lins wrote:\n> > I want to use git-archive to create source packages, but my git \n> > repository has a .gitignore that I don't want to be pushed into the \n> > archive. So is it possible to keep the .gitignore file in the \n> > repository and create an archive(*) without it?\n> > \n> > *) using git-archive, off course. \n> \n> Others already discussed the --delete method with tar, [...]\n\nI wonder if the most natural way with Git would not be to create a \nthrow-away tree:\n\ncp .git/index .git/tmp-index &&\nGIT_INDEX_FILE=.git/tmp-index git rm --cached .gitignore &&\ngit archive $(GIT_INDEX_FILE=.git/tmp-index git write-tree) &&\nrm .git/tmp-index\n\nWARNING: this has not seen any testing.\n\nCiao,\nDscho\n"},{"id":"76598","messageId":"4826CE0B.8080109@lsrfire.ath.cx","threadId":"13401","inReplyTo":"7vk5i7gk6e.fsf@gitster.siamese.dyndns.org","subject":"Re: how to git-archive ignore some files?","fromName":"René Scharfe","fromEmail":"rene.scharfe@lsrfire.ath.cx","sentAt":"2008-05-11T10:44:27Z","receivedAt":"2008-05-11T10:44:27Z","isPatch":false,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Junio C Hamano schrieb:\n> René Scharfe <rene.scharfe@lsrfire.ath.cx> writes:\n> \n>> To really solve this without external tools, git-archive needed to\n>> grow an --exclude option like git-ls-files, though.\n> \n> Because exclude is never about ignoring what is already tracked, an\n> option \"like\" git-ls-files would not help this case, I am afraid.\n\nTrue, it should be named differently, e.g. --ignore.\n\nAnother idea: would it make sense to have an attribute for that instead\n(or in addition to the command line parameter)?  I.e. files marked\nexport-ignore would not end up in the archive.  I suspect the set of\nfiles to ignore doesn't change from archive to archive one creates.\n\nRené\n"},{"id":"76628","messageId":"7vwsm06cdd.fsf@gitster.siamese.dyndns.org","threadId":"13401","inReplyTo":"4826CE0B.8080109@lsrfire.ath.cx","subject":"Re: how to git-archive ignore some files?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-05-11T16:20:46Z","receivedAt":"2008-05-11T16:20:46Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"René Scharfe <rene.scharfe@lsrfire.ath.cx> writes:\n\n> Another idea: would it make sense to have an attribute for that instead\n> (or in addition to the command line parameter)?  I.e. files marked\n> export-ignore would not end up in the archive.  I suspect the set of\n> files to ignore doesn't change from archive to archive one creates.\n\nThat sounds extremely sensible.\n\nShould/does git-archive read .gitattributes from the tree being exported?\n"},{"id":"76684","messageId":"m3prrr50gc.fsf@localhost.localdomain","threadId":"13401","inReplyTo":"7vwsm06cdd.fsf@gitster.siamese.dyndns.org","subject":"Re: how to git-archive ignore some files?","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2008-05-12T09:36:33Z","receivedAt":"2008-05-12T09:36:33Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> René Scharfe <rene.scharfe@lsrfire.ath.cx> writes:\n> \n> > Another idea: would it make sense to have an attribute for that instead\n> > (or in addition to the command line parameter)?  I.e. files marked\n> > export-ignore would not end up in the archive.  I suspect the set of\n> > files to ignore doesn't change from archive to archive one creates.\n> \n> That sounds extremely sensible.\n> \n> Should/does git-archive read .gitattributes from the tree being exported?\n\nIf I understand and remember correctly, current implementation of\ngitattributes, and current tools (git-check-attr), use and can use\nonly working directory version of .gitattributes, in part because of\nchicken-and-egg problem (attributes effect checkout) IIRC.\n\nIt would be nice if git-archive read and use .gitattribues from\na tree being exported; this would for example make `export-subs`\nwork even for bare repositories.  This would be needed for\n`export-ignore`.\n-- \nJakub Narebski\nPoland\nShadeHawk on #git\n"},{"id":"79134","messageId":"484C0BF9.1090909@lsrfire.ath.cx","threadId":"13401","inReplyTo":"m3prrr50gc.fsf@localhost.localdomain","subject":"Re: how to git-archive ignore some files?","fromName":"René Scharfe","fromEmail":"rene.scharfe@lsrfire.ath.cx","sentAt":"2008-06-08T16:42:33Z","receivedAt":"2008-06-08T16:42:33Z","isPatch":false,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Jakub Narebski schrieb:\n> Junio C Hamano <gitster@pobox.com> writes:\n> \n>> René Scharfe <rene.scharfe@lsrfire.ath.cx> writes:\n>>\n>>> Another idea: would it make sense to have an attribute for that instead\n>>> (or in addition to the command line parameter)?  I.e. files marked\n>>> export-ignore would not end up in the archive.  I suspect the set of\n>>> files to ignore doesn't change from archive to archive one creates.\n>> That sounds extremely sensible.\n>>\n>> Should/does git-archive read .gitattributes from the tree being exported?\n> \n> If I understand and remember correctly, current implementation of\n> gitattributes, and current tools (git-check-attr), use and can use\n> only working directory version of .gitattributes, in part because of\n> chicken-and-egg problem (attributes effect checkout) IIRC.\n> \n> It would be nice if git-archive read and use .gitattribues from\n> a tree being exported; this would for example make `export-subs`\n> work even for bare repositories.  This would be needed for\n> `export-ignore`.\n\ngit-archive uses the routines from attr.c, and this is where the ability\nto read attributes from git trees should be added.  It's independent from\nignoring files when creating archives.  Maybe it would be a good idea to\nadd this feature; in the meantime users need to resort to adding their\nattributes to $GIT_DIR/info/attributes.\n\nAnyway, here's a patch to add export-ignore support to git-archive.\nFiles and directories with this attribute are not added to archives.\n\nSigned-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>\n---\n Documentation/gitattributes.txt |    6 ++++++\n archive-tar.c                   |    2 ++\n archive-zip.c                   |    2 ++\n archive.c                       |   13 +++++++++++++\n archive.h                       |    1 +\n t/t5000-tar-tree.sh             |    9 +++++++++\n 6 files changed, 33 insertions(+), 0 deletions(-)\n\ndiff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt\nindex 471754e..6e67990 100644\n--- a/Documentation/gitattributes.txt\n+++ b/Documentation/gitattributes.txt\n@@ -502,6 +502,12 @@ frotz\tunspecified\n Creating an archive\n ~~~~~~~~~~~~~~~~~~~\n \n+`export-ignore`\n+^^^^^^^^^^^^^^^\n+\n+Files and directories with the attribute `export-ignore` won't be added to\n+archive files.\n+\n `export-subst`\n ^^^^^^^^^^^^^^\n \ndiff --git a/archive-tar.c b/archive-tar.c\nindex d7598f9..99db58f 100644\n--- a/archive-tar.c\n+++ b/archive-tar.c\n@@ -247,6 +247,8 @@ static int write_tar_entry(const unsigned char *sha1,\n \tstrbuf_grow(&path, PATH_MAX);\n \tstrbuf_add(&path, base, baselen);\n \tstrbuf_addstr(&path, filename);\n+\tif (is_archive_path_ignored(path.buf + base_len))\n+\t\treturn 0;\n \tif (S_ISDIR(mode) || S_ISGITLINK(mode)) {\n \t\tstrbuf_addch(&path, '/');\n \t\tbuffer = NULL;\ndiff --git a/archive-zip.c b/archive-zip.c\nindex 18c0f87..5742762 100644\n--- a/archive-zip.c\n+++ b/archive-zip.c\n@@ -176,6 +176,8 @@ static int write_zip_entry(const unsigned char *sha1,\n \tcrc = crc32(0, NULL, 0);\n \n \tpath = construct_path(base, baselen, filename, S_ISDIR(mode), &pathlen);\n+\tif (is_archive_path_ignored(path + base_len))\n+\t\treturn 0;\n \tif (verbose)\n \t\tfprintf(stderr, \"%s\\n\", path);\n \tif (pathlen > 0xffff) {\ndiff --git a/archive.c b/archive.c\nindex 7a32c19..6502b76 100644\n--- a/archive.c\n+++ b/archive.c\n@@ -82,3 +82,16 @@ void *sha1_file_to_archive(const char *path, const unsigned char *sha1,\n \treturn buffer;\n }\n \n+int is_archive_path_ignored(const char *path)\n+{\n+\tstatic struct git_attr *attr_export_ignore;\n+\tstruct git_attr_check check[1];\n+\n+\tif (!attr_export_ignore)\n+\t\tattr_export_ignore = git_attr(\"export-ignore\", 13);\n+\n+\tcheck[0].attr = attr_export_ignore;\n+\tif (git_checkattr(path, ARRAY_SIZE(check), check))\n+\t\treturn 0;\n+\treturn ATTR_TRUE(check[0].value);\n+}\ndiff --git a/archive.h b/archive.h\nindex 5791e65..ddf004a 100644\n--- a/archive.h\n+++ b/archive.h\n@@ -44,5 +44,6 @@ extern int write_zip_archive(struct archiver_args *);\n extern void *parse_extra_zip_args(int argc, const char **argv);\n \n 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);\n+extern int is_archive_path_ignored(const char *path);\n \n #endif\t/* ARCHIVE_H */\ndiff --git a/t/t5000-tar-tree.sh b/t/t5000-tar-tree.sh\nindex 9b0baac..3f1e25d 100755\n--- a/t/t5000-tar-tree.sh\n+++ b/t/t5000-tar-tree.sh\n@@ -45,6 +45,11 @@ test_expect_success \\\n      (cd a && find .) | sort >a.lst'\n \n test_expect_success \\\n+    'add ignored file' \\\n+    'echo ignore me >a/ignored &&\n+     echo ignored export-ignore >.gitattributes'\n+\n+test_expect_success \\\n     'add files to repository' \\\n     'find a -type f | xargs git update-index --add &&\n      find a -type l | xargs git update-index --add &&\n@@ -54,6 +59,10 @@ test_expect_success \\\n      git commit-tree $treeid </dev/null)'\n \n test_expect_success \\\n+    'remove ignored file' \\\n+    'rm a/ignored'\n+\n+test_expect_success \\\n     'git archive' \\\n     'git archive HEAD >b.tar'\n \n"}]}