cleaning ignored files

Matthew Fluet <[email protected]> Thu, 23 May 2013 12:08:02 -0400
Newsgroups gmane.comp.lang.ml.mlton.devel
Message-ID <CAMrhFL44yqNuBsRxODFiD8-Ym6Y_q=9EnEuD1k5hNV11CO_OmA@mail.gmail.com>
I'm working on cleaning up a few items from the SVN to Git transition;
see https://github.com/MatthewFluet/mlton/commits/svn-cleanup

Here is one issue that I'm not sure how to handle.  Since most (if not
all) generated files should both be ignored by version control and
deleted by 'make clean', the 'bin/clean' script attempts to delete
files ignored by version control.  As we've moved through different
version control systems, we've needed to adapt to different
conventions/semantics for ignoring files.  CVS's '.cvsignore' files
are per-directory (pathless) file name patterns, so a simple "for f in
`cat .cvsignore`; do rm -rf $f; done" sufficed.  Subversion's
'svn:ignore' properties are also per-directory (pathless) file name
patterns, but are part of the Subversion meta-data.  In order for
'make clean' to work properly in a source release, we used '.ignore'
files (and 'bin/sync-ignore' to synchronize the '.ignore' files with
the corresponding 'svn:ignore' properties) and the 'bin/clean' script
evolved to "xargs -n 1 find . -maxdepth 1 -name < .ignore | xargs rm
-rf" (to be robust in the presence of ignored files with spaces).

Git's '.gitignore' files are bit more complicated.  In the initial SVN
to Git transition, I simply added a '.gitignore' symlink for each
'.ignore' file.  This was simple and avoided the need to audit other
uses of '.ignore' files (such as by the 'bin/clean' script), but it
has changed the semantics of ignoring files.  Git '.gitignore'
patterns can match both (pathless) file names and file paths and
ignore patterns are cumulative from the root directory to the working
directory.  So, for instance, the 'build' pattern in the root
directory '.ignore' now causes any file or directory named 'build'
anywhere in the project to be ignored.  More usefully, the '*.o' and
'*.a' patterns in the 'runtime/.ignore' cause all of the .o files in
'runtime/', 'runtime/platform/', 'runtime/gc/', 'runtime/basis/*/',
etc. to be ignored, without requiring '.ignore'/'.gitignore' files in
each and every directory.  (These '*.o' and '*.a' patterns weren't
actually part of the CVS or SVN repository sources; the expectation
was that such globally ignored files would be specified in a users
~/.cvsignore or ~/.subversion/config.  Indeed, the 'bin/clean' script
specially handles .o and .a files and other globally ignored files.)

On the one hand, it would be nice to take advantage of Git's richer
semantics for ignoring files.  On the other hand, it is not clear how
to replicate that semantics in the 'bin/clean' script.  While 'git
clean -f -X -d' would work in a Git repository, it won't work in a
source release (and can't be invoked on a single directory without
also cleaning all recursive sub-directories).  A compromise might be
to put global ignores in the root '.gitignore' file and update the
remaining '.gitignore' files to patterns that only match files in the
corresponding directory.

Thoughts or suggestions?

------------------------------------------------------------------------------
Try New Relic Now & We'll Send You this Cool Shirt
New Relic is the only SaaS-based application performance monitoring service 
that delivers powerful full stack analytics. Optimize and monitor your
browser, app, & servers with just a few lines of code. Try New Relic
and get this awesome Nerd Life shirt! http://p.sf.net/sfu/newrelic_d2d_may