If you write open source code it is very useful to have a public version control system, but it is also important to remember what not to put in version control. Besides passwords, credit card numbers and other private information, one should also avoid putting files that are generated by various tools. Including the build and release processes.
Why to exclude generated files?
Before going to the list of what and the explanation of how, let's see why should we exclude generated files.
One of the values a version control system provides is making it easy to locate the changes we made. If there are files that were generated by various tools, those just create noise that makes it harder to focus on the real changes.
Besides, some of these files might include a timestamp so even if you have not changed anything in the code,
just ran perl Makefile.PL
you might get these files updated. Adding these changes to the repository would
create a lot of noise.
There are cases when opening a source file for reading will create a temporary file (e.g. vim will create a swap file). It would be very disturbing to see these files in the repository.
If you use a Mac, and use the Finder to browse the project directory, it might create a file called .DS_Store
we certainly don't want those to litter the filesystem of other people.
Finally, some of the generated files will be different among operating systems or even architectures of the same operating system. They might even differ based on what other Perl modules you have installed.
Seeing all those changes in the history will just confuse everyone and will make it hard to focus on the real changes.
What to exclude
Now let's go over the files and directories that should NOT be under version control and have some explanation what is what. We can even try to categorize them as Neil Bowers suggested.
Files generated by various parts of the Perl/CPAN toolchain
The blib/
directory (which probably stands for build lib) is where the build process creates a directory structure
that will be installed. In a simple perl modules this means copying the .pm
files from the lib/
directory
to the blib/
directory. In more complex cases modified versions of the .pm
files are placed in the
blib/
directory. I even recall modules that were creating .pm
file on-the-fly during the perl Makefile.PL
.
Other distributions, especially ones that are partially based on XS or C code, will put compiled files in the blib/
directory.
Build
and Build.bat
are created by perl Build.PL
and they aid in the release and installation process.
The former is created on *nix systems. The latter on MS Windows. Neither of these need to be kept around, nor should they be distributed.
_build/
is also created by perl Build.PL
and holds several files aiding the build process. No need
to keep them or to distribute them.
/.build/
.last_cover_stats
Makefile
is created by running perl Makefile.PL
. It can be very specific to the current system so
it should not be kept in version control or distributed.
Makefile.old
and Makefile.bak
are two "backup copies" of the Makefile. Usually none of them is needed.
Certainly they should not be kept around in version control, nor should they be distributed.
pm_to_blib
is an empty file created by the build process. It is used only to check if any of the source files are
out of date and needs to be rebuilt.
The inc/
directory is created by Module::Install. The content
of this directory should be included in the distribution, but should not be in the version control system. The directory
is created when the developer runs perl Makefile.PL
and it is used when the user installing the module runs
perl Makefile.PL
.
META.yml
and META.json
both contain computer readable meta-information about the distribution. They
are based on the content of the Makefile.PL, Build.PL, dist.ini and on the content of the modules being distributed.
There are two files for historical reasons. Originally it was just the yml file, now many people also include the json file.
Theoretically the content should be identical, though as far as I know the json file usually contains more details.
Some tools, e.g. MetaCPAN use the content of these files.
They are generated during the release of the distribution, and they should be included in the distribution,
but because they are generated files, they should NOT be under version control.
MYMETA.json
and MYMETA.yml
are similar to the META.json and META.yml files but they incorporate the
local specialties of the system where the distribution is currently being installed. They are used during the installation process,
but because they are site specific they should NOT be included in the distribution, and the should NOT
be under version control.
If you use MANIFEST.SKIP
then I'd add /MANIFEST
to the .gitignore file.
Distribution-Name-*
- If this is a repository of a distribution that will be released as Distribution-Name-1.02.tar.gz then
the build process is going to create a directory called Distribution-Name-1.02/ and then a
file called Distribution-Name-1.02.tar.gz. None of these should be kept in the repository where we keep the source code.
Files generated by various Perl tools
The cover_db/
directory is created by Devel::Cover module when
you generated a test-coverage report.
nytprof.out
is created by Devel::NYTProf, the profiler
many people use. This generated file should not be kept in version control, nor should it be included in the distribution.
.tidyall.d/
is a directory created and maintained by Code::TidyAll.
It is a cache to speed up the perltidy process.
Files from the OS
On Mac the Finder, the directory browser creates a file called .DS_Store
in directories
one visits. This is computer specific and should be excluded from the version control system
Files from text editors, compilers, etc
If you use vim
for editing file I'd add *.swp
to ignore the swap files.
How to exclude
It depends on the version control system you use. Git will look at a file called .gitignore
in the root
of the repository. Mercurial (HG) looks at a file called .hgignore
in the root of the repository. Subversion uses the svn:ignore
property
on a directory to defined what items to ignore in that directory. The SVN Book describes
how to ignore unversioned files in Subversion.
GitHub maintains a repository of gitignore files. They have language, project, operating system and editor specific gitignore files. A good gitignore file is for a perl project is probably a combination of several of these files.
.gitignore for Git users
As Git is currently the most widely used version control system for Perl-based project, let's see a
useful .gitignore
file with some explanation.
If you have a Git repository you can easily tell it which files to ignore.
You create a file called .gitignore
in the root directory
of your repository and then follow the instructions on gitignore.
If you'd like to understand more deeply, then you can also read the
explanation about .gitignore.
In this repository there is a sample gitignore file for Perl developers I've repeated here:
/blib/
/.build/
_build/
cover_db/
inc/
Build
!Build/
Build.bat
.last_cover_stats
/Makefile
/Makefile.old
/MANIFEST.bak
/META.yml
/META.json
/MYMETA.*
nytprof.out
/pm_to_blib
*.o
*.bs
I'd probably add the following:
# If MANIFEST.SKIP is used:
/MANIFEST
# Mac Finder generated:
.DS_Store
# vim swap files:
*.swp
# random backup files:
*.bak
# Code::TidyAll Test::Code::TidyAll cache:
/.tidyall.d/
In addition there are some module specific things you might want to add to the .gitignore file:
# Dancer puts the session objects in the session directory and the logs in the logs/ directory
/session
/logs
If you have additions or more recommendation, you can fork the repository of this site and send me a pull-request. Look for the big green button at the top of the page.