XM Cloud is a live evolving platform – the development team releases new base images almost on a weekly basis, and new features are coming to the product regularly, which gets reflected in the underlying dependencies, as well as public starter kit templates such as XM Cloud Foundation Head Starter Kit.
At the same time XM Cloud professionals and enthusiasts and of course – the partners, are building their own starter kits based on publicly available templates provided by Sitecore. I alone have made more than a couple dozen personal improvements over the base starter kit that I am using almost on a daily basis. More to say, here at Perficient I am involved in building our brilliant JumpStart solution that comes as the essence of the company’s collective experience, with our best XM Cloud and Headless developers bringing and documenting their expertise as a part of the solution. The question comes to how to stay in sync with ever-coming changes and what would the best strategy for it?
One such strategy proposed was using a local copy of Foundation Head with semi-automating syncs using software called WinMerge. Despite finding this approach interesting and worth consideration, it does not fit the goals of Perficient XM Cloud JumpStart and is more suitable for smaller or personal repos. The fork-based solution is what seems to be the right path for JumpStart, retaining the ability to pull the latest features from the public template and merge them into its own private starter kit with minimal effort. And of course – being able to pull request back into a public repository, since we’re acting in the open-source community.
The problem that arises here is – Foundation Head is a public template repository on GitHub, and GitHub forking is done in such a manner that you can only fork public repositories into other public repos. We need a private repo with the ability to centrally control contributors’ access with SSO, GitHub Enterprise offers all that, but forking needs to get resolved first.
So here’s the walkthrough I keep in mind, simplified: I need to create a new private repo, clone the original repo locally, set up an additional remote, a new private would be an origin, and so on. Below are the steps in detail.
First of all, we need to create a private repository, in my case, it will be called JumpStart, as we normally do with GitHub, and clone it, but with bare flag option:
git clone --bare
A bare repository is a special type of repository that does not have a working directory. It only contains the Git data (branches, tags, commits, etc.) without the actual project files. Bare repositories are typically used for server-side purposes, such as serving as a central repository for collaboration or as a backup/mirror of a repository. It creates a new bare repository in the current directory, cloning all branches and tags from the source repository.
cd public-repo.git git push --mirror
This command is used to push all branches and tags from your local repository to a remote repository in a way that mirrors the source repository. In the context of creating and maintaining a mirror or backup, you would typically use this command to push changes from your local bare repository (created with git clone --bare
) to another remote repository.
So far so good. After mirroring, let’s clone the private repo so that we can work on it, as normal:
git clone cd JumpStart # do some changes as a part of normal workflow git commit git push origin master
Now, the interesting part: pulling new latest from the public template repo:
cd JumpStart git remote add public git pull public master # this line creates a merge commit git push origin master
Awesome, your private repo now has the latest code from the public repo plus your changes.
Finally, create a pull request from our private repository back to that origin public repository. With the GitHub UI of the public repository, create a fork (using “Fork” button at the top right of the public repository). Then:
git clone cd xmcloud-foundation-head git remote add JumpStart .git git checkout -b pull_request_yourname git pull private_repo_yourname master git push origin pull_request_yourname
Now you can create a pull request via the GitHub UI for public-repo.