Where to place the gh-pages folder?

12 min. read

Caution! This article is 10 years old. It may be obsolete or show old techniques. It may also still be relevant, and you may find it useful! So it has been marked as deprecated, just in case.

It's 2012 and I officially switched to git (finally!) and it seemed natural to get an account in GitHub, because "that's what all the cool kids are doing". I like the fact that you can host your project's dedicated site on the repo, although it is done through Jekyll, GitHub's static-pages generator. Anyways, it means no databases, which means faster loading and less security issues/overhead, but has other limitations. For each problem, its tool.

As the site explains, you have to create a new branch in your project called gh-pages to store the contents of your site. When you push that branch to your GitHub remote repository, the server will build your static site from the files in the branch (that is, you should version-control and push everything but the _site folder).

This branch is not a normal branch though. It's an orphan branch. And, what is an orphan branch? According to git's manual:

Create a new orphan branch, named <new_branch>, started from <start_point> and switch to it. The first commit made on this new branch will have no parents and it will be the root of a new history totally disconnected from all the other branches and commits.

You create it using the command:

git checkout [-q] [-f] [-m] --orphan  [<start_point>]

Since I'm still new to git I can't totally grasp the implications of an orphan branch or its applications, although the git manual lists at least one:

This can be useful when you want to publish the tree from a commit without exposing its full history. You might want to do this to publish an open source branch of a project whose current tree is "clean", but whose full history contains proprietary or otherwise encumbered bits of code.

Now, when you checkout a branch in your local repo, your system's folder browser will switch to the contents of that branch. That is a bit confusing to me. Let me explain why.

Basically I am thinking of these two scenarios: repo folder and gh-pages in the same folder or in different folders.

Repo folder and gh-pages in the same folder

Let's say I have a local repo folder in my computer (or I clone it from GitHub). Now I want to have a dedicated site for my project in a branch called gh-pages. I follow the instructions to create an orphan branch, store my site in there, commit, and push to GitHub.

When I want to continue working on my project I checkout the master branch, make my changes and commit / push to GitHub. If I want to make changes to the site, I checkout gh-pages branch again, and so on.

So everything lives in ONE local folder of my computer, which shows different files depending on the branch I have checked out. But the problem is, every time I want to see the files of one of the branches in, say, Nautilus (Ubuntu's file browser), I have to do it through git. I can't click folders and open them, because they don't appear until I git checkout the branch.

Repo folder and gh-pages in different folders

The other scenario is: I have my local repo folder that contains my project's files, where I make changes to the code, commit and push to GitHub.

Now, instead of making a gh-pages branch, I make a gh-pages folder INSIDE my local repo folder (and add this folder to .gitignore).

I go to the gh-pages folder, clone my project in there, create a gh-pages orphan branch, paste in my site's files, commit and push. In the gh-pages folder, I keep checked into the gh-pages branch forever.

If I want to continue working in my project, I just switch to my local repo folder and make changes / commit / push to GitHub.
If I want to continue working on the project's site, I switch to the gh-pages folder and make changes / commit / push to the gh-pages branch in GitHub.

So I now have a "project" living inside my project, just for gh-pages. Everything is organized, and if I browse the local repo folder with Nautilus (or any other system's file browser), I will be able to see both my code files and my project's site files. If I have several projects, each with their respective site, everything can be kept organized.

The problem is, I am saving my project files twice, am I not? One in my working repo, and the other in the master branch of the cloned repo living inside the gh-pages folder (just that it will never be updated).

Also, if you had files in the gh-pages branch that are also in the master (because you are using some of them in your site as demos, for example), you would have to use the first approach. Lea Verou talked a year or so ago about how to easily keep gh-pages in sync with master because she was having that exact problem. The links in the comments are very enlightening too. And there is even another different way to do it by checking out single files instead of the whole branch. All this is still too obscure to me, and I will need time to internalize it.

How I do it

Maybe the answer is so obvious that you are all laughing at me at this moment. Whatever the answer is, I chose the second approach. I think it's less confusing that way, and since I won't be updating the master branch of the cloned repo, but just the gh-pages branch, seems like it'll be as if the master branch didn't exist at all.

More important is the fact that when I work on a project, I'm usually also updating the project's site at the same time, so I need to have both folders opened. Otherwise I'd have to change from one branch to the other constantly and I find it very prone to error, or simply an uncomfortable workflow. That's the way I work, maybe your workflow is different and this is not an issue for you.

Now, to avoid having the files repeated twice, what I do is to clone the GitHub repo just after I create it, and before uploading any file to it. But this is probably something that will only be viable for my personal projects.

My Workflow

I do this only once: just after creating my repo:

  • Enter repo and add gh-pages to .gitignore.
  • Create folder gh-pages
  • Clone the repo git clone <remote repo URL> gh-pages.
  • Follow the instructions in the GitHub website:

$ cd gh-pages
$ git checkout --orphan gh-pages
$ git rm -rf .

The following step is better done in the GUI (temp is a temporary folder where you have your site files):

$ cd ..
$ mv temp/* gh-pages
$ rm -rf temp

Now, you can start version-controlling your site files:

$ cd gh-pages
$ git add .
$ git commit -a -m "First pages commit"
$ git push origin gh-pages

I'm doing a first pages commit because NOW I will start version controlling my site files. I normally work on a site on my Dropbox when I am in the initial phases, and only when I have something that makes sense do I start control versioning. It's better for my mental health if I do it that way :-).

If there is a better way of doing this, let me know!