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:

  1. 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.
  2. 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.
  3. You then need to review your notes regularly and either update them, file them or trash them.

My setup

I organise my notes into four files:

  1. inbox.org where all my note taking goes by default.
  2. gtd.org which contains my projects, the things I am currently doing.
  3. tickler.org for organising time-definite things – usually meeting agendas.
  4. someday.org which 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 C-c C-k.

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%?")
    

Sync client

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:

  • entr to watch a folder and run a command when it is modified.
  • rclone to sync files with the cloud.
  • systemd to run their combination as a daemon using a sync-client.service file.

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:

  • ExecStartPre Before starting the daemon, I want to sync my local copy with the remote one, which is the up-to-date one.
  • Type=simple Because my systemd was complaining.
  • Wants/After=network This 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 entr and 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:

  1. A bash script that runs the entr/rclone commands.
  2. A systemd service 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:

  1. test to check what files will be synchronised.
  2. once to upload my local directory to the cloud.
  3. start to pull the cloud version onto my local machine.
  4. Without arguments, this runs entr which 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 org-drive using 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

Caveats

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.

The 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.

Final words

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