This may be of interest for you if you host project pages in a GitHub Pages branch (or in a similar setup) and need to derive the contents of the branch from the project itself (e.g., artifacts, documentation, ...).
The gh-pages
branch in GitHub is special -- its contents are interpreted as a Jekyll or HTML website and provided on http://username.github.io/projectname. The source files, on the other hand, are supposed to be located in another branch, e.g., master
, with possible further feature/hotfix/... branches. If the contents of the gh-pages
branch depend on the contents of the "main" branches, there are several obvious options for organizing this:
- Switching between branches: One checkout, current branch is chosen via
git checkout
. - Side by side: Two checkouts, but with different checked-out branches. (@chrisjacob discusses a setup using a "grand-parent" directory.)
- Contents of the
gh-pages
branch are contained redundantly in a subdirectory. (Usesgit subtree
, described here, here, here, here, and my favorite approach until now). - Create Git tree and commit objects manually via plumbing.
None of them are really satisfactory. Perhaps this can be done better.
- Clone the
gh-pages
branch of the working copy into a subdirectory, say,gh-pages-dir
.- This is a two-stage setup, the checkout of
gh-pages
has itsorigin
pointing to the working copy. Similar to submodules, but simpler.
- This is a two-stage setup, the checkout of
- Ignore this subdirectory via
.gitignore
- Initial state of the
gh-pages
branch is an orphaned branch, completely unrelated to all other branches - For deployment, first a merge from
master
is performed in order to connect the histories. (This step is optional but could be desirable.) - Commits to
gh-pages
can be performed bycd
-ing togh-pages-dir
and performing regulargit
operation - The main checkout is set as the
origin
remote of thegh-pages-dir
sub-repository. This avoids any remote access for preparing a deployment, agit push
in the main checkout updates both regular and thegh-pages
branches
Clone the repo and run make
, a subdirectory test
is created. Or head over to the latest test result on Travis CI. Also, the website http://krlmlr.github.io/git-subbranch/
is generated by replacing this section by the output of make
-- the command make push_deploy
takes care of everything.
The file functions
defines a few verbs, the interesting ones have a with git_subbranch_
prefix:
ignore
: Is supposed to run only once, adds thegh-pages-dir
to.gitignore
.init
: Initializes agh-pages
branch, sets up the repository for this branch ingh-pages-dir
and links this repository to the main checkout.link
: Links the current state of themaster
branch with thegh-pages
branch (a trickygit merge
).commit
: Commits all files ingh-pages-dir
(just agit add -A
).push
: Updates the localgh-pages
branch from the repository ingh-pages-dir
.
In day-to-day use, the usual sequence of commands will be link
-> commit
-> push
, although they can be interchanged arbitrarily. In particular, if you never link
, the two branches remain completely separate.
- Seamless operation
- No need to maintain a "clean" state of the repository just to look at the
gh-pages
branch - Clear connection between regular and
gh-pages
branch via history (optional)
- Self-contained
- Clear connection between regular and
gh-pages
branch via history (optional)
- Separation of concern
- No waste of space
- Uses high-level Git operations only
- No tight coupling between
gh-pages
branch and main branch
The setup described here seems to work for me, although this site (and the commands presented here) is in a very early stage. I hope others find this useful too, and this sketch evolves into a more mature tool.