Branch specific gitignores for Bioconductor package documentation
For more background on this post, see this
thread
on the Bioc-devel mailing list. The short story is that I use Hadley
Wickham pkgdown package to
build a website for my packages and then publish it on GitHub.
The easiest is to create a ./docs package directory that contains
the whole site and configure GitHub pages to use it directly to
produce, for example, the
MSnbase page.
The ./docs directory ends in the package’s source which, on one hand
is nice as it simplifies tracking/committing of the site pages with
the package itself, but, on the other hand, the site also ends up on
the Bioconductor subversion server, where it doesn’t serve any purpose
other than taking space (5.5M in the case above).
Ignoring site from package tarball
It is straightforward to exclude the site’s docs directory in the
package tarball/zipfile by amending the .Rbuildignore file - adding
docs will do the trick.
Excluding from svn
It is not straightforward, however, to ignore the docs directory on
the Bioconductor hedgehog subversion server if you use git-svn to
manage the GitHub and subversion repositories together.
Unfortunately, git doesn’t support branch-specific .gitignore
files or directives. Using different .gitignore files for different
branches requires a hack described
here. Here’s
how I have implemented it when documenting my Bioconductor packages
with pkgdown.
Define files to ignore
Instead of have a single static .gitignore files, we are going to
create as branch-specific files and one general file defining what to
ignore. They all come in a new gitignores directory. I choose to
name the general file all and the branch-specific ones using the
branch name (devel below).
$ tree .gitignores
.gitignores
├── all
└── develEach file contains exactly what a .gitignore file would contain.
$ cat .gitignores/all
Makefile
.gitignore
$ cat .gitignores/devel
docsDynamic generation of .gitignore
When I’m in master, I want my .gitignore file to list files in
.gitignores/all only. When I’m in devel, I want both files from
.gitignores/all and .gitignores/devel to be listed in
.gitignore. This can be achieved with a post-checkout hook, that
will be triggered after each git checkout. Mine is currently pretty
simple. I will always create a new .gitignore file from
.gitignores/all and will append the content of a file in
.gitignores/ that matches the branch name.
$ cat .git/hooks/post-checkout
#!/bin/bash
# Copy in .git/hooks/post-checkout and make it executable
branch=$(git rev-parse --abbrev-ref HEAD)
cat .gitignores/all > .gitignore
if [[ -f .gitignores/$branch ]]; then
cat .gitignores/$branch >> .gitignore;
fiIn action
And …
$ git branch
devel
* master
release-3.0
release-3.1
release-3.2
release-3.3
$ cat .gitignore
Makefile
.gitignore
$ git checkout devel
Switched to branch 'devel'
Your branch and 'bioc/master' have diverged,
and have 1754 and 12 different commits each, respectively.
(use "git pull" to merge the remote branch into yours)
$ cat .gitignore
Makefile
.gitignore
docsI seems to work as expected.
I find this solution rather easy to implement. The major benefit is
that once it is in place, I can forget about it and things should work
irrespective of the docs directory.
Drawback
There is one drawback with this solution, however. When comparing the
devel and master branches with git diff, the ignored files are
still shown.
$ git branch
* devel
master
release-3.0
release-3.1
release-3.2
release-3.3
$ git diff --name-only master | head
docs/articles/Bugs.md
docs/articles/Bugs.tex
docs/articles/Figures/MSnbase-io-in.png
docs/articles/Figures/MSnbase-io-in.tex
docs/articles/Figures/MSnbase-io-out.png
docs/articles/Figures/MSnbase-io-out.tex
docs/articles/Figures/itraqchem.pdf
docs/articles/Figures/msnset.png
docs/articles/Figures/plot2d-figure.png
docs/articles/Figures/plotDensity-figure.pngOther possibilities
Orphan branches
Robert M. Flight
suggested
to use the good old original orphaned gh-pages branch solution.
svn ignore property
If one doesn’t use git-svn and manages git and svn
independently, then setting the svn ignore property with
% svn propset svn:ignore docs .should work. It doesn’t when managing both together.
Edit
I suggest to add a header to .gitignores indicating that gitignore
is generated automatically and any updates will be overwritten.
% cat .gitignores/all
# This is an automatically generated file. Ammend in .gitignores/ and
# read http://lgatto.github.io/branch-specific-gitignore/ for details
Makefile
.gitignoreEdit 2
And to ignore the .gitignores directory completely, suffices to add
it to the general excludes file. I prefer to keep it in git (but
not svn, and ignore it when building the package bundle) to keep track
from what I ignore.
$ cat .git/info/exclude
# git ls-files --others --exclude-from=.git/info/exclude
# Lines that start with '#' are comments.
# For a project mostly in C, the following would be a good set of
# exclude patterns (uncomment them if you want to use them):
# *.[oa]
# *~
.gitignores