Setting up a sync client for org notes
I use Get Things Done (GTD) to organise my notes. It is a very popular method amongst Emacs users as it works well with Org captures. However, I used to run into a simple issue: synchronisation between my work machines. By combining a few small utilities, I implemented a Linux-minded sync client for my notes.
Getting things doen
I am not a good follower of productivity methods but I liked GTD for its simplicity. I am not following the whole thing but adding bits of it in my day-to-day work – in a similar way I learned Emacs. The core ideas of GTD are:
- When you think of something to do, determine how long it would take. If it takes less than 2 min., do it now. Otherwise make a task.
- Tasks are not just notes; they are actions. For example, don’t write down: “Look into different search methods;” but: “Compare methods x/y/z.” For large tasks, you will create projects.
- You then need to review your notes regularly and either update them, file them or trash them.
I organise my notes into four files:
inbox.orgwhere all my note taking goes by default.
gtd.orgwhich contains my projects, the things I am currently doing.
tickler.orgfor organising time-definite things – usually meeting agendas.
someday.orgwhich is the repository of the things I want to do but I am not working on right now.
What lead me to GTD is I can configure Emacs with Org capture templates to seamlessly take notes. Org captures are a key sequence which will open a frame in which you can write and will then be refiled to the appropriate file. You can call up a capture with
C-c C-c, which opens a menu in which your capture templates are listed. You can then save with
C-c C-c or abort with
Org templates define a structure for different note taking functions, I use three:
TODO: To keep track of tasks I want to action, I add a timestamp to remember how long ago I said I was going to do it.
("t" "Todo [inbox]" entry (file+headline "~/gtd/inbox.org" "Tasks") "* TODO %i%? %t")
Tickler: I add a deadline to the task and save it directly in the appropriate file.
("T" "Tickler" entry (file+headline "~/gtd/tickler.org" "Tickler") "* %i%? \nSCHEDULED: %^t\n")
Note: For things I just want to keep track of. (I may need a better system at some point.)
("n" "Note [inbox]" entry (file+headline "~/gtd/inbox.org" "Tasks") "* %i%?")
The issue I have is I have two offices and sometime work from home. This means at least three computers, all with their own versions of my work.
I use Git extensively for versioning my code and writing papers. This already gets me into trouble as I regularly forget to
push. But, for code projects, I can always merge them back later.
My notes have slightly different requirements: I never work on two computers at once; revisions make little sense – and are messy; I want to keep the “stress-free” premise of GTD. Git was not cutting it in this case.
I came across this post a while back, and it looks like the solution to my problems. In it, the author implements a Dropbox-like sync client using Linux utilities:
entrto watch a folder and run a command when it is modified.
rcloneto sync files with the cloud.
systemdto run their combination as a daemon using a
Why this post?
Well, the whole idea of the setup presented above is that it works for a single machine. I need to sync across multiple machines. I turn off or at least suspend my computer when I leave work, so that is a good hook. I need to add the following to the service file:
ExecStartPreBefore starting the daemon, I want to sync my local copy with the remote one, which is the up-to-date one.
Wants/After=networkThis service needs the network to be active, and is started after the network connects.
Because I need two-way sync, I wrote a quick bash utility which runs the sync down on boot – so my files get synced with the remote. Then it runs the
rclone combo so my local changes are uploaded immediately.
Setting up a sync service
To set up the sync service, I will create two files:
- A bash script that runs the
systemdservice file that will run at startup.
The first file is a simple utility to which I can pass arguments to decide which action to do. I have four:
testto check what files will be synchronised.
onceto upload my local directory to the cloud.
startto pull the cloud version onto my local machine.
- Without arguments, this runs
entrwhich will watch the files in my GTD directory.
The service file will simply run
<sync scrip> start at startup – more precisely after the network connects. Then it will run
<sync script> to watch the GTD directory. And that’s it.
Installing a sync’d GTD directory
I have created a blank project online, though it would be better to integrate the scripts to your existing workflow. You need to clone it into your home folder.
At this point, delete the
.git folder – unless you want to sync across git too. Make the bash script executable:
$ chmod +x org-gtd-sync.sh
Assuming you have created your
rclone, you will want to create your remote GTD directory:
$ ./org-gtd-sync.sh once
Finally, you need to activate the service:
$ cp org-gtd-sync.service ~/.config/systemd/user/ $ systemctl --user enable org-gtd-sync.service $ systemctl --user start org-gtd-sync.service
If you want to add files to the watched folder (happened to me with the
.org_archive), you need to upload them to the cloud folder. Otherwise, they will get deleted every time the service loads.
test parameter in the script is wonky. Realistically, I should build the sync function in a single place so
test would make actual sense.
If you only care about your active notes, you could filter only the org files:
19 find "$ORG_DIR" -name "*.org" | entr -r rclone sync "$ORG_DIR" "$REMOTE:$ORG_REMOTE_DIR"
I might actually do that now that I have a separate repo with the code.
I hope this benefits someone, flick me an email if something goes wrong – though you should check you distro’s docs first. I always find it a pleasant experience to create something out of “do-one-thing-well-tools.” I have been sticking with this setup for quite a while now, with some modicum of success.
$ wc -l gtd/* 225 gtd/gtd.org 957 gtd/gtd.org_archive 51 gtd/inbox.org 507 gtd/inbox.org_archive 16 gtd/org-gtd-sync.service 21 gtd/org-gtd-sync.sh 642 gtd/someday.org 285 gtd/someday.org_archive 7 gtd/tickler.org 241 gtd/tickler.org_archive 2954 total