I manage my Jekyll blog in a Git repo. My publication process uses 2 branches:
master
contains all production contentfeature/newposts
has the new blog posts, ready to get published, one commit per post
To publish an existing post:
- I check the to-be-published post in the
feature/newposts
branch - Then, get the associated commit
- And cherry pick it in the
master
branch - Finally, I push
While not that slow, this is very boring. This post explains how I "automated" the above process using bash magic.
Date
Bash users know how to get the current date:
date
This outputs:
Sun Aug 5 12:15:23 CEST 2018
However, the Jekyll blog post filename is formatted as 2018-08-05-xxx-yyy-zzz.adoc
.
Having a look at the man page, the relevant syntax is:
date +'%Y-%m-%d'
It outputs the expected string:
2018-08-05
Path
To get the path of a file in a Git tree, one needs to use the git ls-tree
command:
git ls-tree -r feature/newposts | grep `date +'%Y-%m-%d'`
This yields:
100644 blob 2cb14109c9a41b67609b93a9fea904735d082a5c _posts/2018-08-05-spring-boot-integration-intellij-idea.adoc
Note that the hash is the blob’s hash, and not the commit’s hash. From that point, there are two ways:
- Get the commit with this blob
- Get the commit with this path
For no real reason, I chose the second option.
To get the path only, the output needs to be cut:
git ls-tree -r feature/newposts | grep `date +'%Y-%m-%d'` | cut -c54-
This now correctly prints:
_posts/2018-08-05-spring-boot-integration-intellij-idea.adoc
Commit
git log
is the command to get the commit for a specific path.
It allows a branch option.
git log feature/newposts -- $(git ls-tree -r feature/newposts | grep `date +'%Y-%m-%d'` | cut -c54-)
This outputs:
commit dcc9dc60dc7ee615f35703c9a8e696d2dcae6d41 Author: Nicolas Fränkel <nicolas@frankel.ch> Date: Sun Apr 1 23:36:20 2018 +0200 Add Spring Boot integration in IntelliJ IDEA post Fix #25
To limit the output to the commit value, use the --format
option:
git log feature/newposts --format=%H -- $(git ls-tree -r feature/newposts | grep `date +'%Y-%m-%d'` | cut -c54-)
The result is:
dcc9dc60dc7ee615f35703c9a8e696d2dcae6d41
Cherry-pick
The final step is to cherry-pick the relevant commit. At this point, this is a no-brainer:
git cherry-pick $(git log feature/newposts --format=%H -- $(git ls-tree -r feature/newposts | grep `date +'%Y-%m-%d'` | cut -c54-))
Final touch
I didn’t find a way to cherry-pick
into a specific branch, so that it adds the commit to the current one.
The above command just needs to be padded with a checkout to the master
branch, and back.
git checkout master && \
git cherry-pick $(git log feature/newposts --format=%H -- $(git ls-tree -r feature/newposts | grep `date +'%Y-%m-%d'` | cut -c54-)) && \
git checkout -
As we’ve seen in an earlier post, if the snippet above is written in a bash script whose name starts with git-
and that is located on the PATH
, then it’s possible to invoke it through git:
#!/bin/bash
git checkout master && \
git cherry-pick $(git log feature/newposts --format=%H -- $(git ls-tree -r feature/newposts | grep `date +'%Y-%m-%d'` | cut -c54-)) && \
git checkout -
At this point, the script can be invoked like this:
git publish