How I Put My Mind Under Version Control

Using Github and command-line utilities to sync and version control my Zettelkasten

15.png

So I use Obsidian as my app of choice to curate my ZettelKasten.

I keep my vault on iCloud for storage and redundancy but on other machines like my firewalled work machine, I can't access iCloud but I can access GitHub. So I have my vault set up as a repository on GitHub. To keep all my notes, configs, and workspace settings in sync with my home machine when I leave the house I set up auto-syncing to GitHub that I can take advantage of anywhere. Here's how I did it:

Prepare Your Repository



0.

You need git installed, and this works seamlessly if you have your credentials cached so you do not need to enter your password on git push commands for more on caching FCC has a great article on this.

to store your credentials for your system you can use this command to be prompted for your credentials, enter them once, and have them stored for future git interaction:

16.png

1.

Next we need to make an empty repo on GitHub to host our ZettelKasten where we can push and pull changes, to across multiple machines, and have version control on our notes.

2.

We need to Ignore files that are unnecessary and could cause errors on other machines when we pull our files and configs from GitHub. If you work on a ZettelKasten with a team excluding the .obsidia/workspace file could also be a good idea as well as the custom CSS in the root directory if you have one. This would mean people are not overriding each other's personal settings unless you want to keep this consistent in the shared vault. Which files to exclude are up to you and your use case but for mine, the repo is private and only for myself so I need only a few files ignored to avoid issues.

3.

So now to make the .gitignore file to make git… well… ignore the files we don't care about:

17.png

4.

Now that we have the remote repo ready and we are ignoring local files that could cause issues if sent to GitHub, let's make our existing ZettelKasten a git repository so we have something to send to GitHub:

18.png

5.

Now push everything to the remote repository so we can pull it down from GitHub onto any machine. Make sure in the example below to just replace the URL with your GitHub Repository URL or you can just replace the parts of the URL in all caps with the values of your Username on GitHub and the name of the repository:

19.png

This will put your files on GitHub ONCE now any new changes to files or configurations need to be manually pushed to the remote repo with git commands manually. So now let's automate all the work.

Automating The Workflow


6.

