Netlify deploys fail with an error like
fatal: could not read Password for ...: No such device or address
fatal: could not read Username for ...: No such device or address.
The Solution: Git Subtree
You can find a hint to a solution in the Netlify blog post How Our Build Bots Build Sites:
If you have submodules that are in private repositories, or private node modules, or other git repositories that you need separate access to - well, our build environment only has access to them in case you send the authentication raw materials our way somehow. In general we don’t advise this - for instance: use subtrees instead of submodules and create a copy of the private node modules before sending us a deploy.
So, git subtrees allow to publish Hugo sites with private themes on Netlify.
How to do it?
You can copy a public theme into a private repository and then add the private repository as git subtree to your site.
The big picture looks like this:
To start, create a new repository.
Then, copy the public theme repository into the new repository with the
git clone --bare and
git push --mirror.
Next, create a git subtree within your site with
git subtree add.
Whenever you now
git push your site, the subtree content will be included
and Netlify can deploy it.
To push changes back to your private theme repository, use the
git subtree push.
A Step-By-Step Guide
Here is a step by step guide. We will create a custom theme called mycapsule based on the Capsule theme and use it in a Hugo site called mysite. I used my Bitbucket account while creating this example. Please change the repository URL accordingly.
# change repo url accordingly export REPO_URL=https://firstname.lastname@example.org/mitjamartini/mycapsule.git
1. Create a new repo via the Github, Gitlab or Bitbucket UI.
This is how it looks on Bitbucket:
2. Make a copy of the upstream theme and push it into your newly created repository.
git clone --bare https://github.com/sudorook/capsule.git cd capsule.git git push --mirror $REPO_URL cd .. rm -rf capsule.git
3. Add your private theme as a subtree to your Hugo site:
cd mysite git subtree add --prefix themes/mycapsule --squash $REPO_URL master # now change the theme in config.toml to theme = "mycapsule" git add . git commit -m "use mycapsule theme via a git subtree" git push
4. Push changes back to your theme repository.
The changes are now pushed to your hugo site repository. To push your theme changes
to your theme repository as well, use the command
git subtree push. The use of
git remote is optional but nice as it simplifies the push command.
git remote add mycapsule $REPO_URL git subtree push --prefix=themes/mycapsule mycapsule master
Merging in changes from the upstream public theme repository.
You can use a separate working copy for your theme to merge in changes from upstream. To do so, clone your private repository into a separate working directory. Then, add the upstream theme repository as a remote. Finally, pull from upstream and push the merge into your private repository:
git clone $REPO_URL cd mycapsule git remote add upstream https://github.com/sudorook/capsule.git git pull upstream master # creates a merge commit git push origin master
Conclusion and Credits
This is a bit complicated at first but simple to use day to day. After the initial setup, the theme can be changed and pushed to the Hugo site repository without worrying about submodules or subtrees.
Even if you just go with a public theme you should probably still first make a copy of it. Having a copy right from the start is easier than Moving a Git Subtree to Its Own Repository later on.
Two sources have been helpful:
- StackOverflow Question GitHub: How to make a fork of public repository private?
- Nicola Paolucci: Git subtree: the alternative to Git submodule.