kuniga.me > NP-Incompleteness > Writing Posts
01 Sep 2021
This is a meta post to describe my flow for writing posts. When I moved to static Github pages over a year ago, I didn’t have a flow that I was satisfied with but I’ve recently settled in one which I think is worth documenting.
It’s worth recalling that in static Github pages I write in markdown and manage them using git (and Github).
The overall idea is to be able to write a post in draft mode, which is hidden from view and only when it’s ready I merge it on master, which is automatically picked up by Github pages and made public.
I usually have a bunch of topics I’d like to write about at one time, so I keep these early stage drafts as Google docs, which are mostly a collection of links and some comments.
Once I have enough confidence on it becoming a future post, I move to markdown.
In the past I’d keep an un-committed markdown files plus images for the posts, occasionally backing them up by copying them to Dropbox.
Needless to say it’s a subpar flow. I was really looking for a way to use git to backup my changes but didn’t want them to show up in my repository while in development.
I started looking for private branches but they don’t exist. An alternative was proposed in this Stack Overflow answer [1]. The idea is to keep a private mirror of the main repo and commit only to the private one, occasionally syncing with the public.
Suppose the name of our main blog repository is blog
.
Github supports creating private repositories for free. Let’s call it draft-blog
.
Here we copy the steps from the Github docs [3].
Create a bare clone of the repository:
Mirror-push to the new repository:
Remove the temporary local repository you created earlier.
A git remote is basically an alias for the URL of the remote repo. When we use git clone
, it adds a default alias called origin
, which points to the original repo. We can inspect via git remote -v
:
Note we have one entry for read (fetch) and one for write (push).
We want to add another remote that points to the public blog, that is git@github.com:exampleuser/blog.git
, and name it public
:
If we type git remote -v
we should see 4 entries now:
Before we start writing, we create a branch. For this very post I created one called post-writing
:
NOTE: It’s important we create branches off the master
branch (we’ll see why later), so always do git checkout master
before creating a new branch.
I usually write a bit every other way. When I’m done, I simply create a dummy commit and sync to a similarly named branch in the private repo for backup:
Since I always push to a branch to the same name on remote, I set the push
behavior to current
, which pushes the current branch to a branch of the same name in the remote [4]:
So we can simply do:
Once the post is ready for publishing, we want to merge into the master, but we don’t want all those dummy backup commits polluting the logs.
This Stack Overflow answer [2] provides a way to squash all the commits from a branch into a single one:
Let’s analyze the second command:
Simply returns the current branch name post-writing
. Wrapped in $()
means it’s treated as a variable, thus
is really
The command above returns the <hash>
of the commit that is the lowest common ancestor to both master
and post-writing
. Finally we do
This will set the current index back to that ancestor commit and the changes from post-writing
relative to that ancestor will show up as un-committed changes.
This command assumes post-writing
was created off the master
. It it was created off some other branch foo
, resetting the index would include changes from foo
as well. Hence the note in the Writing section.
To simplify things, we can alias the second command as compress
:
Now we can merge it into master:
Finally we can make the post public by pushing it to the public remote:
I usually want to fix typos or reword phrases after the post has been published. For this flow I don’t bother creating branches nor squash commits and do all from the master
branch in draft-blog
.
I only use Git for basic stuff (at work we use some flavor of Mercurial) and whenever I have to do some operation I’m not used to, Git gives me impostor syndrome.
I think I got a good handle of working with remotes through this process of trying to document my workflow. Having to setup another remote made and looking into different push
behaviors [4] made things a lot clearer.
Though it’s worth noting my flow is super simple because I mostly write in one computer (occasionally I also write in a Linux machine) and each post is its own file, so conflicts are almost non-existent.