Over the last few days, I’ve been working out how to get FOAM to automatically sync my notes to their respective Git repositories when I save them in the editor. Here are my findings.

Why?

I keep notes on different areas of my life siloed from each other. This allows me to completely prevent commercially sensitive stuff from my work life leaking onto personal devices and prevents me from accidentally publishing something personal (e.g. my shopping list for this weekend) to my public digital garden. Using FOAM in multi-root mode I can then transparently load all of these different sets of notes into the same workspace and connect relevant things together (for example, I could link to a public note I made about MySQL in a private work-related note I made to myself about debugging a client issue).

diagram showing three way sync between my different markdown notes repositories hosted via different git services

Separating my notes into different repositories allows me to ensure that work stays at work and that I don’t publish something embarassing in my digital garden.

What I Tried First

The FOAM project maintainers recommend using GitDoc as a turn-key solution for getting git auto-sync. GitDoc will monitor your project and automatically push your changes when you save files. However, I have so far only been able to get GitDoc to monitor one project at a time - whichever folder you open first inside VSCode. I have a feeling this might just be user error but I’ve spent a long time tweaking with my config and I couldn’t get any further so I looked at another solution.

My Solution

In the end I’ve sort of rolled my own sync solution using git-sync and the save-and-run vscode plugin.

Firstly git-sync is a bash script that automatically commits, pulls and pushes your depos (basically what GitDoc does in the background). I installed it to my local bin in my user directory:

mkdir ~/bin/git-sync 
wget -O /bin/git-sync https://raw.githubusercontent.com/simonthum/git-sync/master/git-sync
chmod +x ~/bin/git-sync

Next we enable git sync for each of the projects we want to sync by setting a git config value. You specify the name of the branch you are interested in. For my notes at least, I don’t do anything fancy with branches so I just use main:

cd ~/foam-workspace/public-notes
git config --bool branch.main.sync true
cd ~/foam-workspace/private-notes
git config --bool branch.main.sync true

By default git-sync will only commit and sync if it finds that an existing file has changed. If it detects the addition of new files that aren’t already in git it will error. You can optionally run git config --bool branch.main.syncNewFiles true to override this behaviour if you wish but be aware that if you add a new file to the wrong repo it might be immediately synchronised (maybe don’t turn this on if you have a build process that publishes your changes hooked up to the repo).

Now, we install the save-and-run vscode plugin and configure it.

Assuming that you already have a VSCode workspace set up with the note repositories that you want to sync open, you can bring up the workspace settings.json (CTRL + SHIFT + P > Preferences: Open Workspace Settings (JSON)) and add something like the following to the settings section:

    "settings":{
        ... 
        "saveAndRun": {
            "commands": [
                {
                "match": "\\.md$",
                "cmd": "/home/user/bin/git-sync sync"
                }
                
            ]
        }
    }

This will run git-sync sync inside the directory that you are editing files from whenever you save a .md file. It will be run in a terminal in vscode so you’ll be able to see if something goes wrong and intervene if needed.

The final step is to enable the plugin by hitting CTRL + SHIFT + P > Save and Run: Enable