Post

Foolproof Git Sync for Logseq DB

Foolproof Git Sync for Logseq DB

Logseq 2 is database-based and does not have a built-in Git plugin yet.

Running git pull before opening Logseq and git push after closing it in the terminal works, but doing it manually is annoying and easy to forget. If you write notes on another computer and forget to pull first, your notes get out of sync. Fixing Git merge conflicts in database files is messy and can break your notes.

To sync your Logseq notes to a Git repository automatically, we use two tools:

  1. A desktop shortcut: Syncs notes when you open and close Logseq (pulls before it opens, pushes after it closes).
  2. A systemd timer: Syncs notes at regular intervals (every 5 minutes) while Logseq is open.

These might look like two different ways to sync your notes to Git, but they actually complement each other. The shortcut syncs at the start and end of your session, while the timer syncs your work while you write.

Because Logseq DB stores everything in an SQLite database file (db.sqlite), Git conflicts are hard to fix. Using both together gives you a completely automatic, foolproof sync.


Part 1: Patch the Logseq Desktop Shortcut

Make sure the first time you open Logseq app, the script is already executed. If any changes are present in the Git repo, the app won’t start.

Run this script once to patch your desktop shortcut:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#!/usr/bin/env bash
set -euo pipefail

# Path to your logseq git repository (defaults to ~/logseq)
REPO_DIR="${1:-$HOME/logseq}"

# Check if repo exists
if [ ! -d "$REPO_DIR/.git" ]; then
    echo "Error: Logseq git repository not found at '$REPO_DIR'." >&2
    echo "Please clone your Logseq notes repository first: git clone <repo-url> '$REPO_DIR'" >&2
    exit 1
fi

# 1. Find Logseq desktop shortcut
DESKTOP_FILE=$(find ~/.local/share/applications -iname "*logseq*desktop" 2>/dev/null | head -n 1)

if [ -z "$DESKTOP_FILE" ]; then
    echo "Error: No Logseq desktop shortcut found in ~/.local/share/applications" >&2
    exit 1
fi

# 2. Extract the first Exec command up to %U
FIRST_EXEC=$(grep -m 1 "^Exec=" "$DESKTOP_FILE")
ORIGINAL_CMD=$(echo "$FIRST_EXEC" | sed -e 's/^Exec=//' -e 's/[[:space:]]*%[uU].*$//')

# 3. Formulate the wrapped Exec command
NEW_EXEC="Exec=bash -c 'cd $REPO_DIR && if [ -n \"\$(git status --porcelain)\" ]; then notify-send -u critical \"Logseq\" \"Uncommitted changes found in repository. Resolve them first.\"; exit 1; fi && git pull --rebase origin master && { $ORIGINAL_CMD \"\$@\"; cd $REPO_DIR; git status; git add -A; git commit -m \"Auto-sync: \$(date)\" || true; git push origin master; }' _ %U"

# 4. Backup original file and replace only the first Exec line
cp "$DESKTOP_FILE" "${DESKTOP_FILE}.bak"
awk -v new_exec="$NEW_EXEC" '!done && /^Exec=/ { print new_exec; done=1; next } { print }' "$DESKTOP_FILE" > "${DESKTOP_FILE}.tmp" && mv "${DESKTOP_FILE}.tmp" "$DESKTOP_FILE"

# 5. Refresh desktop cache
update-desktop-database ~/.local/share/applications
echo "✓ Updated $DESKTOP_FILE"

When you launch Logseq, the shortcut first checks your Git repository. If any uncommitted changes are present, it stops immediately and shows a desktop notification so you never corrupt your database. Otherwise, it pulls the latest notes from the remote repository before Logseq starts. Once you finish your session and close Logseq, the shortcut automatically stages your new edits, creates a commit with the current timestamp, and pushes everything to the remote repository.


Part 2: Systemd Timer for Background Sync

If you keep Logseq open for hours or days without quitting, the shortcut cannot push your changes. A systemd timer fixes this by syncing in the background.

1. Create the sync script

Save this script as ~/.local/bin/logseq-sync:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#!/usr/bin/env bash
set -euo pipefail

REPO_DIR="$HOME/logseq"

if [ ! -d "$REPO_DIR/.git" ]; then
    echo "Error: Logseq git repository not found at '$REPO_DIR'." >&2
    echo "Please clone your Logseq notes repository first: git clone <repo-url> '$REPO_DIR'" >&2
    exit 1
fi

cd "$REPO_DIR"

# Exit if offline
git ls-remote --exit-code -h origin &>/dev/null || exit 0

# Commit local changes if any
if [ -n "$(git status --porcelain)" ]; then
    git add -A
    git commit -m "Auto-sync: $(date)" || true
fi

# Pull and push
git pull --rebase origin master 2>/dev/null || true
git push origin master 2>/dev/null || true

Make it executable:

1
chmod +x ~/.local/bin/logseq-sync

2. Create the systemd service

Save as ~/.config/systemd/user/logseq-sync.service:

1
2
3
4
5
6
[Unit]
Description=Logseq Git Auto-Sync

[Service]
Type=oneshot
ExecStart=%h/.local/bin/logseq-sync

3. Create the systemd timer

Save as ~/.config/systemd/user/logseq-sync.timer:

1
2
3
4
5
6
7
8
9
[Unit]
Description=Run Logseq Git Sync every 5 minutes

[Timer]
OnCalendar=*:0/5
Persistent=true

[Install]
WantedBy=timers.target

4. Enable and start the timer

1
2
systemctl --user daemon-reload
systemctl --user enable --now logseq-sync.timer

Check its status:

1
systemctl --user list-timers logseq-sync.timer

Summary

The desktop shortcut covers your session boundaries by pulling before Logseq opens and pushing when it exits, while the systemd timer protects your work in between by syncing every five minutes during long sessions. Together, they create a completely hands-off setup so you never have to run manual Git commands.

This post is licensed under CC BY 4.0 by the author.