After getting lots of R CMD check --as-cran NOTEs, WARNINGs, ERRORs on the master branch, I eventually discovered the CRAN branch.
Q1. Does the CRAN branch correspond to the latest version available on CRAN, or is just an internal branch of yours when you're preparing a CRAN release?
Q2. I was surprised that the v2.3.3 tag/commit also gave errors. These errors turn out to be due to the R/zfRenderSeurat.R file - a file that is _not_ part of the CRAN release and therefore is not reported by the CRAN servers. I other words, the version tags does not appear to correpond to the CRAN versions.
Q3. What is in the master branch?
Q4. What is in the develop branch?
Q5. Which branch do you want PRs toward?
Hi Henrik,
A1. The CRAN branch refers to the latest version available on CRAN. This branch is the one that gets built into a package (R CMD build) and submitted to CRAN. Additionally, this branch will only be updated when a new version gets accepted, though not necessarily published, by CRAN (CRAN has to get the package from the people checking submissions, build binaries for Windows and macOS for multiple versions of R, and pushed to CRAN mirrors, so the CRAN branch may be updated before the CRAN repository is).
A2. Only the master branch gets tagged. While the numbers correspond to the latest CRAN release, we only tag the master branch as this is what devtools::install_github installs by default. Mainly, the only difference is the zfRenderSeurat file; we include this with our GitHub releases, but it's not CRAN-compatible, so it's not included in our CRAN releases.
A3. The master branch contains everything in the latest CRAN release, plus the zfRenderSeurat functions.
A4. The develop branch contains the latest bugfixes and minor features added to Seurat. Long-term developments go on their own branch (eg. loom).
A5. Generally speaking, PRs should go towards the develop branch. However, if you're working on a long-term feature (eg. loom), then PRs should go to that branch. PRs to other branches will be switched to develop and rejected if merge conflicts arise.
Hopefully this (rather crude) workflow helps explain our workflow.

Thanks for the explanation. The discrepancy toward CRAN releases is unfortunate. Why is "the zfRenderSeurat file ... not CRAN-compatible"?
It uses custom code that's not released on any CRAN-like repository, which CRAN prohibits for their packages. This code was used for Satija R, Farrell JA, Gennert D, Schier AF, Regev A. Spatial reconstruction of single-cell gene expression data. Nature Biotechnology. 2015; we include zfRenderSeurat in Seurat for historical purposes and easy finding (we are an academic lab, not a software development group), hence the need for a discrepancy between our GitHub and CRAN releases. With the exception of this file (and associated exports/collation), the master and CRAN branches are identical and git tags on the master branch correspond to new releases on CRAN itself.
There are CRAN-compatible workarounds to release R packages that are not on CRAN/Bioconductor - several CRAN packages use this framework already. I'd be happy to have a look at it if you can point me to that "custom code".
My main objective right now is that working with the branches containing R/zfRenderSeurat.R adds lots of friction when it comes to trying to contribute, e.g. each time you run R CMD check you're flooded with issues (e.g. https://travis-ci.org/satijalab/seurat/jobs/401783030) and you have to manually inspect the output rather than getting an "all OK".
PS. For me CRAN is all about supporting science and reproducible research and being a long-term archive regardless what happens to GitHub and maintainers future plans/intent.
Closing this issue for now as we've discussed similar issues elsewhere, and will follow up by e-mail