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