Hexo git deployer removes commits history? Let's do something about that!
I have found Hexo a great tool for building a blog and apply many well-known software development principles. One of them is automation. This is why I have decided to integrate this blog with Travis CI to perform a deployment to GitHub pages. It was a great decision, however a few days later I have noticed one significant issue - deploying a new version of the blog from the CI server caused removing all commits from master
branch and starting with initial commit over and over again. It took me a while to find working solution to this problem. This blog post explains a simple solution to this problem.
Why does hexo deploy
removes the history in the first place?
Let’s start with understanding what actually happens. When you run hexo deploy
[1] command for a git deployment option, Hexo creates a hidden folder called .deploy_git
and it copies generated files from the public
folder to it. Next, it initializes git repository (if it does not yet exist) that targets Hexo’s remote deploy branch and it executes git push --force
from this folder to a repository and a branch you have defined in the _config.yml
[2] file.
deploy:
type: git
repo: [email protected]:wololock/wololock.github.io.git
branch: master
If you build and deploy your blog from your local computer and you never delete (or accidentally lost) your blog source code, you may never face this issue. When you do it from the workspace that does not get wiped, then the folder .deploy_git
with it’s full history exists and hexo deploy
pushes only those files that were actually modified. When you move to CI server like Travis CI, this is not true anymore, because it executes build with the clean workspace and the fresh clone of the repository. In this case .deploy_git
folder simply does not exist and gets recreated from scratch.
How to deploy and keep the history then?
The solution I have found working for me well is fairly simple. Previously my .travis.yml
file part responsible for the deployment looked something like this:
deploy:
skip_cleanup: true
provider: script
script: hexo deploy
on:
branch: develop
It simply triggered hexo deploy
whenever I pushed changes to develop
branch. In this case it ended up creating a new .deploy_git
folder and force pushing an initial commit to the GitHub repository. Then, I have made a small improvement - I’ve created a short bash script instead.
#!/bin/bash
if [ -d "./.deploy_git" ]; then
echo "Removing .deploy_git folder..."
rm -rf ./.deploy_git
echo "Folder removed."
fi
# Initialize target with currently deployed files
git clone --depth 1 --branch=master https://github.com/wololock/wololock.github.io.git .deploy_git
cd .deploy_git
# Remove all files before they get copied from ../public/
# so git can track files that were removed in the last commit
find . -path ./.git -prune -o -exec rm -rf {} \; 2> /dev/null
cd ../
if [ ! -d "./public" ]; then
hexo generate
fi
# Run deployment
hexo deploy
This script does exactly what it says in the comments:
It clones
master
branch from remote repository to.deploy_git
to get existing commits history.Then it removes all non-git objects repository files from
.deploy_git
so copying files back frompublic
folder will track deleted files.And finally - it executes
hexo deploy
command that does the regular deployment.
And the last but not least, here is what deployment configuration part looks like after introducing deployment bash script:
deploy:
skip_cleanup: true
provider: script
script: sh deploy.sh
on:
branch: develop
Thanks to this solution I was able to keep the history of site updates and to track changes of files that were actually modified with the given site update.
Final words
I hope you find this post useful. It describes solution for Hexo + Travis CI + GitHub use case, but it can solve problems that other similar static site generators may have when running from CI server environment.
0 Comments