First we need to write a script that will perform all of our actions for us. I make a shell script in my .local/bin/ directory (this works for Mac and Linux, Windows I'm not sure if this works the same with WSL/Gitbash):

touch creates the file named zk_sync and chmod +x makes the file an executable file, but we still need to say what shell will execute this file, and what exactly are the commands to be executed.

7.

The scripts contents to be executed when ran:

In case it needs to be said, you’ll need to update the string that is the absolute path to your local ZettelKasten repo. You can easily do this by using the terminal to go to that directory and just run the `pwd` command.

In case it needs to be said, you’ll need to update the string that is the absolute path to your local ZettelKasten repo. You can easily do this by using the terminal to go to that directory and just run the `pwd` command.

8.

WHAT THE SCRIPT DOES. You should never run a script without knowing what it does as it could easily be malicious and nuke your machine. So lets review its functionality line by line:

22.png

9.

So now that we have the script ready, enter CRON! We're going to set up a cron job to run this script automatically on a timer.

On Linux I used the tool cronie, but MacOS comes with cron installed already, to get into your list of current cron jobs:

23.png

my cronjob looks like this:

24.png

*/30 * * * * The first section is the timers, mine is set to run on every minute interval that is divisible by 30 i.e. 30 and 60 or 1:30PM, 2PM, 2:30PM, etc.

/Users/bryanjenks/.local/bin/zk_sync The second is what file is it executing (absolute path) which in this case is the script we made.

Finally, to make sure the job is quiet it is sending any script output (there shouldn't be any we used -q a lot) to >/dev/null 2>&1


Now any changes I make to anything in my vault are pushed to GitHub every 30 minutes with an ISO timestamp for the files with changes. If no changes are made, nothing happens.

I keep the repo private, and this way I always have my ZettelKasten available where ever I go and under version control with Git.

I hope someone else enjoys the workflow 🙂️


Quick Summary of What We Covered

A Quick Recap of the main points of this article:

  • Create a GitHub Repo
  • Make your current ZettelKasten a local Git Repo
  • Push that repo to your new fresh remote repo
  • Create a script to sync your local and remote repo's
  • Automate that scripts execution with Cron


Code?

If you would like all the example code used in the video / this article you can grab it:


Get the Code Here

Flexible Layouts With The Patchwork Package In R

Patchwork is a package for the R programming language that simplifies data visualization layouts through a simple math-like syntax.

1_ZU09JFA1ZtGkvvG18FDeZg.png

The Composer of ggplots

With Patchwork the task of combining and organizing ggplots is very easy and can produce ornate visualizations with simple code.

All charts here are made with sample data sets and are just used for example purposes.


Simple Chart Combinations


Vertically Stacked Charts

If i wanted to take a couple charts of mind and compare them next to each other either one above the other it may look something like this:

An Example of Code For a Top and Bottom Chart Combo With Patchwork

An Example of Code For a Top and Bottom Chart Combo With Patchwork

Looking at this code what we do is create 2 ggplots and assign each to their own variable, top and bottom respectively.

Conveniently named we can see where each is going to be placed in the final visual.

The simple Patchwork syntax is finding those 2 variables at the bottom and with a simple division sign saying that top should be divided by bottom.

The syntax is super transparent and intuitive with what it will do with the plots and how you might structure more advanced combinations later on. For now, the stacked visualization will look like

Top and Bottom Chart Stacking

Top and Bottom Chart Stacking

Horizontal Stacking

If you wanted to stack your plots horizontally its as simple as adding them together:

An Example of Code For a Left and Right Chart Combo With Patchwork

An Example of Code For a Left and Right Chart Combo With Patchwork

With the + operator you can add charts together flowing from left to right and we show this with the above defined variables conveniently named left and right:

Left and Right Chart Stacking

Left and Right Chart Stacking

It is also useful to know that using the | pipe operator you can equally divide the sections of the final aggregate visual. So if i ran this code:

Usage of the Pipe Operator |

Usage of the Pipe Operator |

My output would actually look like a 50/25/25 split between the charts:

The Pipe Operator Evenly Divides Space

The Pipe Operator Evenly Divides Space

Overflowing and Defining The Grid

So that is a quick way of putting some visualizations together, what are some more elaborate uses of Patchwork and some of its behavior?

If we add a bunch of charts together with the + operator would it just squeeze the plots together until there's no room left? We now know that the | will evenly divide available space between the plots, so the more we add the evenly divided space will get more cramped over time. With that known what does adding a lot of plots together achieve?

Adding a Lot of Plots Together

Adding a Lot of Plots Together

So Patchwork will try to keep the plots in a square grid shaped combination with the usage of + so if we have 4 plots we should expect a 2x2 grid square combo plot:

2x2 Grid Overflow Plot

2x2 Grid Overflow Plot

This is helpful so that at least with minimal tampering everything is somewhat visible and less squished than if we used the | to combine the plots.

You can imagine this grid behavior as plots moving into available slots in an assembly line fashion. The first row (slots 1 and 2) must be filled before flowing down to Row 2 to fill slots 3 and 4.

Lets say you what to redefine the dimensions of your grid so that you have 3 rows, and 2 columns (a 3x2 grid) and you want to fill the grid by columns not rows. You can imagine the assembly line filling in your grid from top to bottom slot 1, 2, then 3, and finally the top slot of column 2 for the 4th plot.

How do we achieve this with Patchwork syntax?

Overflow Grid Top to Bottom With 3 Rows

Overflow Grid Top to Bottom With 3 Rows

What we're saying is add + all the plots together and overflow the grid, but with plot_layout we define with nrow that we want the grid to have 3 rows, and byrow is asking the question "Should i fill each row first before moving down to the next?" and we're saying No, Fill each column first then move to the next:

Custom Grid Layout 3x2 with Vertical Flowing

Custom Grid Layout 3x2 with Vertical Flowing

Stacking and Packing

Overflowing the grid is useful but still, you say you want more granular control of the layout? Say no more, we can combine multiple operators to achieve this.

Some Layout Magic

Some Layout Magic

So what is going on here? You might be able to guess what this might look like by now, but just in case lets read it from inside out.

  • We're saying take the top chart and place the bottom chart below it in a vertically stacked combo
  • Then we have a combination of the left chart taking up the left half and the combo of top and bottom taking up the right half
  • And finally we take that 3 part combo chart and put the right chart underneath it to finish it off.

You can see how with some simple order of operations (we all remember the PEMDAS acronym from algebra right?) we can easily and logically control the layout of the plots. Lets see the fruits of our labor:

The Stacking and Packing Chart Output

The Stacking and Packing Chart Output

This isn't the prettiest example but you can see by this example the power and flexibility that Patchwork give you with your layouts.

HOWEVER! We left one important thing out, we need to name our Franken-Plot, but with so many pieces involved in this…. Patchwork Plot…. Sorry, I'll stop. With so many pieces how do we appropriately name the whole aggregate visual?

By adding one more thing:

plot_annotation to Name Your New Patchwork Child

plot_annotation to Name Your New Patchwork Child

plot_annotation will let us appropriately title the whole aggregate visualization in the top left:

Our Plot Is Done and Ready For The Big Time

Our Plot Is Done and Ready For The Big Time

Ugly visualizations aside you can see the gold of the Patchwork package shine through and the value it could provide you in your work with R.

Quick Summary of The Operators and What They Do

A Quick Recap of the various operators and functions covered:

  • + Add plots together, defaults left to right, overflows the grid
  • / Divide plots, Put Left hand side on top of right hand side
  • | Evenly separate plots into equal sized portions based on how many | are used: one | two | three produces 3 x 33.33% slots
  • ( & ) are used for order of operations "Do This First then the stuff outside of us"


Code?

If you would like all the example code used in the video / this article you can grab it here: